Comedian Mail - Voicemail System. More...
#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj2.h"
#include "asterisk/event.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
Go to the source code of this file.
Data Structures | |
struct | ast_vm_user |
struct | baseio |
struct | inprocess |
struct | leave_vm_options |
Options for leaving voicemail with the voicemail() application. More... | |
struct | mwi_sub |
An MWI subscription. More... | |
struct | mwi_sub_task |
struct | vm_state |
struct | vm_zone |
Defines | |
#define | ASTERISK_USERNAME "asterisk" |
#define | BASELINELEN 72 |
#define | BASEMAXINLINE 256 |
#define | CHUNKSIZE 65536 |
#define | COMMAND_TIMEOUT 5000 |
#define | COPY(a, b, c, d, e, f, g, h) (copy_plain_file(g,h)); |
#define | DATA_EXPORT_VM_USERS(USER) |
#define | DATA_EXPORT_VM_ZONES(ZONE) |
#define | DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
#define | DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
#define | DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
#define | DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
#define | DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
#define | DEFAULT_POLL_FREQ 30 |
#define | DELETE(a, b, c, d) (vm_delete(c)) |
#define | DISPOSE(a, b) |
#define | ENDL "\n" |
#define | ERROR_LOCK_PATH -100 |
#define | EXISTS(a, b, c, d) (ast_fileexists(c,NULL,d) > 0) |
#define | HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define | HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define | INTRO "vm-intro" |
#define | MAX_DATETIME_FORMAT 512 |
#define | MAX_NUM_CID_CONTEXTS 10 |
#define | MAXMSG 100 |
#define | MAXMSGLIMIT 9999 |
#define | MINPASSWORD 0 |
#define | OPERATOR_EXIT 300 |
#define | PWDCHANGE_EXTERNAL (1 << 2) |
#define | PWDCHANGE_INTERNAL (1 << 1) |
#define | RENAME(a, b, c, d, e, f, g, h) (rename_file(g,h)); |
#define | RETRIEVE(a, b, c, d) |
#define | SENDMAIL "/usr/sbin/sendmail -t" |
#define | SMDI_MWI_WAIT_TIMEOUT 1000 |
#define | STORE(a, b, c, d, e, f, g, h, i, j) |
#define | tdesc "Comedian Mail (Voicemail System)" |
#define | VALID_DTMF "1234567890*#" |
#define | VM_ALLOCED (1 << 13) |
#define | VM_ATTACH (1 << 11) |
#define | VM_DELETE (1 << 12) |
#define | VM_DIRECFORWARD (1 << 10) |
#define | VM_ENVELOPE (1 << 4) |
#define | VM_FORCEGREET (1 << 8) |
#define | VM_FORCENAME (1 << 7) |
#define | VM_FWDURGAUTO (1 << 18) |
#define | VM_MESSAGEWRAP (1 << 17) |
#define | VM_MOVEHEARD (1 << 16) |
#define | VM_OPERATOR (1 << 1) |
#define | VM_PBXSKIP (1 << 9) |
#define | VM_REVIEW (1 << 0) |
#define | VM_SAYCID (1 << 2) |
#define | VM_SAYDURATION (1 << 5) |
#define | VM_SEARCH (1 << 14) |
#define | VM_SKIPAFTERCMD (1 << 6) |
#define | VM_SVMAIL (1 << 3) |
#define | VM_TEMPGREETWARN (1 << 15) |
#define | VMSTATE_MAX_MSG_ARRAY 256 |
#define | VOICEMAIL_CONFIG "voicemail.conf" |
#define | VOICEMAIL_DIR_MODE 0777 |
#define | VOICEMAIL_FILE_MODE 0666 |
Enumerations | |
enum | vm_box { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, 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, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, 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), 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), 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, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2 } |
Functions | |
static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
static int | acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len) |
static int | actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg) |
static int | add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum) |
static void | adsi_begin (struct ast_channel *chan, int *useadsi) |
static void | adsi_delete (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_folders (struct ast_channel *chan, int start, char *label) |
static void | adsi_goodbye (struct ast_channel *chan) |
static int | adsi_load_vmail (struct ast_channel *chan, int *useadsi) |
static void | adsi_login (struct ast_channel *chan) |
static int | adsi_logo (unsigned char *buf) |
static void | adsi_message (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_password (struct ast_channel *chan) |
static void | adsi_status (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_status2 (struct ast_channel *chan, struct vm_state *vms) |
static int | advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain) |
The advanced options within a message. | |
static int | append_mailbox (const char *context, const char *box, const char *data) |
static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
Sets a a specific property value. | |
static void | apply_options (struct ast_vm_user *vmu, const char *options) |
Destructively Parse options and apply. | |
static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
Loads the options specific to a voicemail user. | |
AST_APP_OPTIONS (vm_app_options,{AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION_ARG('d', OPT_DTMFEXIT, OPT_ARG_DTMFEXIT), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER), AST_APP_OPTION('U', OPT_MESSAGE_Urgent),}) | |
AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
static | AST_LIST_HEAD_STATIC (zones, vm_zone) |
static | AST_LIST_HEAD_STATIC (users, ast_vm_user) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,.nonoptreq="res_adsi,res_smdi",) | |
AST_MUTEX_DEFINE_STATIC (poll_lock) | |
static | AST_RWLIST_HEAD_STATIC (mwi_subs, mwi_sub) |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble) |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. | |
static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
AST_TEST_DEFINE (test_voicemail_vmuser) | |
static int | base_encode (char *filename, FILE *so) |
Performs a base 64 encode algorithm on the contents of a File. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
static int | check_mime (const char *str) |
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. | |
static int | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
static int | close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu) |
static char * | complete_voicemail_show_users (const char *line, const char *word, int pos, int state) |
static int | copy (char *infile, char *outfile) |
Utility function to copy a file. | |
static int | copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag) |
Copies a message from one mailbox to another. | |
static void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
static int | count_messages (struct ast_vm_user *vmu, char *dir) |
Find all .txt files - even if they are not in sequence from 0000. | |
static int | create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder) |
basically mkdir -p $dest/$context/$ext/$folder | |
static int | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the users file or the realtime engine. | |
static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the realtime engine. | |
static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent) |
Sends a voicemail message to a mailbox recipient. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
static void | free_zone (struct vm_zone *z) |
static int | get_date (char *s, int len) |
Gets the current date and time, as formatted string. | |
static int | get_folder (struct ast_channel *chan, int start) |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
plays a prompt and waits for a keypress. | |
static int | get_folder_by_name (const char *name) |
static int | handle_subscribe (void *datap) |
static int | handle_unsubscribe (void *datap) |
static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload voicemail configuration from the CLI. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
static int | inbuf (struct baseio *bio, FILE *fi) |
utility used by inchar(), for base_encode() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
static int | inprocess_count (const char *context, const char *mailbox, int delta) |
static int | inprocess_hash_fn (const void *obj, const int flags) |
static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
static int | is_valid_dtmf (const char *key) |
Determines if a DTMF key entered is valid. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
static int | load_config (int reload) |
static int | load_module (void) |
static int | make_dir (char *dest, int len, const char *context, const char *ext, const char *folder) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static int | make_file (char *dest, const int len, const char *dir, const int num) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
static void * | mb_poll_thread (void *data) |
static const char * | mbox (struct ast_vm_user *vmu, int id) |
static int | messagecount (const char *context, const char *mailbox, const char *folder) |
static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
Sends email notification that a user has a new voicemail waiting for them. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback) |
static int | play_message_category (struct ast_channel *chan, const char *category) |
static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag) |
static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
static void | poll_subscribed_mailboxes (void) |
static void | populate_defaults (struct ast_vm_user *vmu) |
Sets default voicemail system options to a voicemail user. | |
static void | prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
static FILE * | vm_mkftemp (char *template) |
static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
static int | vm_play_folder_name_gr (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static char * | addesc = "Comedian Mail" |
static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
static int | adsiver = 1 |
static char * | app = "VoiceMail" |
static char * | app2 = "VoiceMailMain" |
static char * | app3 = "MailboxExists" |
static char * | app4 = "VMAuthenticate" |
static char | callcontext [AST_MAX_CONTEXT] = "" |
static char | charset [32] = "ISO-8859-1" |
static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
static struct ast_cli_entry | cli_voicemail [] |
static char | dialcontext [AST_MAX_CONTEXT] = "" |
static char * | emailbody = NULL |
static char | emaildateformat [32] = "%A, %B %d, %Y at %r" |
static char * | emailsubject = NULL |
static char | exitcontext [AST_MAX_CONTEXT] = "" |
static char | ext_pass_check_cmd [128] |
static char | ext_pass_cmd [128] |
static char | externnotify [160] |
static char | fromstring [100] |
static struct ast_flags | globalflags = {0} |
struct ao2_container * | inprocess_container |
static char | listen_control_forward_key [12] |
static char | listen_control_pause_key [12] |
static char | listen_control_restart_key [12] |
static char | listen_control_reverse_key [12] |
static char | listen_control_stop_key [12] |
static char | locale [20] |
static struct ast_custom_function | mailbox_exists_acf |
static const char *const | mailbox_folders [] |
static char | mailcmd [160] |
static int | maxdeletedmsg |
static int | maxgreet |
static int | maxlogins |
static int | maxmsg |
static int | maxsilence |
static int | minpassword |
static struct ast_event_sub * | mwi_sub_sub |
static struct ast_taskprocessor * | mwi_subscription_tps |
static struct ast_event_sub * | mwi_unsub_sub |
static int | my_umask |
static char * | pagerbody = NULL |
static char | pagerdateformat [32] = "%A, %B %d, %Y at %r" |
static char | pagerfromstring [100] |
static char * | pagersubject = NULL |
static int | passwordlocation |
static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
static unsigned int | poll_freq |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char * | sayname_app = "VMSayName" |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static struct ast_data_entry | vm_data_providers [] |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
static char | vm_passchanged [80] = "vm-passchanged" |
static char | vm_password [80] = "vm-password" |
static char | vm_pls_try_again [80] = "vm-pls-try-again" |
static char | vm_prepend_timeout [80] = "vm-then-pound" |
static char | vm_reenterpassword [80] = "vm-reenterpassword" |
static char | VM_SPOOL_DIR [PATH_MAX] |
static struct ast_data_handler | vm_users_data_provider |
static char | vmfmts [80] |
static int | vmmaxsecs |
static int | vmminsecs |
static double | volgain |
static char | zonetag [80] |
Comedian Mail - Voicemail System.
Definition in file app_voicemail.c.
#define ASTERISK_USERNAME "asterisk" |
Definition at line 430 of file app_voicemail.c.
#define BASELINELEN 72 |
Definition at line 453 of file app_voicemail.c.
Referenced by ochar().
#define BASEMAXINLINE 256 |
Definition at line 454 of file app_voicemail.c.
Referenced by base_encode(), and inbuf().
#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)); |
Definition at line 740 of file app_voicemail.c.
Referenced by copy_message(), and save_to_folder().
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11343 of file app_voicemail.c.
#define DATA_EXPORT_VM_ZONES | ( | ZONE | ) |
ZONE(vm_zone, name, AST_DATA_STRING) \ ZONE(vm_zone, timezone, AST_DATA_STRING) \ ZONE(vm_zone, msg_format, AST_DATA_STRING)
Definition at line 11370 of file app_voicemail.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 435 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 437 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 438 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 436 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 439 of file app_voicemail.c.
Referenced by actual_load_config().
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 810 of file app_voicemail.c.
Referenced by actual_load_config().
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 741 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 736 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 738 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 leave_voicemail(), 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 |
Definition at line 484 of file app_voicemail.c.
Referenced by leave_voicemail(), vm_exec(), and vm_execmain().
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 753 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 752 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 739 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), resequence_mailbox(), and save_to_folder().
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 735 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 |
Definition at line 421 of file app_voicemail.c.
Referenced by run_externnotify().
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 737 of file app_voicemail.c.
Referenced by copy_message(), forward_message(), leave_voicemail(), and play_record_review().
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 762 of file app_voicemail.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 440 of file app_voicemail.c.
Referenced by is_valid_dtmf().
#define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 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 677 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(), leave_voicemail(), 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 |
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 |
OPT_PWLOC_VOICEMAILCONF | |
OPT_PWLOC_SPOOLDIR | |
OPT_PWLOC_USERSCONF | |
OPT_PWLOC_VOICEMAILCONF | |
OPT_PWLOC_SPOOLDIR | |
OPT_PWLOC_USERSCONF | |
OPT_PWLOC_VOICEMAILCONF | |
OPT_PWLOC_SPOOLDIR | |
OPT_PWLOC_USERSCONF |
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 5388 of file app_voicemail.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05389 { 05390 DIR *dir; 05391 struct dirent *de; 05392 char fn[256]; 05393 int ret = 0; 05394 05395 /* If no mailbox, return immediately */ 05396 if (ast_strlen_zero(mailbox)) 05397 return 0; 05398 05399 if (ast_strlen_zero(folder)) 05400 folder = "INBOX"; 05401 if (ast_strlen_zero(context)) 05402 context = "default"; 05403 05404 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05405 05406 if (!(dir = opendir(fn))) 05407 return 0; 05408 05409 while ((de = readdir(dir))) { 05410 if (!strncasecmp(de->d_name, "msg", 3)) { 05411 if (shortcircuit) { 05412 ret = 1; 05413 break; 05414 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05415 ret++; 05416 } 05417 } 05418 } 05419 05420 closedir(dir); 05421 05422 return ret; 05423 }
static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | args, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 11046 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().
11047 { 11048 struct ast_vm_user svm; 11049 AST_DECLARE_APP_ARGS(arg, 11050 AST_APP_ARG(mbox); 11051 AST_APP_ARG(context); 11052 ); 11053 11054 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11055 11056 if (ast_strlen_zero(arg.mbox)) { 11057 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11058 return -1; 11059 } 11060 11061 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11062 return 0; 11063 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11880 of file app_voicemail.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_option(), ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_false(), ast_format_str_reduce(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_DEBUG, AST_LOG_ERROR, AST_LOG_WARNING, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, ast_vm_user::context, DEFAULT_LISTEN_CONTROL_FORWARD_KEY, DEFAULT_LISTEN_CONTROL_PAUSE_KEY, DEFAULT_LISTEN_CONTROL_RESTART_KEY, DEFAULT_LISTEN_CONTROL_REVERSE_KEY, DEFAULT_LISTEN_CONTROL_STOP_KEY, DEFAULT_POLL_FREQ, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, ext_pass_check_cmd, ext_pass_cmd, externnotify, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), ast_variable::lineno, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, locale, LOG_ERROR, ast_vm_user::mailbox, mailcmd, MAX_NUM_CID_CONTEXTS, maxdeletedmsg, maxgreet, maxlogins, MAXMSG, maxmsg, MAXMSGLIMIT, maxsilence, MINPASSWORD, minpassword, ast_variable::name, ast_variable::next, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, ast_vm_user::password, ast_vm_user::passwordlocation, passwordlocation, poll_freq, poll_mailboxes, poll_thread, populate_defaults(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, serveremail, silencethreshold, skipms, smdi_iface, start_poll_thread(), stop_poll_thread(), substitute_escapes(), THRESHOLD_SILENCE, userscontext, ast_variable::value, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, vm_invalid_password, VM_MESSAGEWRAP, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_pls_try_again, vm_prepend_timeout, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SPOOL_DIR, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxsecs, vmminsecs, volgain, and zonetag.
Referenced by load_config().
11881 { 11882 struct ast_vm_user *current; 11883 char *cat; 11884 struct ast_variable *var; 11885 const char *val; 11886 char *q, *stringp, *tmp; 11887 int x; 11888 int tmpadsi[4]; 11889 char secretfn[PATH_MAX] = ""; 11890 11891 #ifdef IMAP_STORAGE 11892 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11893 #endif 11894 /* set audio control prompts */ 11895 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11896 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11897 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11898 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11899 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11900 11901 /* Free all the users structure */ 11902 free_vm_users(); 11903 11904 /* Free all the zones structure */ 11905 free_vm_zones(); 11906 11907 AST_LIST_LOCK(&users); 11908 11909 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11910 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11911 11912 if (cfg) { 11913 /* General settings */ 11914 11915 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11916 val = "default"; 11917 ast_copy_string(userscontext, val, sizeof(userscontext)); 11918 /* Attach voice message to mail message ? */ 11919 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11920 val = "yes"; 11921 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11922 11923 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11924 val = "no"; 11925 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11926 11927 volgain = 0.0; 11928 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11929 sscanf(val, "%30lf", &volgain); 11930 11931 #ifdef ODBC_STORAGE 11932 strcpy(odbc_database, "asterisk"); 11933 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11934 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11935 } 11936 strcpy(odbc_table, "voicemessages"); 11937 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11938 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11939 } 11940 #endif 11941 /* Mail command */ 11942 strcpy(mailcmd, SENDMAIL); 11943 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11944 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11945 11946 maxsilence = 0; 11947 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11948 maxsilence = atoi(val); 11949 if (maxsilence > 0) 11950 maxsilence *= 1000; 11951 } 11952 11953 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11954 maxmsg = MAXMSG; 11955 } else { 11956 maxmsg = atoi(val); 11957 if (maxmsg < 0) { 11958 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11959 maxmsg = MAXMSG; 11960 } else if (maxmsg > MAXMSGLIMIT) { 11961 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11962 maxmsg = MAXMSGLIMIT; 11963 } 11964 } 11965 11966 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11967 maxdeletedmsg = 0; 11968 } else { 11969 if (sscanf(val, "%30d", &x) == 1) 11970 maxdeletedmsg = x; 11971 else if (ast_true(val)) 11972 maxdeletedmsg = MAXMSG; 11973 else 11974 maxdeletedmsg = 0; 11975 11976 if (maxdeletedmsg < 0) { 11977 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11978 maxdeletedmsg = MAXMSG; 11979 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11980 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11981 maxdeletedmsg = MAXMSGLIMIT; 11982 } 11983 } 11984 11985 /* Load date format config for voicemail mail */ 11986 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11987 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11988 } 11989 11990 /* Load date format config for voicemail pager mail */ 11991 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11992 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11993 } 11994 11995 /* External password changing command */ 11996 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11997 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11998 pwdchange = PWDCHANGE_EXTERNAL; 11999 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12000 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12001 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12002 } 12003 12004 /* External password validation command */ 12005 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12006 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12007 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12008 } 12009 12010 #ifdef IMAP_STORAGE 12011 /* IMAP server address */ 12012 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12013 ast_copy_string(imapserver, val, sizeof(imapserver)); 12014 } else { 12015 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12016 } 12017 /* IMAP server port */ 12018 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12019 ast_copy_string(imapport, val, sizeof(imapport)); 12020 } else { 12021 ast_copy_string(imapport, "143", sizeof(imapport)); 12022 } 12023 /* IMAP server flags */ 12024 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12025 ast_copy_string(imapflags, val, sizeof(imapflags)); 12026 } 12027 /* IMAP server master username */ 12028 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12029 ast_copy_string(authuser, val, sizeof(authuser)); 12030 } 12031 /* IMAP server master password */ 12032 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12033 ast_copy_string(authpassword, val, sizeof(authpassword)); 12034 } 12035 /* Expunge on exit */ 12036 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12037 if (ast_false(val)) 12038 expungeonhangup = 0; 12039 else 12040 expungeonhangup = 1; 12041 } else { 12042 expungeonhangup = 1; 12043 } 12044 /* IMAP voicemail folder */ 12045 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12046 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12047 } else { 12048 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12049 } 12050 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12051 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12052 } 12053 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12054 imapgreetings = ast_true(val); 12055 } else { 12056 imapgreetings = 0; 12057 } 12058 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12059 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12060 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12061 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12062 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12063 } else { 12064 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12065 } 12066 12067 /* There is some very unorthodox casting done here. This is due 12068 * to the way c-client handles the argument passed in. It expects a 12069 * void pointer and casts the pointer directly to a long without 12070 * first dereferencing it. */ 12071 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12072 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12073 } else { 12074 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12075 } 12076 12077 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12078 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12079 } else { 12080 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12081 } 12082 12083 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12084 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12085 } else { 12086 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12087 } 12088 12089 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12090 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12091 } else { 12092 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12093 } 12094 12095 /* Increment configuration version */ 12096 imapversion++; 12097 #endif 12098 /* External voicemail notify application */ 12099 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12100 ast_copy_string(externnotify, val, sizeof(externnotify)); 12101 ast_debug(1, "found externnotify: %s\n", externnotify); 12102 } else { 12103 externnotify[0] = '\0'; 12104 } 12105 12106 /* SMDI voicemail notification */ 12107 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12108 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12109 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12110 smdi_iface = ast_smdi_interface_find(val); 12111 } else { 12112 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12113 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12114 } 12115 if (!smdi_iface) { 12116 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12117 } 12118 } 12119 12120 /* Silence treshold */ 12121 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12122 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12123 silencethreshold = atoi(val); 12124 12125 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12126 val = ASTERISK_USERNAME; 12127 ast_copy_string(serveremail, val, sizeof(serveremail)); 12128 12129 vmmaxsecs = 0; 12130 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12131 if (sscanf(val, "%30d", &x) == 1) { 12132 vmmaxsecs = x; 12133 } else { 12134 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12135 } 12136 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12137 static int maxmessage_deprecate = 0; 12138 if (maxmessage_deprecate == 0) { 12139 maxmessage_deprecate = 1; 12140 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12141 } 12142 if (sscanf(val, "%30d", &x) == 1) { 12143 vmmaxsecs = x; 12144 } else { 12145 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12146 } 12147 } 12148 12149 vmminsecs = 0; 12150 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12151 if (sscanf(val, "%30d", &x) == 1) { 12152 vmminsecs = x; 12153 if (maxsilence / 1000 >= vmminsecs) { 12154 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12155 } 12156 } else { 12157 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12158 } 12159 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12160 static int maxmessage_deprecate = 0; 12161 if (maxmessage_deprecate == 0) { 12162 maxmessage_deprecate = 1; 12163 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12164 } 12165 if (sscanf(val, "%30d", &x) == 1) { 12166 vmminsecs = x; 12167 if (maxsilence / 1000 >= vmminsecs) { 12168 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12169 } 12170 } else { 12171 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12172 } 12173 } 12174 12175 val = ast_variable_retrieve(cfg, "general", "format"); 12176 if (!val) { 12177 val = "wav"; 12178 } else { 12179 tmp = ast_strdupa(val); 12180 val = ast_format_str_reduce(tmp); 12181 if (!val) { 12182 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12183 val = "wav"; 12184 } 12185 } 12186 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12187 12188 skipms = 3000; 12189 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12190 if (sscanf(val, "%30d", &x) == 1) { 12191 maxgreet = x; 12192 } else { 12193 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12194 } 12195 } 12196 12197 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12198 if (sscanf(val, "%30d", &x) == 1) { 12199 skipms = x; 12200 } else { 12201 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12202 } 12203 } 12204 12205 maxlogins = 3; 12206 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12207 if (sscanf(val, "%30d", &x) == 1) { 12208 maxlogins = x; 12209 } else { 12210 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12211 } 12212 } 12213 12214 minpassword = MINPASSWORD; 12215 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12216 if (sscanf(val, "%30d", &x) == 1) { 12217 minpassword = x; 12218 } else { 12219 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12220 } 12221 } 12222 12223 /* Force new user to record name ? */ 12224 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12225 val = "no"; 12226 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12227 12228 /* Force new user to record greetings ? */ 12229 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12230 val = "no"; 12231 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12232 12233 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12234 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12235 stringp = ast_strdupa(val); 12236 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12237 if (!ast_strlen_zero(stringp)) { 12238 q = strsep(&stringp, ","); 12239 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12240 q++; 12241 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12242 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12243 } else { 12244 cidinternalcontexts[x][0] = '\0'; 12245 } 12246 } 12247 } 12248 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12249 ast_debug(1, "VM Review Option disabled globally\n"); 12250 val = "no"; 12251 } 12252 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12253 12254 /* Temporary greeting reminder */ 12255 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12256 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12257 val = "no"; 12258 } else { 12259 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12260 } 12261 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12262 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12263 ast_debug(1, "VM next message wrap disabled globally\n"); 12264 val = "no"; 12265 } 12266 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12267 12268 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12269 ast_debug(1, "VM Operator break disabled globally\n"); 12270 val = "no"; 12271 } 12272 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12273 12274 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12275 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12276 val = "no"; 12277 } 12278 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12279 12280 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12281 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12282 val = "no"; 12283 } 12284 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12285 12286 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12287 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12288 val = "yes"; 12289 } 12290 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12291 12292 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12293 ast_debug(1, "Move Heard enabled globally\n"); 12294 val = "yes"; 12295 } 12296 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12297 12298 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12299 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12300 val = "no"; 12301 } 12302 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12303 12304 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12305 ast_debug(1, "Duration info before msg enabled globally\n"); 12306 val = "yes"; 12307 } 12308 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12309 12310 saydurationminfo = 2; 12311 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12312 if (sscanf(val, "%30d", &x) == 1) { 12313 saydurationminfo = x; 12314 } else { 12315 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12316 } 12317 } 12318 12319 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12320 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12321 val = "no"; 12322 } 12323 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12324 12325 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12326 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12327 ast_debug(1, "found dialout context: %s\n", dialcontext); 12328 } else { 12329 dialcontext[0] = '\0'; 12330 } 12331 12332 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12333 ast_copy_string(callcontext, val, sizeof(callcontext)); 12334 ast_debug(1, "found callback context: %s\n", callcontext); 12335 } else { 12336 callcontext[0] = '\0'; 12337 } 12338 12339 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12340 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12341 ast_debug(1, "found operator context: %s\n", exitcontext); 12342 } else { 12343 exitcontext[0] = '\0'; 12344 } 12345 12346 /* load password sounds configuration */ 12347 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12348 ast_copy_string(vm_password, val, sizeof(vm_password)); 12349 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12350 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12351 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12352 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12353 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12354 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12355 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12356 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12357 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12358 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12359 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12360 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12361 } 12362 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12363 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12364 } 12365 /* load configurable audio prompts */ 12366 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12367 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12368 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12369 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12370 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12371 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12372 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12373 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12374 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12375 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12376 12377 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12378 val = "no"; 12379 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12380 12381 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12382 val = "voicemail.conf"; 12383 } 12384 if (!(strcmp(val, "spooldir"))) { 12385 passwordlocation = OPT_PWLOC_SPOOLDIR; 12386 } else { 12387 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12388 } 12389 12390 poll_freq = DEFAULT_POLL_FREQ; 12391 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12392 if (sscanf(val, "%30u", &poll_freq) != 1) { 12393 poll_freq = DEFAULT_POLL_FREQ; 12394 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12395 } 12396 } 12397 12398 poll_mailboxes = 0; 12399 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12400 poll_mailboxes = ast_true(val); 12401 12402 memset(fromstring, 0, sizeof(fromstring)); 12403 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12404 strcpy(charset, "ISO-8859-1"); 12405 if (emailbody) { 12406 ast_free(emailbody); 12407 emailbody = NULL; 12408 } 12409 if (emailsubject) { 12410 ast_free(emailsubject); 12411 emailsubject = NULL; 12412 } 12413 if (pagerbody) { 12414 ast_free(pagerbody); 12415 pagerbody = NULL; 12416 } 12417 if (pagersubject) { 12418 ast_free(pagersubject); 12419 pagersubject = NULL; 12420 } 12421 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12422 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12423 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12424 ast_copy_string(fromstring, val, sizeof(fromstring)); 12425 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12426 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12427 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12428 ast_copy_string(charset, val, sizeof(charset)); 12429 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12430 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12431 for (x = 0; x < 4; x++) { 12432 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12433 } 12434 } 12435 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12436 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12437 for (x = 0; x < 4; x++) { 12438 memcpy(&adsisec[x], &tmpadsi[x], 1); 12439 } 12440 } 12441 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12442 if (atoi(val)) { 12443 adsiver = atoi(val); 12444 } 12445 } 12446 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12447 ast_copy_string(zonetag, val, sizeof(zonetag)); 12448 } 12449 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12450 ast_copy_string(locale, val, sizeof(locale)); 12451 } 12452 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12453 emailsubject = ast_strdup(substitute_escapes(val)); 12454 } 12455 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12456 emailbody = ast_strdup(substitute_escapes(val)); 12457 } 12458 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12459 pagersubject = ast_strdup(substitute_escapes(val)); 12460 } 12461 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12462 pagerbody = ast_strdup(substitute_escapes(val)); 12463 } 12464 12465 /* load mailboxes from users.conf */ 12466 if (ucfg) { 12467 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12468 if (!strcasecmp(cat, "general")) { 12469 continue; 12470 } 12471 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12472 continue; 12473 if ((current = find_or_create(userscontext, cat))) { 12474 populate_defaults(current); 12475 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12476 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12477 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12478 current->passwordlocation = OPT_PWLOC_USERSCONF; 12479 } 12480 12481 switch (current->passwordlocation) { 12482 case OPT_PWLOC_SPOOLDIR: 12483 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12484 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12485 } 12486 } 12487 } 12488 } 12489 12490 /* load mailboxes from voicemail.conf */ 12491 cat = ast_category_browse(cfg, NULL); 12492 while (cat) { 12493 if (strcasecmp(cat, "general")) { 12494 var = ast_variable_browse(cfg, cat); 12495 if (strcasecmp(cat, "zonemessages")) { 12496 /* Process mailboxes in this context */ 12497 while (var) { 12498 append_mailbox(cat, var->name, var->value); 12499 var = var->next; 12500 } 12501 } else { 12502 /* Timezones in this context */ 12503 while (var) { 12504 struct vm_zone *z; 12505 if ((z = ast_malloc(sizeof(*z)))) { 12506 char *msg_format, *tzone; 12507 msg_format = ast_strdupa(var->value); 12508 tzone = strsep(&msg_format, "|,"); 12509 if (msg_format) { 12510 ast_copy_string(z->name, var->name, sizeof(z->name)); 12511 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12512 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12513 AST_LIST_LOCK(&zones); 12514 AST_LIST_INSERT_HEAD(&zones, z, list); 12515 AST_LIST_UNLOCK(&zones); 12516 } else { 12517 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12518 ast_free(z); 12519 } 12520 } else { 12521 AST_LIST_UNLOCK(&users); 12522 return -1; 12523 } 12524 var = var->next; 12525 } 12526 } 12527 } 12528 cat = ast_category_browse(cfg, cat); 12529 } 12530 12531 AST_LIST_UNLOCK(&users); 12532 12533 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12534 start_poll_thread(); 12535 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12536 stop_poll_thread();; 12537 12538 return 0; 12539 } else { 12540 AST_LIST_UNLOCK(&users); 12541 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12542 return 0; 12543 } 12544 }
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 4802 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().
04803 { 04804 char tmpdir[256], newtmp[256]; 04805 char fname[256]; 04806 char tmpcmd[256]; 04807 int tmpfd = -1; 04808 int soxstatus = 0; 04809 04810 /* Eww. We want formats to tell us their own MIME type */ 04811 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04812 04813 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04814 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04815 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04816 tmpfd = mkstemp(newtmp); 04817 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04818 ast_debug(3, "newtmp: %s\n", newtmp); 04819 if (tmpfd > -1) { 04820 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04821 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04822 attach = newtmp; 04823 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04824 } else { 04825 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04826 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04827 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04828 } 04829 } 04830 } 04831 fprintf(p, "--%s" ENDL, bound); 04832 if (msgnum > -1) 04833 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04834 else 04835 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04836 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04837 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04838 if (msgnum > -1) 04839 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04840 else 04841 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04842 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04843 base_encode(fname, p); 04844 if (last) 04845 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04846 if (tmpfd > -1) { 04847 if (soxstatus == 0) { 04848 unlink(fname); 04849 } 04850 close(tmpfd); 04851 unlink(newtmp); 04852 } 04853 return 0; 04854 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6408 of file app_voicemail.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), ast_log(), and AST_LOG_WARNING.
Referenced by vm_authenticate(), and vm_execmain().
06409 { 06410 int x; 06411 if (!ast_adsi_available(chan)) 06412 return; 06413 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06414 if (x < 0) 06415 return; 06416 if (!x) { 06417 if (adsi_load_vmail(chan, useadsi)) { 06418 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06419 return; 06420 } 06421 } else 06422 *useadsi = 1; 06423 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6603 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_set_keys(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_mutex_lock, ast_mutex_unlock, vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.
Referenced by vm_execmain().
06604 { 06605 int bytes = 0; 06606 unsigned char buf[256]; 06607 unsigned char keys[8]; 06608 06609 int x; 06610 06611 if (!ast_adsi_available(chan)) 06612 return; 06613 06614 /* New meaning for keys */ 06615 for (x = 0; x < 5; x++) 06616 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06617 06618 keys[6] = 0x0; 06619 keys[7] = 0x0; 06620 06621 if (!vms->curmsg) { 06622 /* No prev key, provide "Folder" instead */ 06623 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06624 } 06625 if (vms->curmsg >= vms->lastmsg) { 06626 /* If last message ... */ 06627 if (vms->curmsg) { 06628 /* but not only message, provide "Folder" instead */ 06629 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06630 } else { 06631 /* Otherwise if only message, leave blank */ 06632 keys[3] = 1; 06633 } 06634 } 06635 06636 /* If deleted, show "undeleted" */ 06637 #ifdef IMAP_STORAGE 06638 ast_mutex_lock(&vms->lock); 06639 #endif 06640 if (vms->deleted[vms->curmsg]) { 06641 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06642 } 06643 #ifdef IMAP_STORAGE 06644 ast_mutex_unlock(&vms->lock); 06645 #endif 06646 06647 /* Except "Exit" */ 06648 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06649 bytes += ast_adsi_set_keys(buf + bytes, keys); 06650 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06651 06652 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06653 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6473 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().
06474 { 06475 unsigned char buf[256]; 06476 int bytes = 0; 06477 unsigned char keys[8]; 06478 int x, y; 06479 06480 if (!ast_adsi_available(chan)) 06481 return; 06482 06483 for (x = 0; x < 5; x++) { 06484 y = ADSI_KEY_APPS + 12 + start + x; 06485 if (y > ADSI_KEY_APPS + 12 + 4) 06486 y = 0; 06487 keys[x] = ADSI_KEY_SKT | y; 06488 } 06489 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06490 keys[6] = 0; 06491 keys[7] = 0; 06492 06493 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06494 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06495 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06496 bytes += ast_adsi_set_keys(buf + bytes, keys); 06497 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06498 06499 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06500 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6758 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().
06759 { 06760 unsigned char buf[256]; 06761 int bytes = 0; 06762 06763 if (!ast_adsi_available(chan)) 06764 return; 06765 bytes += adsi_logo(buf + bytes); 06766 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06767 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06768 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06769 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06770 06771 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06772 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6279 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().
06280 { 06281 unsigned char buf[256]; 06282 int bytes = 0; 06283 int x; 06284 char num[5]; 06285 06286 *useadsi = 0; 06287 bytes += ast_adsi_data_mode(buf + bytes); 06288 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06289 06290 bytes = 0; 06291 bytes += adsi_logo(buf); 06292 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06293 #ifdef DISPLAY 06294 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06295 #endif 06296 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06297 bytes += ast_adsi_data_mode(buf + bytes); 06298 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06299 06300 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06301 bytes = 0; 06302 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06303 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06304 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06305 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06306 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06307 return 0; 06308 } 06309 06310 #ifdef DISPLAY 06311 /* Add a dot */ 06312 bytes = 0; 06313 bytes += ast_adsi_logo(buf); 06314 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06315 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06316 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06317 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06318 #endif 06319 bytes = 0; 06320 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06321 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06322 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06323 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06324 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06325 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06326 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06327 06328 #ifdef DISPLAY 06329 /* Add another dot */ 06330 bytes = 0; 06331 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06332 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06333 06334 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06335 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06336 #endif 06337 06338 bytes = 0; 06339 /* These buttons we load but don't use yet */ 06340 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06341 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06342 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06343 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06344 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06345 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06346 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06347 06348 #ifdef DISPLAY 06349 /* Add another dot */ 06350 bytes = 0; 06351 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06352 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06353 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06354 #endif 06355 06356 bytes = 0; 06357 for (x = 0; x < 5; x++) { 06358 snprintf(num, sizeof(num), "%d", x); 06359 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06360 } 06361 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06362 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06363 06364 #ifdef DISPLAY 06365 /* Add another dot */ 06366 bytes = 0; 06367 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06368 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06369 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06370 #endif 06371 06372 if (ast_adsi_end_download(chan)) { 06373 bytes = 0; 06374 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06375 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06376 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06377 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06378 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06379 return 0; 06380 } 06381 bytes = 0; 06382 bytes += ast_adsi_download_disconnect(buf + bytes); 06383 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06384 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06385 06386 ast_debug(1, "Done downloading scripts...\n"); 06387 06388 #ifdef DISPLAY 06389 /* Add last dot */ 06390 bytes = 0; 06391 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06392 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06393 #endif 06394 ast_debug(1, "Restarting session...\n"); 06395 06396 bytes = 0; 06397 /* Load the session now */ 06398 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06399 *useadsi = 1; 06400 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06401 } else 06402 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06403 06404 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06405 return 0; 06406 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6425 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().
06426 { 06427 unsigned char buf[256]; 06428 int bytes = 0; 06429 unsigned char keys[8]; 06430 int x; 06431 if (!ast_adsi_available(chan)) 06432 return; 06433 06434 for (x = 0; x < 8; x++) 06435 keys[x] = 0; 06436 /* Set one key for next */ 06437 keys[3] = ADSI_KEY_APPS + 3; 06438 06439 bytes += adsi_logo(buf + bytes); 06440 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06441 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06442 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06443 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06444 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06445 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06446 bytes += ast_adsi_set_keys(buf + bytes, keys); 06447 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06448 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06449 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6271 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().
06272 { 06273 int bytes = 0; 06274 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06275 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06276 return bytes; 06277 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6502 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_callerid_parse(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, and name.
Referenced by play_message(), and vm_execmain().
06503 { 06504 int bytes = 0; 06505 unsigned char buf[256]; 06506 char buf1[256], buf2[256]; 06507 char fn2[PATH_MAX]; 06508 06509 char cid[256] = ""; 06510 char *val; 06511 char *name, *num; 06512 char datetime[21] = ""; 06513 FILE *f; 06514 06515 unsigned char keys[8]; 06516 06517 int x; 06518 06519 if (!ast_adsi_available(chan)) 06520 return; 06521 06522 /* Retrieve important info */ 06523 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06524 f = fopen(fn2, "r"); 06525 if (f) { 06526 while (!feof(f)) { 06527 if (!fgets((char *) buf, sizeof(buf), f)) { 06528 continue; 06529 } 06530 if (!feof(f)) { 06531 char *stringp = NULL; 06532 stringp = (char *) buf; 06533 strsep(&stringp, "="); 06534 val = strsep(&stringp, "="); 06535 if (!ast_strlen_zero(val)) { 06536 if (!strcmp((char *) buf, "callerid")) 06537 ast_copy_string(cid, val, sizeof(cid)); 06538 if (!strcmp((char *) buf, "origdate")) 06539 ast_copy_string(datetime, val, sizeof(datetime)); 06540 } 06541 } 06542 } 06543 fclose(f); 06544 } 06545 /* New meaning for keys */ 06546 for (x = 0; x < 5; x++) 06547 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06548 keys[6] = 0x0; 06549 keys[7] = 0x0; 06550 06551 if (!vms->curmsg) { 06552 /* No prev key, provide "Folder" instead */ 06553 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06554 } 06555 if (vms->curmsg >= vms->lastmsg) { 06556 /* If last message ... */ 06557 if (vms->curmsg) { 06558 /* but not only message, provide "Folder" instead */ 06559 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06560 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06561 06562 } else { 06563 /* Otherwise if only message, leave blank */ 06564 keys[3] = 1; 06565 } 06566 } 06567 06568 if (!ast_strlen_zero(cid)) { 06569 ast_callerid_parse(cid, &name, &num); 06570 if (!name) 06571 name = num; 06572 } else 06573 name = "Unknown Caller"; 06574 06575 /* If deleted, show "undeleted" */ 06576 #ifdef IMAP_STORAGE 06577 ast_mutex_lock(&vms->lock); 06578 #endif 06579 if (vms->deleted[vms->curmsg]) { 06580 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06581 } 06582 #ifdef IMAP_STORAGE 06583 ast_mutex_unlock(&vms->lock); 06584 #endif 06585 06586 /* Except "Exit" */ 06587 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06588 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06589 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06590 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06591 06592 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06593 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06594 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06595 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06596 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06597 bytes += ast_adsi_set_keys(buf + bytes, keys); 06598 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06599 06600 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06601 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6451 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().
06452 { 06453 unsigned char buf[256]; 06454 int bytes = 0; 06455 unsigned char keys[8]; 06456 int x; 06457 if (!ast_adsi_available(chan)) 06458 return; 06459 06460 for (x = 0; x < 8; x++) 06461 keys[x] = 0; 06462 /* Set one key for next */ 06463 keys[3] = ADSI_KEY_APPS + 3; 06464 06465 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06466 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06467 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06468 bytes += ast_adsi_set_keys(buf + bytes, keys); 06469 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06470 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06471 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6655 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
06656 { 06657 unsigned char buf[256] = ""; 06658 char buf1[256] = "", buf2[256] = ""; 06659 int bytes = 0; 06660 unsigned char keys[8]; 06661 int x; 06662 06663 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06664 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06665 if (!ast_adsi_available(chan)) 06666 return; 06667 if (vms->newmessages) { 06668 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06669 if (vms->oldmessages) { 06670 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06671 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06672 } else { 06673 snprintf(buf2, sizeof(buf2), "%s.", newm); 06674 } 06675 } else if (vms->oldmessages) { 06676 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06677 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06678 } else { 06679 strcpy(buf1, "You have no messages."); 06680 buf2[0] = ' '; 06681 buf2[1] = '\0'; 06682 } 06683 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06684 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06685 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06686 06687 for (x = 0; x < 6; x++) 06688 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06689 keys[6] = 0; 06690 keys[7] = 0; 06691 06692 /* Don't let them listen if there are none */ 06693 if (vms->lastmsg < 0) 06694 keys[0] = 1; 06695 bytes += ast_adsi_set_keys(buf + bytes, keys); 06696 06697 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06698 06699 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06700 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6702 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
06703 { 06704 unsigned char buf[256] = ""; 06705 char buf1[256] = "", buf2[256] = ""; 06706 int bytes = 0; 06707 unsigned char keys[8]; 06708 int x; 06709 06710 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06711 06712 if (!ast_adsi_available(chan)) 06713 return; 06714 06715 /* Original command keys */ 06716 for (x = 0; x < 6; x++) 06717 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06718 06719 keys[6] = 0; 06720 keys[7] = 0; 06721 06722 if ((vms->lastmsg + 1) < 1) 06723 keys[0] = 0; 06724 06725 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06726 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06727 06728 if (vms->lastmsg + 1) 06729 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06730 else 06731 strcpy(buf2, "no messages."); 06732 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06733 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06734 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06735 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06736 bytes += ast_adsi_set_keys(buf + bytes, keys); 06737 06738 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06739 06740 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06741 06742 }
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 13251 of file app_voicemail.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), name, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
13252 { 13253 int res = 0; 13254 char filename[PATH_MAX]; 13255 struct ast_config *msg_cfg = NULL; 13256 const char *origtime, *context; 13257 char *name, *num; 13258 int retries = 0; 13259 char *cid; 13260 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13261 13262 vms->starting = 0; 13263 13264 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13265 13266 /* Retrieve info from VM attribute file */ 13267 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13268 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13269 msg_cfg = ast_config_load(filename, config_flags); 13270 DISPOSE(vms->curdir, vms->curmsg); 13271 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13272 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13273 return 0; 13274 } 13275 13276 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13277 ast_config_destroy(msg_cfg); 13278 return 0; 13279 } 13280 13281 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13282 13283 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13284 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13285 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13286 switch (option) { 13287 case 3: /* Play message envelope */ 13288 if (!res) 13289 res = play_message_datetime(chan, vmu, origtime, filename); 13290 if (!res) 13291 res = play_message_callerid(chan, vms, cid, context, 0); 13292 13293 res = 't'; 13294 break; 13295 13296 case 2: /* Call back */ 13297 13298 if (ast_strlen_zero(cid)) 13299 break; 13300 13301 ast_callerid_parse(cid, &name, &num); 13302 while ((res > -1) && (res != 't')) { 13303 switch (res) { 13304 case '1': 13305 if (num) { 13306 /* Dial the CID number */ 13307 res = dialout(chan, vmu, num, vmu->callback); 13308 if (res) { 13309 ast_config_destroy(msg_cfg); 13310 return 9; 13311 } 13312 } else { 13313 res = '2'; 13314 } 13315 break; 13316 13317 case '2': 13318 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13319 if (!ast_strlen_zero(vmu->dialout)) { 13320 res = dialout(chan, vmu, NULL, vmu->dialout); 13321 if (res) { 13322 ast_config_destroy(msg_cfg); 13323 return 9; 13324 } 13325 } else { 13326 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13327 res = ast_play_and_wait(chan, "vm-sorry"); 13328 } 13329 ast_config_destroy(msg_cfg); 13330 return res; 13331 case '*': 13332 res = 't'; 13333 break; 13334 case '3': 13335 case '4': 13336 case '5': 13337 case '6': 13338 case '7': 13339 case '8': 13340 case '9': 13341 case '0': 13342 13343 res = ast_play_and_wait(chan, "vm-sorry"); 13344 retries++; 13345 break; 13346 default: 13347 if (num) { 13348 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13349 res = ast_play_and_wait(chan, "vm-num-i-have"); 13350 if (!res) 13351 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13352 if (!res) 13353 res = ast_play_and_wait(chan, "vm-tocallnum"); 13354 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13355 if (!ast_strlen_zero(vmu->dialout)) { 13356 if (!res) 13357 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13358 } 13359 } else { 13360 res = ast_play_and_wait(chan, "vm-nonumber"); 13361 if (!ast_strlen_zero(vmu->dialout)) { 13362 if (!res) 13363 res = ast_play_and_wait(chan, "vm-toenternumber"); 13364 } 13365 } 13366 if (!res) { 13367 res = ast_play_and_wait(chan, "vm-star-cancel"); 13368 } 13369 if (!res) { 13370 res = ast_waitfordigit(chan, 6000); 13371 } 13372 if (!res) { 13373 retries++; 13374 if (retries > 3) { 13375 res = 't'; 13376 } 13377 } 13378 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13379 break; 13380 13381 } 13382 if (res == 't') 13383 res = 0; 13384 else if (res == '*') 13385 res = -1; 13386 } 13387 break; 13388 13389 case 1: /* Reply */ 13390 /* Send reply directly to sender */ 13391 if (ast_strlen_zero(cid)) 13392 break; 13393 13394 ast_callerid_parse(cid, &name, &num); 13395 if (!num) { 13396 ast_verb(3, "No CID number available, no reply sent\n"); 13397 if (!res) 13398 res = ast_play_and_wait(chan, "vm-nonumber"); 13399 ast_config_destroy(msg_cfg); 13400 return res; 13401 } else { 13402 struct ast_vm_user vmu2; 13403 if (find_user(&vmu2, vmu->context, num)) { 13404 struct leave_vm_options leave_options; 13405 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13406 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13407 13408 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13409 13410 memset(&leave_options, 0, sizeof(leave_options)); 13411 leave_options.record_gain = record_gain; 13412 res = leave_voicemail(chan, mailbox, &leave_options); 13413 if (!res) 13414 res = 't'; 13415 ast_config_destroy(msg_cfg); 13416 return res; 13417 } else { 13418 /* Sender has no mailbox, can't reply */ 13419 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13420 ast_play_and_wait(chan, "vm-nobox"); 13421 res = 't'; 13422 ast_config_destroy(msg_cfg); 13423 return res; 13424 } 13425 } 13426 res = 0; 13427 13428 break; 13429 } 13430 13431 #ifndef IMAP_STORAGE 13432 ast_config_destroy(msg_cfg); 13433 13434 if (!res) { 13435 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13436 vms->heard[msg] = 1; 13437 res = wait_file(chan, vms, vms->fn); 13438 } 13439 #endif 13440 return res; 13441 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10773 of file app_voicemail.c.
References apply_options(), ast_alloca, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), LOG_WARNING, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), queue_mwi_event(), read_password_from_file(), and VM_SPOOL_DIR.
Referenced by actual_load_config().
10774 { 10775 /* Assumes lock is already held */ 10776 char *tmp; 10777 char *stringp; 10778 char *s; 10779 struct ast_vm_user *vmu; 10780 char *mailbox_full; 10781 int new = 0, old = 0, urgent = 0; 10782 char secretfn[PATH_MAX] = ""; 10783 10784 tmp = ast_strdupa(data); 10785 10786 if (!(vmu = find_or_create(context, box))) 10787 return -1; 10788 10789 populate_defaults(vmu); 10790 10791 stringp = tmp; 10792 if ((s = strsep(&stringp, ","))) { 10793 if (!ast_strlen_zero(s) && s[0] == '*') { 10794 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10795 "\n\tmust be reset in voicemail.conf.\n", box); 10796 } 10797 /* assign password regardless of validity to prevent NULL password from being assigned */ 10798 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10799 } 10800 if (stringp && (s = strsep(&stringp, ","))) { 10801 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10802 } 10803 if (stringp && (s = strsep(&stringp, ","))) { 10804 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10805 } 10806 if (stringp && (s = strsep(&stringp, ","))) { 10807 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10808 } 10809 if (stringp && (s = strsep(&stringp, ","))) { 10810 apply_options(vmu, s); 10811 } 10812 10813 switch (vmu->passwordlocation) { 10814 case OPT_PWLOC_SPOOLDIR: 10815 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10816 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10817 } 10818 10819 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10820 strcpy(mailbox_full, box); 10821 strcat(mailbox_full, "@"); 10822 strcat(mailbox_full, context); 10823 10824 inboxcount2(mailbox_full, &urgent, &new, &old); 10825 queue_mwi_event(mailbox_full, urgent, new, old); 10826 10827 return 0; 10828 }
static void apply_option | ( | struct ast_vm_user * | vmu, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Sets a a specific property value.
vmu | The voicemail user object to work with. | |
var | The name of the property to be set. | |
value | The value to be set to the property. |
The property name must be one of the understood properties. See the source for details.
Definition at line 1055 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_strdup, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::locale, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::serveremail, substitute_escapes(), VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, vmmaxsecs, vmminsecs, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
01056 { 01057 int x; 01058 if (!strcasecmp(var, "attach")) { 01059 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01060 } else if (!strcasecmp(var, "attachfmt")) { 01061 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01062 } else if (!strcasecmp(var, "serveremail")) { 01063 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01064 } else if (!strcasecmp(var, "emailbody")) { 01065 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01066 } else if (!strcasecmp(var, "emailsubject")) { 01067 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01068 } else if (!strcasecmp(var, "language")) { 01069 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01070 } else if (!strcasecmp(var, "tz")) { 01071 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01072 } else if (!strcasecmp(var, "locale")) { 01073 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01074 #ifdef IMAP_STORAGE 01075 } else if (!strcasecmp(var, "imapuser")) { 01076 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01077 vmu->imapversion = imapversion; 01078 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01079 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01080 vmu->imapversion = imapversion; 01081 } else if (!strcasecmp(var, "imapfolder")) { 01082 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01083 } else if (!strcasecmp(var, "imapvmshareid")) { 01084 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01085 vmu->imapversion = imapversion; 01086 #endif 01087 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01088 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01089 } else if (!strcasecmp(var, "saycid")){ 01090 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01091 } else if (!strcasecmp(var, "sendvoicemail")){ 01092 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01093 } else if (!strcasecmp(var, "review")){ 01094 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01095 } else if (!strcasecmp(var, "tempgreetwarn")){ 01096 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01097 } else if (!strcasecmp(var, "messagewrap")){ 01098 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01099 } else if (!strcasecmp(var, "operator")) { 01100 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01101 } else if (!strcasecmp(var, "envelope")){ 01102 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01103 } else if (!strcasecmp(var, "moveheard")){ 01104 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01105 } else if (!strcasecmp(var, "sayduration")){ 01106 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01107 } else if (!strcasecmp(var, "saydurationm")){ 01108 if (sscanf(value, "%30d", &x) == 1) { 01109 vmu->saydurationm = x; 01110 } else { 01111 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01112 } 01113 } else if (!strcasecmp(var, "forcename")){ 01114 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01115 } else if (!strcasecmp(var, "forcegreetings")){ 01116 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01117 } else if (!strcasecmp(var, "callback")) { 01118 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01119 } else if (!strcasecmp(var, "dialout")) { 01120 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01121 } else if (!strcasecmp(var, "exitcontext")) { 01122 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01123 } else if (!strcasecmp(var, "minsecs")) { 01124 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01125 vmu->minsecs = x; 01126 } else { 01127 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01128 vmu->minsecs = vmminsecs; 01129 } 01130 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01131 vmu->maxsecs = atoi(value); 01132 if (vmu->maxsecs <= 0) { 01133 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01134 vmu->maxsecs = vmmaxsecs; 01135 } else { 01136 vmu->maxsecs = atoi(value); 01137 } 01138 if (!strcasecmp(var, "maxmessage")) 01139 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01140 } else if (!strcasecmp(var, "maxmsg")) { 01141 vmu->maxmsg = atoi(value); 01142 /* Accept maxmsg=0 (Greetings only voicemail) */ 01143 if (vmu->maxmsg < 0) { 01144 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01145 vmu->maxmsg = MAXMSG; 01146 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01147 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01148 vmu->maxmsg = MAXMSGLIMIT; 01149 } 01150 } else if (!strcasecmp(var, "nextaftercmd")) { 01151 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01152 } else if (!strcasecmp(var, "backupdeleted")) { 01153 if (sscanf(value, "%30d", &x) == 1) 01154 vmu->maxdeletedmsg = x; 01155 else if (ast_true(value)) 01156 vmu->maxdeletedmsg = MAXMSG; 01157 else 01158 vmu->maxdeletedmsg = 0; 01159 01160 if (vmu->maxdeletedmsg < 0) { 01161 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01162 vmu->maxdeletedmsg = MAXMSG; 01163 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01164 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01165 vmu->maxdeletedmsg = MAXMSGLIMIT; 01166 } 01167 } else if (!strcasecmp(var, "volgain")) { 01168 sscanf(value, "%30lf", &vmu->volgain); 01169 } else if (!strcasecmp(var, "passwordlocation")) { 01170 if (!strcasecmp(value, "spooldir")) { 01171 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01172 } else { 01173 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01174 } 01175 } else if (!strcasecmp(var, "options")) { 01176 apply_options(vmu, value); 01177 } 01178 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1296 of file app_voicemail.c.
References apply_option(), ast_strdupa, value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01297 { 01298 char *stringp; 01299 char *s; 01300 char *var, *value; 01301 stringp = ast_strdupa(options); 01302 while ((s = strsep(&stringp, "|"))) { 01303 value = s; 01304 if ((var = strsep(&value, "=")) && value) { 01305 apply_option(vmu, var, value); 01306 } 01307 } 01308 }
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 1315 of file app_voicemail.c.
References apply_option(), ast_copy_string(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::fullname, LOG_WARNING, ast_vm_user::mailbox, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, substitute_escapes(), ast_vm_user::uniqueid, and ast_variable::value.
Referenced by actual_load_config(), and find_user_realtime().
01316 { 01317 for (; var; var = var->next) { 01318 if (!strcasecmp(var->name, "vmsecret")) { 01319 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01320 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01321 if (ast_strlen_zero(retval->password)) { 01322 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01323 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01324 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01325 } else { 01326 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01327 } 01328 } 01329 } else if (!strcasecmp(var->name, "uniqueid")) { 01330 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01331 } else if (!strcasecmp(var->name, "pager")) { 01332 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01333 } else if (!strcasecmp(var->name, "email")) { 01334 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01335 } else if (!strcasecmp(var->name, "fullname")) { 01336 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01337 } else if (!strcasecmp(var->name, "context")) { 01338 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01339 } else if (!strcasecmp(var->name, "emailsubject")) { 01340 ast_free(retval->emailsubject); 01341 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01342 } else if (!strcasecmp(var->name, "emailbody")) { 01343 ast_free(retval->emailbody); 01344 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01345 #ifdef IMAP_STORAGE 01346 } else if (!strcasecmp(var->name, "imapuser")) { 01347 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01348 retval->imapversion = imapversion; 01349 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01350 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01351 retval->imapversion = imapversion; 01352 } else if (!strcasecmp(var->name, "imapfolder")) { 01353 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01354 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01355 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01356 retval->imapversion = imapversion; 01357 #endif 01358 } else 01359 apply_option(retval, var->name, var->value); 01360 } 01361 }
AST_APP_OPTIONS | ( | vm_app_options | ) |
AST_DATA_STRUCTURE | ( | vm_zone | , | |
DATA_EXPORT_VM_ZONES | ||||
) |
AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
DATA_EXPORT_VM_USERS | ||||
) |
static AST_LIST_HEAD_STATIC | ( | zones | , | |
vm_zone | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | users | , | |
ast_vm_user | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
tdesc | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload , |
|||
. | nonoptreq = "res_adsi,res_smdi" | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | poll_lock | ) |
static AST_RWLIST_HEAD_STATIC | ( | mwi_subs | , | |
mwi_sub | ||||
) | [static] |
static const char* ast_str_encode_mime | ( | struct ast_str ** | end, | |
ssize_t | maxlen, | |||
const char * | start, | |||
size_t | preamble, | |||
size_t | postamble | |||
) | [static] |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.
Additionally, if the encoded string would exceed the MIME limit of 76 characters per line, then the encoding will be broken up into multiple sections, separated by a space character, in order to facilitate breaking up the associated header across multiple lines.
end | An expandable buffer for holding the result | |
maxlen | Always zero, but see |
start | A string to be encoded | |
preamble | The length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars. | |
postamble | the length of any additional characters appended to the line, used to ensure proper field wrapping. |
The | encoded string. |
Definition at line 4477 of file app_voicemail.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), and charset.
Referenced by make_email_file(), and sendpage().
04478 { 04479 struct ast_str *tmp = ast_str_alloca(80); 04480 int first_section = 1; 04481 04482 ast_str_reset(*end); 04483 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04484 for (; *start; start++) { 04485 int need_encoding = 0; 04486 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04487 need_encoding = 1; 04488 } 04489 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04490 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04491 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04492 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04493 /* Start new line */ 04494 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04495 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04496 first_section = 0; 04497 } 04498 if (need_encoding && *start == ' ') { 04499 ast_str_append(&tmp, -1, "_"); 04500 } else if (need_encoding) { 04501 ast_str_append(&tmp, -1, "=%hhX", *start); 04502 } else { 04503 ast_str_append(&tmp, -1, "%c", *start); 04504 } 04505 } 04506 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04507 return ast_str_buffer(*end); 04508 }
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 4405 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), and sendpage().
04406 { 04407 const char *ptr; 04408 04409 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04410 ast_str_set(buf, maxlen, "\""); 04411 for (ptr = from; *ptr; ptr++) { 04412 if (*ptr == '"' || *ptr == '\\') { 04413 ast_str_append(buf, maxlen, "\\%c", *ptr); 04414 } else { 04415 ast_str_append(buf, maxlen, "%c", *ptr); 04416 } 04417 } 04418 ast_str_append(buf, maxlen, "\""); 04419 04420 return ast_str_buffer(*buf); 04421 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10830 of file app_voicemail.c.
References apply_options(), ast_calloc, ast_set_flag, AST_TEST_FAIL, ast_test_flag, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, free_user(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, ast_vm_user::passwordlocation, populate_defaults(), ast_vm_user::saydurationm, ast_vm_user::serveremail, TEST_EXECUTE, TEST_INIT, VM_ALLOCED, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
10831 { 10832 int res = 0; 10833 struct ast_vm_user *vmu; 10834 /* language parameter seems to only be used for display in manager action */ 10835 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10836 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10837 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10838 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10839 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10840 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10841 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10842 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10843 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10844 #ifdef IMAP_STORAGE 10845 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10846 "imapfolder=INBOX|imapvmshareid=6000"; 10847 #endif 10848 10849 switch (cmd) { 10850 case TEST_INIT: 10851 info->name = "vmuser"; 10852 info->category = "/apps/app_voicemail/"; 10853 info->summary = "Vmuser unit test"; 10854 info->description = 10855 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10856 return AST_TEST_NOT_RUN; 10857 case TEST_EXECUTE: 10858 break; 10859 } 10860 10861 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10862 return AST_TEST_NOT_RUN; 10863 } 10864 populate_defaults(vmu); 10865 ast_set_flag(vmu, VM_ALLOCED); 10866 10867 apply_options(vmu, options_string); 10868 10869 if (!ast_test_flag(vmu, VM_ATTACH)) { 10870 ast_test_status_update(test, "Parse failure for attach option\n"); 10871 res = 1; 10872 } 10873 if (strcasecmp(vmu->attachfmt, "wav49")) { 10874 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10875 res = 1; 10876 } 10877 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10878 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10879 res = 1; 10880 } 10881 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10882 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10883 res = 1; 10884 } 10885 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10886 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10887 res = 1; 10888 } 10889 if (strcasecmp(vmu->zonetag, "central")) { 10890 ast_test_status_update(test, "Parse failure for tz option\n"); 10891 res = 1; 10892 } 10893 if (!ast_test_flag(vmu, VM_DELETE)) { 10894 ast_test_status_update(test, "Parse failure for delete option\n"); 10895 res = 1; 10896 } 10897 if (!ast_test_flag(vmu, VM_SAYCID)) { 10898 ast_test_status_update(test, "Parse failure for saycid option\n"); 10899 res = 1; 10900 } 10901 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10902 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10903 res = 1; 10904 } 10905 if (!ast_test_flag(vmu, VM_REVIEW)) { 10906 ast_test_status_update(test, "Parse failure for review option\n"); 10907 res = 1; 10908 } 10909 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10910 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10911 res = 1; 10912 } 10913 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10914 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10915 res = 1; 10916 } 10917 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10918 ast_test_status_update(test, "Parse failure for operator option\n"); 10919 res = 1; 10920 } 10921 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10922 ast_test_status_update(test, "Parse failure for envelope option\n"); 10923 res = 1; 10924 } 10925 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10926 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10927 res = 1; 10928 } 10929 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10930 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10931 res = 1; 10932 } 10933 if (vmu->saydurationm != 5) { 10934 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10935 res = 1; 10936 } 10937 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10938 ast_test_status_update(test, "Parse failure for forcename option\n"); 10939 res = 1; 10940 } 10941 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10942 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10943 res = 1; 10944 } 10945 if (strcasecmp(vmu->callback, "somecontext")) { 10946 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10947 res = 1; 10948 } 10949 if (strcasecmp(vmu->dialout, "somecontext2")) { 10950 ast_test_status_update(test, "Parse failure for dialout option\n"); 10951 res = 1; 10952 } 10953 if (strcasecmp(vmu->exit, "somecontext3")) { 10954 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10955 res = 1; 10956 } 10957 if (vmu->minsecs != 10) { 10958 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10959 res = 1; 10960 } 10961 if (vmu->maxsecs != 100) { 10962 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10963 res = 1; 10964 } 10965 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10966 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10967 res = 1; 10968 } 10969 if (vmu->maxdeletedmsg != 50) { 10970 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10971 res = 1; 10972 } 10973 if (vmu->volgain != 1.3) { 10974 ast_test_status_update(test, "Parse failure for volgain option\n"); 10975 res = 1; 10976 } 10977 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10978 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10979 res = 1; 10980 } 10981 #ifdef IMAP_STORAGE 10982 apply_options(vmu, option_string2); 10983 10984 if (strcasecmp(vmu->imapuser, "imapuser")) { 10985 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10986 res = 1; 10987 } 10988 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10989 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10990 res = 1; 10991 } 10992 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10993 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 10994 res = 1; 10995 } 10996 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10997 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10998 res = 1; 10999 } 11000 #endif 11001 11002 free_user(vmu); 11003 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11004 }
static int base_encode | ( | char * | filename, | |
FILE * | so | |||
) | [static] |
Performs a base 64 encode algorithm on the contents of a File.
filename | The path to the file to be encoded. Must be readable, file is opened in read mode. | |
so | A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename. |
TODO: shouldn't this (and the above 3 support functions) be put into some kind of external utility location, such as funcs/func_base64.c ?
Definition at line 4281 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
Referenced by add_email_attachment().
04282 { 04283 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04284 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04285 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04286 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04287 int i, hiteof = 0; 04288 FILE *fi; 04289 struct baseio bio; 04290 04291 memset(&bio, 0, sizeof(bio)); 04292 bio.iocp = BASEMAXINLINE; 04293 04294 if (!(fi = fopen(filename, "rb"))) { 04295 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04296 return -1; 04297 } 04298 04299 while (!hiteof){ 04300 unsigned char igroup[3], ogroup[4]; 04301 int c, n; 04302 04303 memset(igroup, 0, sizeof(igroup)); 04304 04305 for (n = 0; n < 3; n++) { 04306 if ((c = inchar(&bio, fi)) == EOF) { 04307 hiteof = 1; 04308 break; 04309 } 04310 04311 igroup[n] = (unsigned char) c; 04312 } 04313 04314 if (n > 0) { 04315 ogroup[0]= dtable[igroup[0] >> 2]; 04316 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04317 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04318 ogroup[3]= dtable[igroup[2] & 0x3F]; 04319 04320 if (n < 3) { 04321 ogroup[3] = '='; 04322 04323 if (n < 2) 04324 ogroup[2] = '='; 04325 } 04326 04327 for (i = 0; i < 4; i++) 04328 ochar(&bio, ogroup[i], so); 04329 } 04330 } 04331 04332 fclose(fi); 04333 04334 if (fputs(ENDL, so) == EOF) { 04335 return 0; 04336 } 04337 04338 return 1; 04339 }
static int change_password_realtime | ( | struct ast_vm_user * | vmu, | |
const char * | password | |||
) | [static] |
Performs a change of the voicemail passowrd in the realtime engine.
vmu | The voicemail user to change the password for. | |
password | The new value to be set to the password for this user. |
This only works if there is a realtime engine configured. This is called from the (top level) vm_change_password.
Definition at line 1274 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().
01275 { 01276 int res = -1; 01277 if (!strcmp(vmu->password, password)) { 01278 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01279 return 0; 01280 } 01281 01282 if (strlen(password) > 10) { 01283 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01284 } 01285 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01286 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01287 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01288 res = 0; 01289 } 01290 return res; 01291 }
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 4450 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
static int check_password | ( | struct ast_vm_user * | vmu, | |
char * | password | |||
) | [static] |
Check that password meets minimum required length.
vmu | The voicemail user to change the password for. | |
password | The password string to check |
Definition at line 1233 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ext_pass_check_cmd, ast_vm_user::mailbox, minpassword, ast_vm_user::password, and vm_check_password_shell().
Referenced by vm_newuser(), and vm_options().
01234 { 01235 /* check minimum length */ 01236 if (strlen(password) < minpassword) 01237 return 1; 01238 /* check that password does not contain '*' character */ 01239 if (!ast_strlen_zero(password) && password[0] == '*') 01240 return 1; 01241 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01242 char cmd[255], buf[255]; 01243 01244 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01245 01246 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01247 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01248 ast_debug(5, "Result: %s\n", buf); 01249 if (!strncasecmp(buf, "VALID", 5)) { 01250 ast_debug(3, "Passed password check: '%s'\n", buf); 01251 return 0; 01252 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01253 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01254 return 0; 01255 } else { 01256 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01257 return 1; 01258 } 01259 } 01260 } 01261 return 0; 01262 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7968 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_free, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_unlock_path(), ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, vm_state::dh_arraysize, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::heard, last_message_index(), vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
07969 { 07970 int x = 0; 07971 int last_msg_idx = 0; 07972 07973 #ifndef IMAP_STORAGE 07974 int res = 0, nummsg; 07975 char fn2[PATH_MAX]; 07976 #endif 07977 07978 if (vms->lastmsg <= -1) { 07979 goto done; 07980 } 07981 07982 vms->curmsg = -1; 07983 #ifndef IMAP_STORAGE 07984 /* Get the deleted messages fixed */ 07985 if (vm_lock_path(vms->curdir)) { 07986 return ERROR_LOCK_PATH; 07987 } 07988 07989 /* update count as message may have arrived while we've got mailbox open */ 07990 last_msg_idx = last_message_index(vmu, vms->curdir); 07991 if (last_msg_idx != vms->lastmsg) { 07992 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07993 } 07994 07995 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07996 for (x = 0; x < last_msg_idx + 1; x++) { 07997 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07998 /* Save this message. It's not in INBOX or hasn't been heard */ 07999 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08000 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08001 break; 08002 } 08003 vms->curmsg++; 08004 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08005 if (strcmp(vms->fn, fn2)) { 08006 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08007 } 08008 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08009 /* Move to old folder before deleting */ 08010 res = save_to_folder(vmu, vms, x, 1); 08011 if (res == ERROR_LOCK_PATH) { 08012 /* If save failed do not delete the message */ 08013 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08014 vms->deleted[x] = 0; 08015 vms->heard[x] = 0; 08016 --x; 08017 } 08018 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08019 /* Move to deleted folder */ 08020 res = save_to_folder(vmu, vms, x, 10); 08021 if (res == ERROR_LOCK_PATH) { 08022 /* If save failed do not delete the message */ 08023 vms->deleted[x] = 0; 08024 vms->heard[x] = 0; 08025 --x; 08026 } 08027 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08028 /* If realtime storage enabled - we should explicitly delete this message, 08029 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08030 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08031 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08032 DELETE(vms->curdir, x, vms->fn, vmu); 08033 } 08034 } 08035 } 08036 08037 /* Delete ALL remaining messages */ 08038 nummsg = x - 1; 08039 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08040 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08041 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08042 DELETE(vms->curdir, x, vms->fn, vmu); 08043 } 08044 } 08045 ast_unlock_path(vms->curdir); 08046 #else /* defined(IMAP_STORAGE) */ 08047 ast_mutex_lock(&vms->lock); 08048 if (vms->deleted) { 08049 /* Since we now expunge after each delete, deleting in reverse order 08050 * ensures that no reordering occurs between each step. */ 08051 last_msg_idx = vms->dh_arraysize; 08052 for (x = last_msg_idx - 1; x >= 0; x--) { 08053 if (vms->deleted[x]) { 08054 ast_debug(3, "IMAP delete of %d\n", x); 08055 DELETE(vms->curdir, x, vms->fn, vmu); 08056 } 08057 } 08058 } 08059 #endif 08060 08061 done: 08062 if (vms->deleted) { 08063 ast_free(vms->deleted); 08064 vms->deleted = NULL; 08065 } 08066 if (vms->heard) { 08067 ast_free(vms->heard); 08068 vms->heard = NULL; 08069 } 08070 vms->dh_arraysize = 0; 08071 #ifdef IMAP_STORAGE 08072 ast_mutex_unlock(&vms->lock); 08073 #endif 08074 08075 return 0; 08076 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11150 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11151 { 11152 int which = 0; 11153 int wordlen; 11154 struct ast_vm_user *vmu; 11155 const char *context = ""; 11156 11157 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11158 if (pos > 4) 11159 return NULL; 11160 if (pos == 3) 11161 return (state == 0) ? ast_strdup("for") : NULL; 11162 wordlen = strlen(word); 11163 AST_LIST_TRAVERSE(&users, vmu, list) { 11164 if (!strncasecmp(word, vmu->context, wordlen)) { 11165 if (context && strcmp(context, vmu->context) && ++which > state) 11166 return ast_strdup(vmu->context); 11167 /* ignore repeated contexts ? */ 11168 context = vmu->context; 11169 } 11170 } 11171 return NULL; 11172 }
static int copy | ( | char * | infile, | |
char * | outfile | |||
) | [static] |
Utility function to copy a file.
infile | The path to the file to be copied. The file must be readable, it is opened in read only mode. | |
outfile | The path for which to copy the file to. The directory permissions must allow the creation (or truncation) of the file, and allow for opening the file in write only mode. |
When the compiler option HARDLINK_WHEN_POSSIBLE is set, the copy operation will attempt to use the hard link facility instead of copy the file (to save disk space). If the link operation fails, it falls back to the copy operation. The copy operation copies up to 4096 bytes at once.
Definition at line 4086 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by ast_func_read(), ast_func_read2(), ast_func_write(), copy_plain_file(), iax2_register(), and vm_forwardoptions().
04087 { 04088 int ifd; 04089 int ofd; 04090 int res; 04091 int len; 04092 char buf[4096]; 04093 04094 #ifdef HARDLINK_WHEN_POSSIBLE 04095 /* Hard link if possible; saves disk space & is faster */ 04096 if (link(infile, outfile)) { 04097 #endif 04098 if ((ifd = open(infile, O_RDONLY)) < 0) { 04099 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04100 return -1; 04101 } 04102 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04103 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04104 close(ifd); 04105 return -1; 04106 } 04107 do { 04108 len = read(ifd, buf, sizeof(buf)); 04109 if (len < 0) { 04110 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04111 close(ifd); 04112 close(ofd); 04113 unlink(outfile); 04114 } else if (len) { 04115 res = write(ofd, buf, len); 04116 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04117 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04118 close(ifd); 04119 close(ofd); 04120 unlink(outfile); 04121 } 04122 } 04123 } while (len); 04124 close(ifd); 04125 close(ofd); 04126 return 0; 04127 #ifdef HARDLINK_WHEN_POSSIBLE 04128 } else { 04129 /* Hard link succeeded */ 04130 return 0; 04131 } 04132 #endif 04133 }
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 5322 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::caller, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_party_caller::id, inprocess_count(), last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), maxmsg, mbox(), ast_party_id::name, notify_new_message(), ast_party_id::number, S_COR, STORE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, vm_delete(), and vm_lock_path().
Referenced by forward_message(), and leave_voicemail().
05323 { 05324 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05325 const char *frombox = mbox(vmu, imbox); 05326 const char *userfolder; 05327 int recipmsgnum; 05328 int res = 0; 05329 05330 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05331 05332 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05333 userfolder = "Urgent"; 05334 } else { 05335 userfolder = "INBOX"; 05336 } 05337 05338 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05339 05340 if (!dir) 05341 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05342 else 05343 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05344 05345 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05346 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05347 05348 if (vm_lock_path(todir)) 05349 return ERROR_LOCK_PATH; 05350 05351 recipmsgnum = last_message_index(recip, todir) + 1; 05352 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05353 make_file(topath, sizeof(topath), todir, recipmsgnum); 05354 #ifndef ODBC_STORAGE 05355 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05356 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05357 } else { 05358 #endif 05359 /* If we are prepending a message for ODBC, then the message already 05360 * exists in the database, but we want to force copying from the 05361 * filesystem (since only the FS contains the prepend). */ 05362 copy_plain_file(frompath, topath); 05363 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05364 vm_delete(topath); 05365 #ifndef ODBC_STORAGE 05366 } 05367 #endif 05368 } else { 05369 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05370 res = -1; 05371 } 05372 ast_unlock_path(todir); 05373 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05374 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05375 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05376 flag); 05377 05378 return res; 05379 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Every voicemail has the data (.wav) file, and the information file. This function performs the file system copying of the information file for a voicemail, handling the internal fields and their values. This is used by the COPY macro when not using IMAP storage.
Definition at line 4144 of file app_voicemail.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), ast_store_realtime(), ast_variables_destroy(), copy(), exten, ast_variable::name, ast_variable::next, SENTINEL, and ast_variable::value.
Referenced by copy_message().
04145 { 04146 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04147 struct ast_variable *tmp,*var = NULL; 04148 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04149 ast_filecopy(frompath, topath, NULL); 04150 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04151 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04152 if (ast_check_realtime("voicemail_data")) { 04153 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04154 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04155 for (tmp = var; tmp; tmp = tmp->next) { 04156 if (!strcasecmp(tmp->name, "origmailbox")) { 04157 origmailbox = tmp->value; 04158 } else if (!strcasecmp(tmp->name, "context")) { 04159 context = tmp->value; 04160 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04161 macrocontext = tmp->value; 04162 } else if (!strcasecmp(tmp->name, "exten")) { 04163 exten = tmp->value; 04164 } else if (!strcasecmp(tmp->name, "priority")) { 04165 priority = tmp->value; 04166 } else if (!strcasecmp(tmp->name, "callerchan")) { 04167 callerchan = tmp->value; 04168 } else if (!strcasecmp(tmp->name, "callerid")) { 04169 callerid = tmp->value; 04170 } else if (!strcasecmp(tmp->name, "origdate")) { 04171 origdate = tmp->value; 04172 } else if (!strcasecmp(tmp->name, "origtime")) { 04173 origtime = tmp->value; 04174 } else if (!strcasecmp(tmp->name, "category")) { 04175 category = tmp->value; 04176 } else if (!strcasecmp(tmp->name, "duration")) { 04177 duration = tmp->value; 04178 } 04179 } 04180 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); 04181 } 04182 copy(frompath2, topath2); 04183 ast_variables_destroy(var); 04184 }
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 3981 of file app_voicemail.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().
03982 { 03983 03984 int vmcount = 0; 03985 DIR *vmdir = NULL; 03986 struct dirent *vment = NULL; 03987 03988 if (vm_lock_path(dir)) 03989 return ERROR_LOCK_PATH; 03990 03991 if ((vmdir = opendir(dir))) { 03992 while ((vment = readdir(vmdir))) { 03993 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03994 vmcount++; 03995 } 03996 } 03997 closedir(vmdir); 03998 } 03999 ast_unlock_path(dir); 04000 04001 return vmcount; 04002 }
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 1684 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
01685 { 01686 mode_t mode = VOICEMAIL_DIR_MODE; 01687 int res; 01688 01689 make_dir(dest, len, context, ext, folder); 01690 if ((res = ast_mkdir(dest, mode))) { 01691 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01692 return -1; 01693 } 01694 return 0; 01695 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13178 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().
13179 { 13180 int cmd = 0; 13181 char destination[80] = ""; 13182 int retries = 0; 13183 13184 if (!num) { 13185 ast_verb(3, "Destination number will be entered manually\n"); 13186 while (retries < 3 && cmd != 't') { 13187 destination[1] = '\0'; 13188 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13189 if (!cmd) 13190 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13191 if (!cmd) 13192 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13193 if (!cmd) { 13194 cmd = ast_waitfordigit(chan, 6000); 13195 if (cmd) 13196 destination[0] = cmd; 13197 } 13198 if (!cmd) { 13199 retries++; 13200 } else { 13201 13202 if (cmd < 0) 13203 return 0; 13204 if (cmd == '*') { 13205 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13206 return 0; 13207 } 13208 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13209 retries++; 13210 else 13211 cmd = 't'; 13212 } 13213 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13214 } 13215 if (retries >= 3) { 13216 return 0; 13217 } 13218 13219 } else { 13220 if (option_verbose > 2) 13221 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13222 ast_copy_string(destination, num, sizeof(destination)); 13223 } 13224 13225 if (!ast_strlen_zero(destination)) { 13226 if (destination[strlen(destination) -1 ] == '*') 13227 return 0; 13228 if (option_verbose > 2) 13229 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13230 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13231 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13232 chan->priority = 0; 13233 return 9; 13234 } 13235 return 0; 13236 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10733 of file app_voicemail.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, globalflags, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by actual_load_config(), and append_mailbox().
10734 { 10735 struct ast_vm_user *vmu; 10736 10737 if (!ast_strlen_zero(box) && box[0] == '*') { 10738 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10739 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10740 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10741 "\n\tand will be ignored.\n", box, context); 10742 return NULL; 10743 } 10744 10745 AST_LIST_TRAVERSE(&users, vmu, list) { 10746 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10747 if (strcasecmp(vmu->context, context)) { 10748 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10749 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10750 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10751 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10752 } 10753 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10754 return NULL; 10755 } 10756 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10757 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10758 return NULL; 10759 } 10760 } 10761 10762 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10763 return NULL; 10764 10765 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10766 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10767 10768 AST_LIST_INSERT_TAIL(&users, vmu, list); 10769 10770 return vmu; 10771 }
static struct ast_vm_user* find_user | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static, read] |
Finds a voicemail user from the users file or the realtime engine.
ivm | ||
context | ||
mailbox |
Definition at line 1436 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_strdup, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, find_user_realtime(), globalflags, VM_ALLOCED, and VM_SEARCH.
Referenced by acf_mailbox_exists(), advanced_options(), forward_message(), leave_voicemail(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01437 { 01438 /* This function could be made to generate one from a database, too */ 01439 struct ast_vm_user *vmu = NULL, *cur; 01440 AST_LIST_LOCK(&users); 01441 01442 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01443 context = "default"; 01444 01445 AST_LIST_TRAVERSE(&users, cur, list) { 01446 #ifdef IMAP_STORAGE 01447 if (cur->imapversion != imapversion) { 01448 continue; 01449 } 01450 #endif 01451 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01452 break; 01453 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01454 break; 01455 } 01456 if (cur) { 01457 /* Make a copy, so that on a reload, we have no race */ 01458 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01459 *vmu = *cur; 01460 if (!ivm) { 01461 vmu->emailbody = ast_strdup(cur->emailbody); 01462 vmu->emailsubject = ast_strdup(cur->emailsubject); 01463 } 01464 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01465 AST_LIST_NEXT(vmu, list) = NULL; 01466 } 01467 } else 01468 vmu = find_user_realtime(ivm, context, mailbox); 01469 AST_LIST_UNLOCK(&users); 01470 return vmu; 01471 }
static struct ast_vm_user* find_user_realtime | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static, read] |
Finds a voicemail user from the realtime engine.
ivm | ||
context | ||
mailbox | This is called as a fall through case when the normal find_user() was not able to find a user. That is, the default it so look in the usual voicemail users file first. |
Definition at line 1395 of file app_voicemail.c.
References apply_options_full(), ast_calloc, ast_copy_string(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free_user(), globalflags, ast_vm_user::mailbox, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
Referenced by find_user().
01396 { 01397 struct ast_variable *var; 01398 struct ast_vm_user *retval; 01399 01400 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01401 if (ivm) { 01402 memset(retval, 0, sizeof(*retval)); 01403 } 01404 populate_defaults(retval); 01405 if (!ivm) { 01406 ast_set_flag(retval, VM_ALLOCED); 01407 } 01408 if (mailbox) { 01409 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01410 } 01411 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01412 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01413 } else { 01414 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01415 } 01416 if (var) { 01417 apply_options_full(retval, var); 01418 ast_variables_destroy(var); 01419 } else { 01420 if (!ivm) 01421 free_user(retval); 01422 retval = NULL; 01423 } 01424 } 01425 return retval; 01426 }
static int forward_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
struct vm_state * | vms, | |||
struct ast_vm_user * | sender, | |||
char * | fmt, | |||
int | is_new_message, | |||
signed char | record_gain, | |||
int | urgent | |||
) | [static] |
Sends a voicemail message to a mailbox recipient.
chan | ||
context | ||
vms | ||
sender | ||
fmt | ||
is_new_message | Used to indicate the mode for which this method was invoked. Will be 0 when called to forward an existing message (option 8) Will be 1 when called to leave a message (option 3->5) | |
record_gain | ||
urgent | Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory. |
When in the leave message mode (is_new_message == 1):
When in the forward message mode (is_new_message == 0):
Definition at line 7169 of file app_voicemail.c.
References ast_clear_flag, ast_copy_string(), ast_fileexists(), ast_filerename(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_waitfordigit(), ast_channel::caller, ast_vm_user::context, ast_channel::context, copy_message(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_party_caller::id, inboxcount(), inprocess_count(), leave_voicemail(), LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_party_id::name, ast_party_id::number, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), serveremail, STORE, ast_party_name::str, ast_party_number::str, vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), VM_FWDURGAUTO, VM_SPOOL_DIR, and vmfmts.
Referenced by vm_execmain().
07170 { 07171 #ifdef IMAP_STORAGE 07172 int todircount = 0; 07173 struct vm_state *dstvms; 07174 #endif 07175 char username[70]=""; 07176 char fn[PATH_MAX]; /* for playback of name greeting */ 07177 char ecodes[16] = "#"; 07178 int res = 0, cmd = 0; 07179 struct ast_vm_user *receiver = NULL, *vmtmp; 07180 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07181 char *stringp; 07182 const char *s; 07183 int saved_messages = 0; 07184 int valid_extensions = 0; 07185 char *dir; 07186 int curmsg; 07187 char urgent_str[7] = ""; 07188 int prompt_played = 0; 07189 #ifndef IMAP_STORAGE 07190 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07191 #endif 07192 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07193 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07194 } 07195 07196 if (vms == NULL) return -1; 07197 dir = vms->curdir; 07198 curmsg = vms->curmsg; 07199 07200 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07201 while (!res && !valid_extensions) { 07202 int use_directory = 0; 07203 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07204 int done = 0; 07205 int retries = 0; 07206 cmd = 0; 07207 while ((cmd >= 0) && !done ){ 07208 if (cmd) 07209 retries = 0; 07210 switch (cmd) { 07211 case '1': 07212 use_directory = 0; 07213 done = 1; 07214 break; 07215 case '2': 07216 use_directory = 1; 07217 done = 1; 07218 break; 07219 case '*': 07220 cmd = 't'; 07221 done = 1; 07222 break; 07223 default: 07224 /* Press 1 to enter an extension press 2 to use the directory */ 07225 cmd = ast_play_and_wait(chan, "vm-forward"); 07226 if (!cmd) { 07227 cmd = ast_waitfordigit(chan, 3000); 07228 } 07229 if (!cmd) { 07230 retries++; 07231 } 07232 if (retries > 3) { 07233 cmd = 't'; 07234 done = 1; 07235 } 07236 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07237 } 07238 } 07239 if (cmd < 0 || cmd == 't') 07240 break; 07241 } 07242 07243 if (use_directory) { 07244 /* use app_directory */ 07245 07246 char old_context[sizeof(chan->context)]; 07247 char old_exten[sizeof(chan->exten)]; 07248 int old_priority; 07249 struct ast_app* directory_app; 07250 07251 directory_app = pbx_findapp("Directory"); 07252 if (directory_app) { 07253 char vmcontext[256]; 07254 /* make backup copies */ 07255 memcpy(old_context, chan->context, sizeof(chan->context)); 07256 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07257 old_priority = chan->priority; 07258 07259 /* call the the Directory, changes the channel */ 07260 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07261 res = pbx_exec(chan, directory_app, vmcontext); 07262 07263 ast_copy_string(username, chan->exten, sizeof(username)); 07264 07265 /* restore the old context, exten, and priority */ 07266 memcpy(chan->context, old_context, sizeof(chan->context)); 07267 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07268 chan->priority = old_priority; 07269 } else { 07270 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07271 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07272 } 07273 } else { 07274 /* Ask for an extension */ 07275 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07276 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07277 prompt_played++; 07278 if (res || prompt_played > 4) 07279 break; 07280 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07281 break; 07282 } 07283 07284 /* start all over if no username */ 07285 if (ast_strlen_zero(username)) 07286 continue; 07287 stringp = username; 07288 s = strsep(&stringp, "*"); 07289 /* start optimistic */ 07290 valid_extensions = 1; 07291 while (s) { 07292 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07293 int oldmsgs; 07294 int newmsgs; 07295 int capacity; 07296 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07297 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07298 /* Shouldn't happen, but allow trying another extension if it does */ 07299 res = ast_play_and_wait(chan, "pbx-invalid"); 07300 valid_extensions = 0; 07301 break; 07302 } 07303 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07304 if ((newmsgs + oldmsgs) >= capacity) { 07305 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07306 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07307 valid_extensions = 0; 07308 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07309 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07310 free_user(vmtmp); 07311 } 07312 inprocess_count(receiver->mailbox, receiver->context, -1); 07313 break; 07314 } 07315 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07316 } else { 07317 /* XXX Optimization for the future. When we encounter a single bad extension, 07318 * bailing out on all of the extensions may not be the way to go. We should 07319 * probably just bail on that single extension, then allow the user to enter 07320 * several more. XXX 07321 */ 07322 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07323 free_user(receiver); 07324 } 07325 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07326 /* "I am sorry, that's not a valid extension. Please try again." */ 07327 res = ast_play_and_wait(chan, "pbx-invalid"); 07328 valid_extensions = 0; 07329 break; 07330 } 07331 07332 /* play name if available, else play extension number */ 07333 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07334 RETRIEVE(fn, -1, s, receiver->context); 07335 if (ast_fileexists(fn, NULL, NULL) > 0) { 07336 res = ast_stream_and_wait(chan, fn, ecodes); 07337 if (res) { 07338 DISPOSE(fn, -1); 07339 return res; 07340 } 07341 } else { 07342 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07343 } 07344 DISPOSE(fn, -1); 07345 07346 s = strsep(&stringp, "*"); 07347 } 07348 /* break from the loop of reading the extensions */ 07349 if (valid_extensions) 07350 break; 07351 } 07352 /* check if we're clear to proceed */ 07353 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07354 return res; 07355 if (is_new_message == 1) { 07356 struct leave_vm_options leave_options; 07357 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07358 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07359 07360 /* Send VoiceMail */ 07361 memset(&leave_options, 0, sizeof(leave_options)); 07362 leave_options.record_gain = record_gain; 07363 cmd = leave_voicemail(chan, mailbox, &leave_options); 07364 } else { 07365 /* Forward VoiceMail */ 07366 long duration = 0; 07367 struct vm_state vmstmp; 07368 int copy_msg_result = 0; 07369 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07370 07371 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07372 07373 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07374 if (!cmd) { 07375 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07376 #ifdef IMAP_STORAGE 07377 int attach_user_voicemail; 07378 char *myserveremail = serveremail; 07379 07380 /* get destination mailbox */ 07381 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07382 if (!dstvms) { 07383 dstvms = create_vm_state_from_user(vmtmp); 07384 } 07385 if (dstvms) { 07386 init_mailstream(dstvms, 0); 07387 if (!dstvms->mailstream) { 07388 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07389 } else { 07390 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07391 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07392 } 07393 } else { 07394 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07395 } 07396 if (!ast_strlen_zero(vmtmp->serveremail)) 07397 myserveremail = vmtmp->serveremail; 07398 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07399 /* NULL category for IMAP storage */ 07400 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07401 dstvms->curbox, 07402 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07403 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07404 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07405 NULL, urgent_str); 07406 #else 07407 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07408 #endif 07409 saved_messages++; 07410 AST_LIST_REMOVE_CURRENT(list); 07411 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07412 free_user(vmtmp); 07413 if (res) 07414 break; 07415 } 07416 AST_LIST_TRAVERSE_SAFE_END; 07417 if (saved_messages > 0 && !copy_msg_result) { 07418 /* give confirmation that the message was saved */ 07419 /* commented out since we can't forward batches yet 07420 if (saved_messages == 1) 07421 res = ast_play_and_wait(chan, "vm-message"); 07422 else 07423 res = ast_play_and_wait(chan, "vm-messages"); 07424 if (!res) 07425 res = ast_play_and_wait(chan, "vm-saved"); */ 07426 #ifdef IMAP_STORAGE 07427 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07428 if (ast_strlen_zero(vmstmp.introfn)) 07429 #endif 07430 res = ast_play_and_wait(chan, "vm-msgsaved"); 07431 } 07432 #ifndef IMAP_STORAGE 07433 else { 07434 /* with IMAP, mailbox full warning played by imap_check_limits */ 07435 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07436 } 07437 /* Restore original message without prepended message if backup exists */ 07438 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07439 strcpy(textfile, msgfile); 07440 strcpy(backup, msgfile); 07441 strcpy(backup_textfile, msgfile); 07442 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07443 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07444 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07445 if (ast_fileexists(backup, NULL, NULL) > 0) { 07446 ast_filerename(backup, msgfile, NULL); 07447 rename(backup_textfile, textfile); 07448 } 07449 #endif 07450 } 07451 DISPOSE(dir, curmsg); 07452 #ifndef IMAP_STORAGE 07453 if (cmd) { /* assuming hangup, cleanup backup file */ 07454 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07455 strcpy(textfile, msgfile); 07456 strcpy(backup_textfile, msgfile); 07457 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07458 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07459 rename(backup_textfile, textfile); 07460 } 07461 #endif 07462 } 07463 07464 /* If anything failed above, we still have this list to free */ 07465 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07466 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07467 free_user(vmtmp); 07468 } 07469 return res ? res : cmd; 07470 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1739 of file app_voicemail.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
Referenced by AST_TEST_DEFINE(), find_user_realtime(), forward_message(), free_vm_users(), leave_voicemail(), and vm_execmain().
01740 { 01741 if (ast_test_flag(vmu, VM_ALLOCED)) { 01742 01743 ast_free(vmu->emailbody); 01744 vmu->emailbody = NULL; 01745 01746 ast_free(vmu->emailsubject); 01747 vmu->emailsubject = NULL; 01748 01749 ast_free(vmu); 01750 } 01751 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11762 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), and VM_ALLOCED.
Referenced by actual_load_config(), and unload_module().
11763 { 11764 struct ast_vm_user *current; 11765 AST_LIST_LOCK(&users); 11766 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11767 ast_set_flag(current, VM_ALLOCED); 11768 free_user(current); 11769 } 11770 AST_LIST_UNLOCK(&users); 11771 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11774 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by actual_load_config(), and unload_module().
11775 { 11776 struct vm_zone *zcur; 11777 AST_LIST_LOCK(&zones); 11778 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11779 free_zone(zcur); 11780 AST_LIST_UNLOCK(&zones); 11781 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5090 of file app_voicemail.c.
References ast_free.
Referenced by free_vm_zones().
05091 { 05092 ast_free(z); 05093 }
static int get_date | ( | char * | s, | |
int | len | |||
) | [static] |
Gets the current date and time, as formatted string.
s | The buffer to hold the output formatted date. | |
len | the length of the buffer. Used to prevent buffer overflow in ast_strftime. |
The date format string used is "%a %b %e %r UTC %Y".
Definition at line 5046 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
05047 { 05048 struct ast_tm tm; 05049 struct timeval t = ast_tvnow(); 05050 05051 ast_localtime(&t, &tm, "UTC"); 05052 05053 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05054 }
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 6778 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_fileexists(), ast_play_and_wait(), ast_say_number(), ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), mbox(), and vm_play_folder_name().
Referenced by get_folder2().
06779 { 06780 int x; 06781 int d; 06782 char fn[PATH_MAX]; 06783 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06784 if (d) 06785 return d; 06786 for (x = start; x < 5; x++) { /* For all folders */ 06787 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06788 return d; 06789 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06790 if (d) 06791 return d; 06792 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06793 06794 /* The inbox folder can have its name changed under certain conditions 06795 * so this checks if the sound file exists for the inbox folder name and 06796 * if it doesn't, plays the default name instead. */ 06797 if (x == 0) { 06798 if (ast_fileexists(fn, NULL, NULL)) { 06799 d = vm_play_folder_name(chan, fn); 06800 } else { 06801 ast_verb(1, "failed to find %s\n", fn); 06802 d = vm_play_folder_name(chan, "vm-INBOX"); 06803 } 06804 } else { 06805 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06806 d = vm_play_folder_name(chan, fn); 06807 } 06808 06809 if (d) 06810 return d; 06811 d = ast_waitfordigit(chan, 500); 06812 if (d) 06813 return d; 06814 } 06815 06816 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06817 if (d) 06818 return d; 06819 d = ast_waitfordigit(chan, 4000); 06820 return d; 06821 }
static int get_folder2 | ( | struct ast_channel * | chan, | |
char * | fn, | |||
int | start | |||
) | [static] |
plays a prompt and waits for a keypress.
chan | ||
fn | the name of the voice prompt file to be played. For example, 'vm-changeto', 'vm-savefolder' | |
start | Does not appear to be used at this time. |
This is used by the main menu option to move a message to a folder or to save a message into a folder. After playing the message identified by the fn parameter value, it calls get_folder(), which plays the prompting for the number inputs that correspond to the available folders.
Definition at line 6835 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06836 { 06837 int res = 0; 06838 int loops = 0; 06839 06840 res = ast_play_and_wait(chan, fn); /* Folder name */ 06841 while (((res < '0') || (res > '9')) && 06842 (res != '#') && (res >= 0) && 06843 loops < 4) { 06844 res = get_folder(chan, 0); 06845 loops++; 06846 } 06847 if (loops == 4) { /* give up */ 06848 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06849 return '#'; 06850 } 06851 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06852 return res; 06853 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1726 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by vm_execmain().
01727 { 01728 size_t i; 01729 01730 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01731 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01732 return i; 01733 } 01734 } 01735 01736 return -1; 01737 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11532 of file app_voicemail.c.
References ast_calloc, ast_free, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), mwi_sub_task::context, mwi_sub_task::mailbox, poll_subscribed_mailbox(), and mwi_sub_task::uniqueid.
Referenced by mwi_sub_event_cb().
11533 { 11534 unsigned int len; 11535 struct mwi_sub *mwi_sub; 11536 struct mwi_sub_task *p = datap; 11537 11538 len = sizeof(*mwi_sub); 11539 if (!ast_strlen_zero(p->mailbox)) 11540 len += strlen(p->mailbox); 11541 11542 if (!ast_strlen_zero(p->context)) 11543 len += strlen(p->context) + 1; /* Allow for seperator */ 11544 11545 if (!(mwi_sub = ast_calloc(1, len))) 11546 return -1; 11547 11548 mwi_sub->uniqueid = p->uniqueid; 11549 if (!ast_strlen_zero(p->mailbox)) 11550 strcpy(mwi_sub->mailbox, p->mailbox); 11551 11552 if (!ast_strlen_zero(p->context)) { 11553 strcat(mwi_sub->mailbox, "@"); 11554 strcat(mwi_sub->mailbox, p->context); 11555 } 11556 11557 AST_RWLIST_WRLOCK(&mwi_subs); 11558 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11559 AST_RWLIST_UNLOCK(&mwi_subs); 11560 ast_free((void *) p->mailbox); 11561 ast_free((void *) p->context); 11562 ast_free(p); 11563 poll_subscribed_mailbox(mwi_sub); 11564 return 0; 11565 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11510 of file app_voicemail.c.
References ast_free, AST_LIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and mwi_sub_destroy().
Referenced by mwi_unsub_event_cb().
11511 { 11512 struct mwi_sub *mwi_sub; 11513 uint32_t *uniqueid = datap; 11514 11515 AST_RWLIST_WRLOCK(&mwi_subs); 11516 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11517 if (mwi_sub->uniqueid == *uniqueid) { 11518 AST_LIST_REMOVE_CURRENT(entry); 11519 break; 11520 } 11521 } 11522 AST_RWLIST_TRAVERSE_SAFE_END 11523 AST_RWLIST_UNLOCK(&mwi_subs); 11524 11525 if (mwi_sub) 11526 mwi_sub_destroy(mwi_sub); 11527 11528 ast_free(uniqueid); 11529 return 0; 11530 }
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 11287 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.
11288 { 11289 switch (cmd) { 11290 case CLI_INIT: 11291 e->command = "voicemail reload"; 11292 e->usage = 11293 "Usage: voicemail reload\n" 11294 " Reload voicemail configuration\n"; 11295 return NULL; 11296 case CLI_GENERATE: 11297 return NULL; 11298 } 11299 11300 if (a->argc != 2) 11301 return CLI_SHOWUSAGE; 11302 11303 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11304 load_config(1); 11305 11306 return CLI_SUCCESS; 11307 }
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 11175 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_check_realtime(), ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_voicemail_show_users(), ast_vm_user::context, ast_cli_args::fd, ast_vm_user::fullname, HVSU_OUTPUT_FORMAT, inboxcount(), ast_cli_args::line, ast_vm_user::mailbox, ast_cli_args::n, ast_cli_args::pos, show_users_realtime(), ast_cli_entry::usage, ast_cli_args::word, and ast_vm_user::zonetag.
11176 { 11177 struct ast_vm_user *vmu; 11178 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11179 const char *context = NULL; 11180 int users_counter = 0; 11181 11182 switch (cmd) { 11183 case CLI_INIT: 11184 e->command = "voicemail show users"; 11185 e->usage = 11186 "Usage: voicemail show users [for <context>]\n" 11187 " Lists all mailboxes currently set up\n"; 11188 return NULL; 11189 case CLI_GENERATE: 11190 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11191 } 11192 11193 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11194 return CLI_SHOWUSAGE; 11195 if (a->argc == 5) { 11196 if (strcmp(a->argv[3],"for")) 11197 return CLI_SHOWUSAGE; 11198 context = a->argv[4]; 11199 } 11200 11201 if (ast_check_realtime("voicemail")) { 11202 if (!context) { 11203 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11204 return CLI_SHOWUSAGE; 11205 } 11206 return show_users_realtime(a->fd, context); 11207 } 11208 11209 AST_LIST_LOCK(&users); 11210 if (AST_LIST_EMPTY(&users)) { 11211 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11212 AST_LIST_UNLOCK(&users); 11213 return CLI_FAILURE; 11214 } 11215 if (!context) { 11216 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11217 } else { 11218 int count = 0; 11219 AST_LIST_TRAVERSE(&users, vmu, list) { 11220 if (!strcmp(context, vmu->context)) { 11221 count++; 11222 break; 11223 } 11224 } 11225 if (count) { 11226 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11227 } else { 11228 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11229 AST_LIST_UNLOCK(&users); 11230 return CLI_FAILURE; 11231 } 11232 } 11233 AST_LIST_TRAVERSE(&users, vmu, list) { 11234 int newmsgs = 0, oldmsgs = 0; 11235 char count[12], tmp[256] = ""; 11236 11237 if (!context || !strcmp(context, vmu->context)) { 11238 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11239 inboxcount(tmp, &newmsgs, &oldmsgs); 11240 snprintf(count, sizeof(count), "%d", newmsgs); 11241 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11242 users_counter++; 11243 } 11244 } 11245 AST_LIST_UNLOCK(&users); 11246 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11247 return CLI_SUCCESS; 11248 }
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 11251 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVSZ_OUTPUT_FORMAT, and ast_cli_entry::usage.
11252 { 11253 struct vm_zone *zone; 11254 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11255 char *res = CLI_SUCCESS; 11256 11257 switch (cmd) { 11258 case CLI_INIT: 11259 e->command = "voicemail show zones"; 11260 e->usage = 11261 "Usage: voicemail show zones\n" 11262 " Lists zone message formats\n"; 11263 return NULL; 11264 case CLI_GENERATE: 11265 return NULL; 11266 } 11267 11268 if (a->argc != 3) 11269 return CLI_SHOWUSAGE; 11270 11271 AST_LIST_LOCK(&zones); 11272 if (!AST_LIST_EMPTY(&zones)) { 11273 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11274 AST_LIST_TRAVERSE(&zones, zone, list) { 11275 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11276 } 11277 } else { 11278 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11279 res = CLI_FAILURE; 11280 } 11281 AST_LIST_UNLOCK(&zones); 11282 11283 return res; 11284 }
static int has_voicemail | ( | const char * | mailbox, | |
const char * | folder | |||
) | [static] |
Determines if the given folder has messages.
mailbox | The @ delimited string for user. If no context is found, uses 'default' for the context. | |
folder | the folder to look in |
This function is used when the mailbox is stored in a filesystem back end. This invokes the __has_voicemail(). Here we are interested in the presence of messages (> 0) only, not the actual count.
Definition at line 5434 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by load_module(), and vm_execmain().
05435 { 05436 char tmp[256], *tmp2 = tmp, *box, *context; 05437 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05438 if (ast_strlen_zero(folder)) { 05439 folder = "INBOX"; 05440 } 05441 while ((box = strsep(&tmp2, ",&"))) { 05442 if ((context = strchr(box, '@'))) 05443 *context++ = '\0'; 05444 else 05445 context = "default"; 05446 if (__has_voicemail(context, box, folder, 1)) 05447 return 1; 05448 /* If we are checking INBOX, we should check Urgent as well */ 05449 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05450 return 1; 05451 } 05452 } 05453 return 0; 05454 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5516 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05517 { 05518 int urgentmsgs = 0; 05519 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05520 if (newmsgs) { 05521 *newmsgs += urgentmsgs; 05522 } 05523 return res; 05524 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5457 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by append_mailbox(), inboxcount(), load_module(), poll_subscribed_mailbox(), run_externnotify(), and vm_users_data_provider_get_helper().
05458 { 05459 char tmp[256]; 05460 char *context; 05461 05462 /* If no mailbox, return immediately */ 05463 if (ast_strlen_zero(mailbox)) 05464 return 0; 05465 05466 if (newmsgs) 05467 *newmsgs = 0; 05468 if (oldmsgs) 05469 *oldmsgs = 0; 05470 if (urgentmsgs) 05471 *urgentmsgs = 0; 05472 05473 if (strchr(mailbox, ',')) { 05474 int tmpnew, tmpold, tmpurgent; 05475 char *mb, *cur; 05476 05477 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05478 mb = tmp; 05479 while ((cur = strsep(&mb, ", "))) { 05480 if (!ast_strlen_zero(cur)) { 05481 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05482 return -1; 05483 else { 05484 if (newmsgs) 05485 *newmsgs += tmpnew; 05486 if (oldmsgs) 05487 *oldmsgs += tmpold; 05488 if (urgentmsgs) 05489 *urgentmsgs += tmpurgent; 05490 } 05491 } 05492 } 05493 return 0; 05494 } 05495 05496 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05497 05498 if ((context = strchr(tmp, '@'))) 05499 *context++ = '\0'; 05500 else 05501 context = "default"; 05502 05503 if (newmsgs) 05504 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05505 if (oldmsgs) 05506 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05507 if (urgentmsgs) 05508 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05509 05510 return 0; 05511 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4216 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().
04217 { 04218 int l; 04219 04220 if (bio->ateof) 04221 return 0; 04222 04223 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04224 if (ferror(fi)) 04225 return -1; 04226 04227 bio->ateof = 1; 04228 return 0; 04229 } 04230 04231 bio->iolen = l; 04232 bio->iocp = 0; 04233 04234 return 1; 04235 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4240 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
static int inprocess_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 934 of file app_voicemail.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
Referenced by load_module().
static int inprocess_count | ( | const char * | context, | |
const char * | mailbox, | |||
int | delta | |||
) | [static] |
Definition at line 943 of file app_voicemail.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_alloca, ast_atomic_fetchadd_int(), ast_log(), inprocess::context, inprocess::count, inprocess_container, LOG_WARNING, and inprocess::mailbox.
Referenced by copy_message(), forward_message(), and leave_voicemail().
00944 { 00945 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00946 arg->context = arg->mailbox + strlen(mailbox) + 1; 00947 strcpy(arg->mailbox, mailbox); /* SAFE */ 00948 strcpy(arg->context, context); /* SAFE */ 00949 ao2_lock(inprocess_container); 00950 if ((i = ao2_find(inprocess_container, arg, 0))) { 00951 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00952 ao2_unlock(inprocess_container); 00953 ao2_ref(i, -1); 00954 return ret; 00955 } 00956 if (delta < 0) { 00957 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00958 } 00959 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00960 ao2_unlock(inprocess_container); 00961 return 0; 00962 } 00963 i->context = i->mailbox + strlen(mailbox) + 1; 00964 strcpy(i->mailbox, mailbox); /* SAFE */ 00965 strcpy(i->context, context); /* SAFE */ 00966 i->count = delta; 00967 ao2_link(inprocess_container, i); 00968 ao2_unlock(inprocess_container); 00969 ao2_ref(i, -1); 00970 return 0; 00971 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 928 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 5056 of file app_voicemail.c.
References ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
Referenced by leave_voicemail().
05057 { 05058 int res; 05059 char fn[PATH_MAX]; 05060 char dest[PATH_MAX]; 05061 05062 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05063 05064 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05065 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05066 return -1; 05067 } 05068 05069 RETRIEVE(fn, -1, ext, context); 05070 if (ast_fileexists(fn, NULL, NULL) > 0) { 05071 res = ast_stream_and_wait(chan, fn, ecodes); 05072 if (res) { 05073 DISPOSE(fn, -1); 05074 return res; 05075 } 05076 } else { 05077 /* Dispose just in case */ 05078 DISPOSE(fn, -1); 05079 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05080 if (res) 05081 return res; 05082 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05083 if (res) 05084 return res; 05085 } 05086 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05087 return res; 05088 }
static int is_valid_dtmf | ( | const char * | key | ) | [static] |
Determines if a DTMF key entered is valid.
key | The character to be compared. expects a single character. Though is capable of handling a string, this is internally copies using ast_strdupa. |
Tests the character entered against the set of valid DTMF characters.
Definition at line 1370 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01371 { 01372 int i; 01373 char *local_key = ast_strdupa(key); 01374 01375 for (i = 0; i < strlen(key); ++i) { 01376 if (!strchr(VALID_DTMF, *local_key)) { 01377 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01378 return 0; 01379 } 01380 local_key++; 01381 } 01382 return 1; 01383 }
static int last_message_index | ( | struct ast_vm_user * | vmu, | |
char * | dir | |||
) | [static] |
Determines the highest message number in use for a given user and mailbox folder.
vmu | ||
dir | the folder the mailbox folder to look for messages. Used to construct the SQL where clause. |
This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). Typical use to set the msgnum would be to take the value returned from this method and add one to it.
Definition at line 4035 of file app_voicemail.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by close_mailbox(), copy_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
04036 { 04037 int x; 04038 unsigned char map[MAXMSGLIMIT] = ""; 04039 DIR *msgdir; 04040 struct dirent *msgdirent; 04041 int msgdirint; 04042 char extension[4]; 04043 int stopcount = 0; 04044 04045 /* Reading the entire directory into a file map scales better than 04046 * doing a stat repeatedly on a predicted sequence. I suspect this 04047 * is partially due to stat(2) internally doing a readdir(2) itself to 04048 * find each file. */ 04049 if (!(msgdir = opendir(dir))) { 04050 return -1; 04051 } 04052 04053 while ((msgdirent = readdir(msgdir))) { 04054 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04055 map[msgdirint] = 1; 04056 stopcount++; 04057 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04058 } 04059 } 04060 closedir(msgdir); 04061 04062 for (x = 0; x < vmu->maxmsg; x++) { 04063 if (map[x] == 1) { 04064 stopcount--; 04065 } else if (map[x] == 0 && !stopcount) { 04066 break; 04067 } 04068 } 04069 04070 return x - 1; 04071 }
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 5589 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, ast_vm_user::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, ast_vm_user::exit, leave_vm_options::exitcontext, exten, ast_channel::exten, find_user(), free_user(), ast_party_redirecting::from, get_date(), ast_party_caller::id, inboxcount(), inprocess_count(), INTRO, invent_message(), last_message_index(), LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, my_umask, ast_party_id::name, vm_state::newmessages, notify_new_message(), ast_party_id::number, OPERATOR_EXIT, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, option_debug, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, ast_channel::redirecting, RENAME, RETRIEVE, S_COR, S_OR, SENTINEL, STORE, ast_party_name::str, ast_party_number::str, transfer, ast_party_name::valid, ast_party_number::valid, vm_lock_path(), VM_OPERATOR, VM_SPOOL_DIR, vmfmts, VOICEMAIL_DIR_MODE, and VOICEMAIL_FILE_MODE.
Referenced by advanced_options(), forward_message(), and vm_exec().
05590 { 05591 #ifdef IMAP_STORAGE 05592 int newmsgs, oldmsgs; 05593 #else 05594 char urgdir[PATH_MAX]; 05595 #endif 05596 char txtfile[PATH_MAX]; 05597 char tmptxtfile[PATH_MAX]; 05598 struct vm_state *vms = NULL; 05599 char callerid[256]; 05600 FILE *txt; 05601 char date[256]; 05602 int txtdes; 05603 int res = 0; 05604 int msgnum; 05605 int duration = 0; 05606 int sound_duration = 0; 05607 int ausemacro = 0; 05608 int ousemacro = 0; 05609 int ouseexten = 0; 05610 char tmpdur[16]; 05611 char priority[16]; 05612 char origtime[16]; 05613 char dir[PATH_MAX]; 05614 char tmpdir[PATH_MAX]; 05615 char fn[PATH_MAX]; 05616 char prefile[PATH_MAX] = ""; 05617 char tempfile[PATH_MAX] = ""; 05618 char ext_context[256] = ""; 05619 char fmt[80]; 05620 char *context; 05621 char ecodes[17] = "#"; 05622 struct ast_str *tmp = ast_str_create(16); 05623 char *tmpptr; 05624 struct ast_vm_user *vmu; 05625 struct ast_vm_user svm; 05626 const char *category = NULL; 05627 const char *code; 05628 const char *alldtmf = "0123456789ABCD*#"; 05629 char flag[80]; 05630 05631 if (!tmp) { 05632 return -1; 05633 } 05634 05635 ast_str_set(&tmp, 0, "%s", ext); 05636 ext = ast_str_buffer(tmp); 05637 if ((context = strchr(ext, '@'))) { 05638 *context++ = '\0'; 05639 tmpptr = strchr(context, '&'); 05640 } else { 05641 tmpptr = strchr(ext, '&'); 05642 } 05643 05644 if (tmpptr) 05645 *tmpptr++ = '\0'; 05646 05647 ast_channel_lock(chan); 05648 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05649 category = ast_strdupa(category); 05650 } 05651 ast_channel_unlock(chan); 05652 05653 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05654 ast_copy_string(flag, "Urgent", sizeof(flag)); 05655 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05656 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05657 } else { 05658 flag[0] = '\0'; 05659 } 05660 05661 ast_debug(3, "Before find_user\n"); 05662 if (!(vmu = find_user(&svm, context, ext))) { 05663 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05664 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05665 ast_free(tmp); 05666 return res; 05667 } 05668 /* Setup pre-file if appropriate */ 05669 if (strcmp(vmu->context, "default")) 05670 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05671 else 05672 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05673 05674 /* Set the path to the prefile. Will be one of 05675 VM_SPOOL_DIRcontext/ext/busy 05676 VM_SPOOL_DIRcontext/ext/unavail 05677 Depending on the flag set in options. 05678 */ 05679 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05680 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05681 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05682 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05683 } 05684 /* Set the path to the tmpfile as 05685 VM_SPOOL_DIR/context/ext/temp 05686 and attempt to create the folder structure. 05687 */ 05688 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05689 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05690 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05691 ast_free(tmp); 05692 return -1; 05693 } 05694 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05695 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05696 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05697 05698 DISPOSE(tempfile, -1); 05699 /* It's easier just to try to make it than to check for its existence */ 05700 #ifndef IMAP_STORAGE 05701 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05702 #else 05703 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05704 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05705 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05706 } 05707 #endif 05708 05709 /* Check current or macro-calling context for special extensions */ 05710 if (ast_test_flag(vmu, VM_OPERATOR)) { 05711 if (!ast_strlen_zero(vmu->exit)) { 05712 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05713 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05714 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05715 ouseexten = 1; 05716 } 05717 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05718 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05719 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05720 ouseexten = 1; 05721 } else if (!ast_strlen_zero(chan->macrocontext) 05722 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05723 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05724 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05725 ousemacro = 1; 05726 } 05727 } 05728 05729 if (!ast_strlen_zero(vmu->exit)) { 05730 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05731 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05732 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05733 } 05734 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05735 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05736 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05737 } else if (!ast_strlen_zero(chan->macrocontext) 05738 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05739 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05740 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05741 ausemacro = 1; 05742 } 05743 05744 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05745 for (code = alldtmf; *code; code++) { 05746 char e[2] = ""; 05747 e[0] = *code; 05748 if (strchr(ecodes, e[0]) == NULL 05749 && ast_canmatch_extension(chan, 05750 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05751 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05752 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05753 } 05754 } 05755 } 05756 05757 /* Play the beginning intro if desired */ 05758 if (!ast_strlen_zero(prefile)) { 05759 #ifdef ODBC_STORAGE 05760 int success = 05761 #endif 05762 RETRIEVE(prefile, -1, ext, context); 05763 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05764 if (ast_streamfile(chan, prefile, chan->language) > -1) 05765 res = ast_waitstream(chan, ecodes); 05766 #ifdef ODBC_STORAGE 05767 if (success == -1) { 05768 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05769 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05770 store_file(prefile, vmu->mailbox, vmu->context, -1); 05771 } 05772 #endif 05773 } else { 05774 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05775 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05776 } 05777 DISPOSE(prefile, -1); 05778 if (res < 0) { 05779 ast_debug(1, "Hang up during prefile playback\n"); 05780 free_user(vmu); 05781 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05782 ast_free(tmp); 05783 return -1; 05784 } 05785 } 05786 if (res == '#') { 05787 /* On a '#' we skip the instructions */ 05788 ast_set_flag(options, OPT_SILENT); 05789 res = 0; 05790 } 05791 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05792 if (vmu->maxmsg == 0) { 05793 if (option_debug > 2) 05794 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05795 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05796 goto leave_vm_out; 05797 } 05798 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05799 res = ast_stream_and_wait(chan, INTRO, ecodes); 05800 if (res == '#') { 05801 ast_set_flag(options, OPT_SILENT); 05802 res = 0; 05803 } 05804 } 05805 if (res > 0) 05806 ast_stopstream(chan); 05807 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05808 other than the operator -- an automated attendant or mailbox login for example */ 05809 if (res == '*') { 05810 chan->exten[0] = 'a'; 05811 chan->exten[1] = '\0'; 05812 if (!ast_strlen_zero(vmu->exit)) { 05813 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05814 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05815 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05816 } 05817 chan->priority = 0; 05818 free_user(vmu); 05819 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05820 ast_free(tmp); 05821 return 0; 05822 } 05823 05824 /* Check for a '0' here */ 05825 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05826 transfer: 05827 if (ouseexten || ousemacro) { 05828 chan->exten[0] = 'o'; 05829 chan->exten[1] = '\0'; 05830 if (!ast_strlen_zero(vmu->exit)) { 05831 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05832 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05833 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05834 } 05835 ast_play_and_wait(chan, "transfer"); 05836 chan->priority = 0; 05837 free_user(vmu); 05838 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05839 } 05840 ast_free(tmp); 05841 return OPERATOR_EXIT; 05842 } 05843 05844 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05845 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05846 if (!ast_strlen_zero(options->exitcontext)) { 05847 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05848 } 05849 free_user(vmu); 05850 ast_free(tmp); 05851 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05852 return res; 05853 } 05854 05855 if (res < 0) { 05856 free_user(vmu); 05857 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05858 ast_free(tmp); 05859 return -1; 05860 } 05861 /* The meat of recording the message... All the announcements and beeps have been played*/ 05862 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05863 if (!ast_strlen_zero(fmt)) { 05864 msgnum = 0; 05865 05866 #ifdef IMAP_STORAGE 05867 /* Is ext a mailbox? */ 05868 /* must open stream for this user to get info! */ 05869 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05870 if (res < 0) { 05871 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05872 ast_free(tmp); 05873 return -1; 05874 } 05875 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05876 /* It is possible under certain circumstances that inboxcount did not 05877 * create a vm_state when it was needed. This is a catchall which will 05878 * rarely be used. 05879 */ 05880 if (!(vms = create_vm_state_from_user(vmu))) { 05881 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05882 ast_free(tmp); 05883 return -1; 05884 } 05885 } 05886 vms->newmessages++; 05887 05888 /* here is a big difference! We add one to it later */ 05889 msgnum = newmsgs + oldmsgs; 05890 ast_debug(3, "Messagecount set to %d\n", msgnum); 05891 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05892 /* set variable for compatibility */ 05893 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05894 05895 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05896 goto leave_vm_out; 05897 } 05898 #else 05899 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05900 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05901 if (!res) 05902 res = ast_waitstream(chan, ""); 05903 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05904 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05905 inprocess_count(vmu->mailbox, vmu->context, -1); 05906 goto leave_vm_out; 05907 } 05908 05909 #endif 05910 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05911 txtdes = mkstemp(tmptxtfile); 05912 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05913 if (txtdes < 0) { 05914 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05915 if (!res) 05916 res = ast_waitstream(chan, ""); 05917 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05918 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05919 inprocess_count(vmu->mailbox, vmu->context, -1); 05920 goto leave_vm_out; 05921 } 05922 05923 /* Now play the beep once we have the message number for our next message. */ 05924 if (res >= 0) { 05925 /* Unless we're *really* silent, try to send the beep */ 05926 res = ast_stream_and_wait(chan, "beep", ""); 05927 } 05928 05929 /* Store information in real-time storage */ 05930 if (ast_check_realtime("voicemail_data")) { 05931 snprintf(priority, sizeof(priority), "%d", chan->priority); 05932 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05933 get_date(date, sizeof(date)); 05934 ast_callerid_merge(callerid, sizeof(callerid), 05935 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05936 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05937 "Unknown"); 05938 ast_store_realtime("voicemail_data", 05939 "origmailbox", ext, 05940 "context", chan->context, 05941 "macrocontext", chan->macrocontext, 05942 "exten", chan->exten, 05943 "priority", priority, 05944 "callerchan", chan->name, 05945 "callerid", callerid, 05946 "origdate", date, 05947 "origtime", origtime, 05948 "category", S_OR(category, ""), 05949 "filename", tmptxtfile, 05950 SENTINEL); 05951 } 05952 05953 /* Store information */ 05954 txt = fdopen(txtdes, "w+"); 05955 if (txt) { 05956 get_date(date, sizeof(date)); 05957 ast_callerid_merge(callerid, sizeof(callerid), 05958 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05959 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05960 "Unknown"); 05961 fprintf(txt, 05962 ";\n" 05963 "; Message Information file\n" 05964 ";\n" 05965 "[message]\n" 05966 "origmailbox=%s\n" 05967 "context=%s\n" 05968 "macrocontext=%s\n" 05969 "exten=%s\n" 05970 "rdnis=%s\n" 05971 "priority=%d\n" 05972 "callerchan=%s\n" 05973 "callerid=%s\n" 05974 "origdate=%s\n" 05975 "origtime=%ld\n" 05976 "category=%s\n", 05977 ext, 05978 chan->context, 05979 chan->macrocontext, 05980 chan->exten, 05981 S_COR(chan->redirecting.from.number.valid, 05982 chan->redirecting.from.number.str, "unknown"), 05983 chan->priority, 05984 chan->name, 05985 callerid, 05986 date, (long) time(NULL), 05987 category ? category : ""); 05988 } else { 05989 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05990 inprocess_count(vmu->mailbox, vmu->context, -1); 05991 if (ast_check_realtime("voicemail_data")) { 05992 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05993 } 05994 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05995 goto leave_vm_out; 05996 } 05997 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05998 05999 if (txt) { 06000 fprintf(txt, "flag=%s\n", flag); 06001 if (sound_duration < vmu->minsecs) { 06002 fclose(txt); 06003 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06004 ast_filedelete(tmptxtfile, NULL); 06005 unlink(tmptxtfile); 06006 if (ast_check_realtime("voicemail_data")) { 06007 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06008 } 06009 inprocess_count(vmu->mailbox, vmu->context, -1); 06010 } else { 06011 fprintf(txt, "duration=%d\n", duration); 06012 fclose(txt); 06013 if (vm_lock_path(dir)) { 06014 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06015 /* Delete files */ 06016 ast_filedelete(tmptxtfile, NULL); 06017 unlink(tmptxtfile); 06018 inprocess_count(vmu->mailbox, vmu->context, -1); 06019 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06020 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06021 unlink(tmptxtfile); 06022 ast_unlock_path(dir); 06023 inprocess_count(vmu->mailbox, vmu->context, -1); 06024 if (ast_check_realtime("voicemail_data")) { 06025 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06026 } 06027 } else { 06028 #ifndef IMAP_STORAGE 06029 msgnum = last_message_index(vmu, dir) + 1; 06030 #endif 06031 make_file(fn, sizeof(fn), dir, msgnum); 06032 06033 /* assign a variable with the name of the voicemail file */ 06034 #ifndef IMAP_STORAGE 06035 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06036 #else 06037 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06038 #endif 06039 06040 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06041 ast_filerename(tmptxtfile, fn, NULL); 06042 rename(tmptxtfile, txtfile); 06043 inprocess_count(vmu->mailbox, vmu->context, -1); 06044 06045 /* Properly set permissions on voicemail text descriptor file. 06046 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06047 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06048 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06049 06050 ast_unlock_path(dir); 06051 if (ast_check_realtime("voicemail_data")) { 06052 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06053 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06054 } 06055 /* We must store the file first, before copying the message, because 06056 * ODBC storage does the entire copy with SQL. 06057 */ 06058 if (ast_fileexists(fn, NULL, NULL) > 0) { 06059 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06060 } 06061 06062 /* Are there to be more recipients of this message? */ 06063 while (tmpptr) { 06064 struct ast_vm_user recipu, *recip; 06065 char *exten, *cntx; 06066 06067 exten = strsep(&tmpptr, "&"); 06068 cntx = strchr(exten, '@'); 06069 if (cntx) { 06070 *cntx = '\0'; 06071 cntx++; 06072 } 06073 if ((recip = find_user(&recipu, cntx, exten))) { 06074 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06075 free_user(recip); 06076 } 06077 } 06078 #ifndef IMAP_STORAGE 06079 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06080 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06081 char sfn[PATH_MAX]; 06082 char dfn[PATH_MAX]; 06083 int x; 06084 /* It's easier just to try to make it than to check for its existence */ 06085 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06086 x = last_message_index(vmu, urgdir) + 1; 06087 make_file(sfn, sizeof(sfn), dir, msgnum); 06088 make_file(dfn, sizeof(dfn), urgdir, x); 06089 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06090 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06091 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06092 ast_copy_string(fn, dfn, sizeof(fn)); 06093 msgnum = x; 06094 } 06095 #endif 06096 /* Notification needs to happen after the copy, though. */ 06097 if (ast_fileexists(fn, NULL, NULL)) { 06098 #ifdef IMAP_STORAGE 06099 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06100 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06101 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06102 flag); 06103 #else 06104 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06105 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06106 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06107 flag); 06108 #endif 06109 } 06110 06111 /* Disposal needs to happen after the optional move and copy */ 06112 if (ast_fileexists(fn, NULL, NULL)) { 06113 DISPOSE(dir, msgnum); 06114 } 06115 } 06116 } 06117 } else { 06118 inprocess_count(vmu->mailbox, vmu->context, -1); 06119 } 06120 if (res == '0') { 06121 goto transfer; 06122 } else if (res > 0 && res != 't') 06123 res = 0; 06124 06125 if (sound_duration < vmu->minsecs) 06126 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06127 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06128 else 06129 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06130 } else 06131 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06132 leave_vm_out: 06133 free_user(vmu); 06134 06135 #ifdef IMAP_STORAGE 06136 /* expunge message - use UID Expunge if supported on IMAP server*/ 06137 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06138 if (expungeonhangup == 1) { 06139 ast_mutex_lock(&vms->lock); 06140 #ifdef HAVE_IMAP_TK2006 06141 if (LEVELUIDPLUS (vms->mailstream)) { 06142 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06143 } else 06144 #endif 06145 mail_expunge(vms->mailstream); 06146 ast_mutex_unlock(&vms->lock); 06147 } 06148 #endif 06149 06150 ast_free(tmp); 06151 return res; 06152 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11830 of file app_voicemail.c.
References actual_load_config(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_unload_realtime(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
Referenced by handle_voicemail_reload(), load_module(), and reload().
11831 { 11832 struct ast_config *cfg, *ucfg; 11833 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11834 int res; 11835 11836 ast_unload_realtime("voicemail"); 11837 ast_unload_realtime("voicemail_data"); 11838 11839 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11840 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11841 return 0; 11842 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11843 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11844 ucfg = NULL; 11845 } 11846 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11847 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11848 ast_config_destroy(ucfg); 11849 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11850 return 0; 11851 } 11852 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11853 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11854 return 0; 11855 } else { 11856 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11857 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11858 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11859 ucfg = NULL; 11860 } 11861 } 11862 11863 res = actual_load_config(reload, cfg, ucfg); 11864 11865 ast_config_destroy(cfg); 11866 ast_config_destroy(ucfg); 11867 11868 return res; 11869 }
static int load_module | ( | void | ) | [static] |
Definition at line 13130 of file app_voicemail.c.
References ao2_container_alloc, app, app2, app3, app4, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), AST_LOG_WARNING, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_container, inprocess_hash_fn(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, my_umask, RQ_CHAR, RQ_UINTEGER3, sayname(), sayname_app, SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), VM_SPOOL_DIR, vmauthenticate(), and vmsayname_exec().
13131 { 13132 int res; 13133 my_umask = umask(0); 13134 umask(my_umask); 13135 13136 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13137 return AST_MODULE_LOAD_DECLINE; 13138 } 13139 13140 /* compute the location of the voicemail spool directory */ 13141 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13142 13143 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13144 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13145 } 13146 13147 if ((res = load_config(0))) 13148 return res; 13149 13150 res = ast_register_application_xml(app, vm_exec); 13151 res |= ast_register_application_xml(app2, vm_execmain); 13152 res |= ast_register_application_xml(app3, vm_box_exists); 13153 res |= ast_register_application_xml(app4, vmauthenticate); 13154 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13155 res |= ast_custom_function_register(&mailbox_exists_acf); 13156 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13157 #ifdef TEST_FRAMEWORK 13158 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13159 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13160 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13161 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13162 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13163 #endif 13164 13165 if (res) 13166 return res; 13167 13168 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13169 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13170 13171 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13172 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13173 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13174 13175 return res; 13176 }
static int make_dir | ( | char * | dest, | |
int | len, | |||
const char * | context, | |||
const char * | ext, | |||
const char * | folder | |||
) | [static] |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
context | ||
ext | ||
folder |
The path is constructed as VM_SPOOL_DIRcontext/ext/folder
Definition at line 1638 of file app_voicemail.c.
References VM_SPOOL_DIR.
Referenced by copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01639 { 01640 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01641 }
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 4533 of file app_voicemail.c.
References add_email_attachment(), ast_channel_unref, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc, ast_free, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04534 { 04535 char date[256]; 04536 char host[MAXHOSTNAMELEN] = ""; 04537 char who[256]; 04538 char bound[256]; 04539 char dur[256]; 04540 struct ast_tm tm; 04541 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04542 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04543 char *greeting_attachment; 04544 char filename[256]; 04545 04546 if (!str1 || !str2) { 04547 ast_free(str1); 04548 ast_free(str2); 04549 return; 04550 } 04551 04552 if (cidnum) { 04553 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04554 } 04555 if (cidname) { 04556 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04557 } 04558 gethostname(host, sizeof(host) - 1); 04559 04560 if (strchr(srcemail, '@')) { 04561 ast_copy_string(who, srcemail, sizeof(who)); 04562 } else { 04563 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04564 } 04565 04566 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04567 if (greeting_attachment) { 04568 *greeting_attachment++ = '\0'; 04569 } 04570 04571 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04572 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04573 fprintf(p, "Date: %s" ENDL, date); 04574 04575 /* Set date format for voicemail mail */ 04576 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04577 04578 if (!ast_strlen_zero(fromstring)) { 04579 struct ast_channel *ast; 04580 if ((ast = ast_dummy_channel_alloc())) { 04581 char *ptr; 04582 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04583 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04584 04585 if (check_mime(ast_str_buffer(str1))) { 04586 int first_line = 1; 04587 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04588 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04589 *ptr = '\0'; 04590 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04591 first_line = 0; 04592 /* Substring is smaller, so this will never grow */ 04593 ast_str_set(&str2, 0, "%s", ptr + 1); 04594 } 04595 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04596 } else { 04597 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04598 } 04599 ast = ast_channel_unref(ast); 04600 } else { 04601 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04602 } 04603 } else { 04604 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04605 } 04606 04607 if (check_mime(vmu->fullname)) { 04608 int first_line = 1; 04609 char *ptr; 04610 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04611 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04612 *ptr = '\0'; 04613 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04614 first_line = 0; 04615 /* Substring is smaller, so this will never grow */ 04616 ast_str_set(&str2, 0, "%s", ptr + 1); 04617 } 04618 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04619 } else { 04620 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04621 } 04622 04623 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04624 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04625 struct ast_channel *ast; 04626 if ((ast = ast_dummy_channel_alloc())) { 04627 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04628 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04629 if (check_mime(ast_str_buffer(str1))) { 04630 int first_line = 1; 04631 char *ptr; 04632 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04633 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04634 *ptr = '\0'; 04635 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04636 first_line = 0; 04637 /* Substring is smaller, so this will never grow */ 04638 ast_str_set(&str2, 0, "%s", ptr + 1); 04639 } 04640 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04641 } else { 04642 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04643 } 04644 ast = ast_channel_unref(ast); 04645 } else { 04646 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04647 } 04648 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04649 if (ast_strlen_zero(flag)) { 04650 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04651 } else { 04652 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04653 } 04654 } else { 04655 if (ast_strlen_zero(flag)) { 04656 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04657 } else { 04658 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04659 } 04660 } 04661 04662 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04663 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04664 if (imap) { 04665 /* additional information needed for IMAP searching */ 04666 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04667 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04668 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04669 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04670 #ifdef IMAP_STORAGE 04671 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04672 #else 04673 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04674 #endif 04675 /* flag added for Urgent */ 04676 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04677 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04678 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04679 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04680 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04681 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04682 if (!ast_strlen_zero(category)) { 04683 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04684 } else { 04685 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04686 } 04687 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04688 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04689 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04690 } 04691 if (!ast_strlen_zero(cidnum)) { 04692 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04693 } 04694 if (!ast_strlen_zero(cidname)) { 04695 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04696 } 04697 fprintf(p, "MIME-Version: 1.0" ENDL); 04698 if (attach_user_voicemail) { 04699 /* Something unique. */ 04700 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04701 (int) getpid(), (unsigned int) ast_random()); 04702 04703 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04704 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04705 fprintf(p, "--%s" ENDL, bound); 04706 } 04707 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04708 if (emailbody || vmu->emailbody) { 04709 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04710 struct ast_channel *ast; 04711 if ((ast = ast_dummy_channel_alloc())) { 04712 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04713 ast_str_substitute_variables(&str1, 0, ast, e_body); 04714 #ifdef IMAP_STORAGE 04715 { 04716 /* Convert body to native line terminators for IMAP backend */ 04717 char *line = ast_str_buffer(str1), *next; 04718 do { 04719 /* Terminate line before outputting it to the file */ 04720 if ((next = strchr(line, '\n'))) { 04721 *next++ = '\0'; 04722 } 04723 fprintf(p, "%s" ENDL, line); 04724 line = next; 04725 } while (!ast_strlen_zero(line)); 04726 } 04727 #else 04728 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04729 #endif 04730 ast = ast_channel_unref(ast); 04731 } else { 04732 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04733 } 04734 } else if (msgnum > -1) { 04735 if (strcmp(vmu->mailbox, mailbox)) { 04736 /* Forwarded type */ 04737 struct ast_config *msg_cfg; 04738 const char *v; 04739 int inttime; 04740 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04741 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04742 /* Retrieve info from VM attribute file */ 04743 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04744 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04745 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04746 strcat(fromfile, ".txt"); 04747 } 04748 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04749 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04750 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04751 } 04752 04753 /* You might be tempted to do origdate, except that a) it's in the wrong 04754 * format, and b) it's missing for IMAP recordings. */ 04755 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04756 struct timeval tv = { inttime, }; 04757 struct ast_tm tm; 04758 ast_localtime(&tv, &tm, NULL); 04759 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04760 } 04761 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04762 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04763 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04764 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04765 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04766 date, origcallerid, origdate); 04767 ast_config_destroy(msg_cfg); 04768 } else { 04769 goto plain_message; 04770 } 04771 } else { 04772 plain_message: 04773 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04774 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04775 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04776 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04777 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04778 } 04779 } else { 04780 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04781 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04782 } 04783 04784 if (imap || attach_user_voicemail) { 04785 if (!ast_strlen_zero(attach2)) { 04786 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04787 ast_debug(5, "creating second attachment filename %s\n", filename); 04788 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04789 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04790 ast_debug(5, "creating attachment filename %s\n", filename); 04791 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04792 } else { 04793 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04794 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04795 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04796 } 04797 } 04798 ast_free(str1); 04799 ast_free(str2); 04800 }
static int make_file | ( | char * | dest, | |
const int | len, | |||
const char * | dir, | |||
const int | num | |||
) | [static] |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
dir | ||
num |
The path is constructed as VM_SPOOL_DIRcontext/ext/folder
Definition at line 1655 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), resequence_mailbox(), save_to_folder(), vm_execmain(), and vm_forwardoptions().
01656 { 01657 return snprintf(dest, len, "%s/msg%04d", dir, num); 01658 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11661 of file app_voicemail.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_ack(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::context, count_messages(), ast_vm_user::dialout, ast_vm_user::email, ast_vm_user::exit, ast_vm_user::fullname, inboxcount(), ast_vm_user::language, ast_vm_user::mailbox, mailcmd, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, ast_vm_user::saydurationm, serveremail, ast_vm_user::serveremail, ast_vm_user::uniqueid, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_OPERATOR, VM_REVIEW, VM_SAYCID, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by load_module().
11662 { 11663 struct ast_vm_user *vmu = NULL; 11664 const char *id = astman_get_header(m, "ActionID"); 11665 char actionid[128] = ""; 11666 11667 if (!ast_strlen_zero(id)) 11668 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11669 11670 AST_LIST_LOCK(&users); 11671 11672 if (AST_LIST_EMPTY(&users)) { 11673 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11674 AST_LIST_UNLOCK(&users); 11675 return RESULT_SUCCESS; 11676 } 11677 11678 astman_send_ack(s, m, "Voicemail user list will follow"); 11679 11680 AST_LIST_TRAVERSE(&users, vmu, list) { 11681 char dirname[256]; 11682 11683 #ifdef IMAP_STORAGE 11684 int new, old; 11685 inboxcount(vmu->mailbox, &new, &old); 11686 #endif 11687 11688 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11689 astman_append(s, 11690 "%s" 11691 "Event: VoicemailUserEntry\r\n" 11692 "VMContext: %s\r\n" 11693 "VoiceMailbox: %s\r\n" 11694 "Fullname: %s\r\n" 11695 "Email: %s\r\n" 11696 "Pager: %s\r\n" 11697 "ServerEmail: %s\r\n" 11698 "MailCommand: %s\r\n" 11699 "Language: %s\r\n" 11700 "TimeZone: %s\r\n" 11701 "Callback: %s\r\n" 11702 "Dialout: %s\r\n" 11703 "UniqueID: %s\r\n" 11704 "ExitContext: %s\r\n" 11705 "SayDurationMinimum: %d\r\n" 11706 "SayEnvelope: %s\r\n" 11707 "SayCID: %s\r\n" 11708 "AttachMessage: %s\r\n" 11709 "AttachmentFormat: %s\r\n" 11710 "DeleteMessage: %s\r\n" 11711 "VolumeGain: %.2f\r\n" 11712 "CanReview: %s\r\n" 11713 "CallOperator: %s\r\n" 11714 "MaxMessageCount: %d\r\n" 11715 "MaxMessageLength: %d\r\n" 11716 "NewMessageCount: %d\r\n" 11717 #ifdef IMAP_STORAGE 11718 "OldMessageCount: %d\r\n" 11719 "IMAPUser: %s\r\n" 11720 #endif 11721 "\r\n", 11722 actionid, 11723 vmu->context, 11724 vmu->mailbox, 11725 vmu->fullname, 11726 vmu->email, 11727 vmu->pager, 11728 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11729 mailcmd, 11730 vmu->language, 11731 vmu->zonetag, 11732 vmu->callback, 11733 vmu->dialout, 11734 vmu->uniqueid, 11735 vmu->exit, 11736 vmu->saydurationm, 11737 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11738 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11739 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11740 vmu->attachfmt, 11741 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11742 vmu->volgain, 11743 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11744 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11745 vmu->maxmsg, 11746 vmu->maxsecs, 11747 #ifdef IMAP_STORAGE 11748 new, old, vmu->imapuser 11749 #else 11750 count_messages(vmu, dirname) 11751 #endif 11752 ); 11753 } 11754 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11755 11756 AST_LIST_UNLOCK(&users); 11757 11758 return RESULT_SUCCESS; 11759 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11482 of file app_voicemail.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_cond, poll_freq, poll_subscribed_mailboxes(), and poll_thread_run.
Referenced by start_poll_thread().
11483 { 11484 while (poll_thread_run) { 11485 struct timespec ts = { 0, }; 11486 struct timeval wait; 11487 11488 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11489 ts.tv_sec = wait.tv_sec; 11490 ts.tv_nsec = wait.tv_usec * 1000; 11491 11492 ast_mutex_lock(&poll_lock); 11493 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11494 ast_mutex_unlock(&poll_lock); 11495 11496 if (!poll_thread_run) 11497 break; 11498 11499 poll_subscribed_mailboxes(); 11500 } 11501 11502 return NULL; 11503 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1716 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by acf_mailbox_exists(), add_peer_mailboxes(), adsi_load_vmail(), build_gateway(), copy_message(), get_folder(), has_voicemail(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().
01717 { 01718 #ifdef IMAP_STORAGE 01719 if (vmu && id == 0) { 01720 return vmu->imapfolder; 01721 } 01722 #endif 01723 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01724 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5383 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
05384 { 05385 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05386 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11505 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
11506 { 11507 ast_free(mwi_sub); 11508 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11593 of file app_voicemail.c.
References ast_calloc, ast_event_get_ie_str(), ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_SUB, ast_free, ast_log(), ast_strdup, ast_taskprocessor_push(), mwi_sub_task::context, handle_subscribe(), LOG_ERROR, mwi_sub_task::mailbox, mwi_subscription_tps, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11594 { 11595 struct mwi_sub_task *mwist; 11596 11597 if (ast_event_get_type(event) != AST_EVENT_SUB) 11598 return; 11599 11600 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11601 return; 11602 11603 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11604 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11605 return; 11606 } 11607 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11608 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11609 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11610 11611 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11612 ast_free(mwist); 11613 } 11614 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11567 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().
11568 { 11569 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11570 11571 if (!uniqueid) { 11572 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11573 return; 11574 } 11575 11576 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11577 ast_free(uniqueid); 11578 return; 11579 } 11580 11581 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11582 ast_free(uniqueid); 11583 return; 11584 } 11585 11586 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11587 *uniqueid = u; 11588 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11589 ast_free(uniqueid); 11590 } 11591 }
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 7066 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), AST_LOG_WARNING, ast_manager_event, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, vm_state::curmsg, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, ast_vm_user::mailbox, make_dir(), make_file(), mbox(), vm_state::newmessages, ast_vm_user::pager, pbx_builtin_getvar_helper(), queue_mwi_event(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, serveremail, VM_ATTACH, vm_delete(), VM_DELETE, and VM_SPOOL_DIR.
Referenced by copy_message(), and leave_voicemail().
07067 { 07068 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07069 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07070 const char *category; 07071 char *myserveremail = serveremail; 07072 07073 ast_channel_lock(chan); 07074 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07075 category = ast_strdupa(category); 07076 } 07077 ast_channel_unlock(chan); 07078 07079 #ifndef IMAP_STORAGE 07080 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07081 #else 07082 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07083 #endif 07084 make_file(fn, sizeof(fn), todir, msgnum); 07085 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07086 07087 if (!ast_strlen_zero(vmu->attachfmt)) { 07088 if (strstr(fmt, vmu->attachfmt)) 07089 fmt = vmu->attachfmt; 07090 else 07091 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); 07092 } 07093 07094 /* Attach only the first format */ 07095 fmt = ast_strdupa(fmt); 07096 stringp = fmt; 07097 strsep(&stringp, "|"); 07098 07099 if (!ast_strlen_zero(vmu->serveremail)) 07100 myserveremail = vmu->serveremail; 07101 07102 if (!ast_strlen_zero(vmu->email)) { 07103 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07104 07105 if (attach_user_voicemail) 07106 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07107 07108 /* XXX possible imap issue, should category be NULL XXX */ 07109 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07110 07111 if (attach_user_voicemail) 07112 DISPOSE(todir, msgnum); 07113 } 07114 07115 if (!ast_strlen_zero(vmu->pager)) { 07116 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07117 } 07118 07119 if (ast_test_flag(vmu, VM_DELETE)) 07120 DELETE(todir, msgnum, fn, vmu); 07121 07122 /* Leave voicemail for someone */ 07123 if (ast_app_has_voicemail(ext_context, NULL)) 07124 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07125 07126 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07127 07128 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); 07129 run_externnotify(vmu->context, vmu->mailbox, flag); 07130 07131 #ifdef IMAP_STORAGE 07132 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07133 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07134 vm_imap_delete(NULL, vms->curmsg, vmu); 07135 vms->newmessages--; /* Fix new message count */ 07136 } 07137 #endif 07138 07139 return 0; 07140 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4253 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04254 { 04255 if (bio->linelength >= BASELINELEN) { 04256 if (fputs(ENDL, so) == EOF) { 04257 return -1; 04258 } 04259 04260 bio->linelength = 0; 04261 } 04262 04263 if (putc(((unsigned char) c), so) == EOF) { 04264 return -1; 04265 } 04266 04267 bio->linelength++; 04268 04269 return 1; 04270 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7915 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().
07916 { 07917 int count_msg, last_msg; 07918 07919 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07920 07921 /* Rename the member vmbox HERE so that we don't try to return before 07922 * we know what's going on. 07923 */ 07924 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07925 07926 /* Faster to make the directory than to check if it exists. */ 07927 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07928 07929 /* traverses directory using readdir (or select query for ODBC) */ 07930 count_msg = count_messages(vmu, vms->curdir); 07931 if (count_msg < 0) { 07932 return count_msg; 07933 } else { 07934 vms->lastmsg = count_msg - 1; 07935 } 07936 07937 if (vm_allocate_dh(vms, vmu, count_msg)) { 07938 return -1; 07939 } 07940 07941 /* 07942 The following test is needed in case sequencing gets messed up. 07943 There appears to be more than one way to mess up sequence, so 07944 we will not try to find all of the root causes--just fix it when 07945 detected. 07946 */ 07947 07948 if (vm_lock_path(vms->curdir)) { 07949 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07950 return ERROR_LOCK_PATH; 07951 } 07952 07953 /* for local storage, checks directory for messages up to maxmsg limit */ 07954 last_msg = last_message_index(vmu, vms->curdir); 07955 ast_unlock_path(vms->curdir); 07956 07957 if (last_msg < -1) { 07958 return last_msg; 07959 } else if (vms->lastmsg != last_msg) { 07960 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); 07961 resequence_mailbox(vmu, vms->curdir, count_msg); 07962 } 07963 07964 return 0; 07965 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7689 of file app_voicemail.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
Referenced by vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), vm_browse_messages_zh(), and vm_execmain().
07690 { 07691 int res = 0; 07692 char filename[256], *cid; 07693 const char *origtime, *context, *category, *duration, *flag; 07694 struct ast_config *msg_cfg; 07695 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07696 07697 vms->starting = 0; 07698 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07699 adsi_message(chan, vms); 07700 if (!vms->curmsg) { 07701 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07702 } else if (vms->curmsg == vms->lastmsg) { 07703 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07704 } 07705 07706 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07707 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07708 msg_cfg = ast_config_load(filename, config_flags); 07709 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07710 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07711 return 0; 07712 } 07713 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07714 07715 /* Play the word urgent if we are listening to urgent messages */ 07716 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07717 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07718 } 07719 07720 if (!res) { 07721 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07722 /* POLISH syntax */ 07723 if (!strncasecmp(chan->language, "pl", 2)) { 07724 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07725 int ten, one; 07726 char nextmsg[256]; 07727 ten = (vms->curmsg + 1) / 10; 07728 one = (vms->curmsg + 1) % 10; 07729 07730 if (vms->curmsg < 20) { 07731 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07732 res = wait_file2(chan, vms, nextmsg); 07733 } else { 07734 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07735 res = wait_file2(chan, vms, nextmsg); 07736 if (one > 0) { 07737 if (!res) { 07738 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07739 res = wait_file2(chan, vms, nextmsg); 07740 } 07741 } 07742 } 07743 } 07744 if (!res) 07745 res = wait_file2(chan, vms, "vm-message"); 07746 /* HEBREW syntax */ 07747 } else if (!strncasecmp(chan->language, "he", 2)) { 07748 if (!vms->curmsg) { 07749 res = wait_file2(chan, vms, "vm-message"); 07750 res = wait_file2(chan, vms, "vm-first"); 07751 } else if (vms->curmsg == vms->lastmsg) { 07752 res = wait_file2(chan, vms, "vm-message"); 07753 res = wait_file2(chan, vms, "vm-last"); 07754 } else { 07755 res = wait_file2(chan, vms, "vm-message"); 07756 res = wait_file2(chan, vms, "vm-number"); 07757 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07758 } 07759 /* VIETNAMESE syntax */ 07760 } else if (!strncasecmp(chan->language, "vi", 2)) { 07761 if (!vms->curmsg) { 07762 res = wait_file2(chan, vms, "vm-message"); 07763 res = wait_file2(chan, vms, "vm-first"); 07764 } else if (vms->curmsg == vms->lastmsg) { 07765 res = wait_file2(chan, vms, "vm-message"); 07766 res = wait_file2(chan, vms, "vm-last"); 07767 } else { 07768 res = wait_file2(chan, vms, "vm-message"); 07769 res = wait_file2(chan, vms, "vm-number"); 07770 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07771 } 07772 } else { 07773 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07774 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07775 } else { /* DEFAULT syntax */ 07776 res = wait_file2(chan, vms, "vm-message"); 07777 } 07778 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07779 if (!res) { 07780 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07781 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07782 } 07783 } 07784 } 07785 } 07786 07787 if (!msg_cfg) { 07788 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07789 return 0; 07790 } 07791 07792 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07793 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07794 DISPOSE(vms->curdir, vms->curmsg); 07795 ast_config_destroy(msg_cfg); 07796 return 0; 07797 } 07798 07799 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07800 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07801 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07802 07803 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07804 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07805 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07806 if (!res) { 07807 res = play_message_category(chan, category); 07808 } 07809 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07810 res = play_message_datetime(chan, vmu, origtime, filename); 07811 } 07812 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07813 res = play_message_callerid(chan, vms, cid, context, 0); 07814 } 07815 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07816 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07817 } 07818 /* Allow pressing '1' to skip envelope / callerid */ 07819 if (res == '1') { 07820 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07821 res = 0; 07822 } 07823 ast_config_destroy(msg_cfg); 07824 07825 if (!res) { 07826 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07827 #ifdef IMAP_STORAGE 07828 ast_mutex_lock(&vms->lock); 07829 #endif 07830 vms->heard[vms->curmsg] = 1; 07831 #ifdef IMAP_STORAGE 07832 ast_mutex_unlock(&vms->lock); 07833 /*IMAP storage stores any prepended message from a forward 07834 * as a separate file from the rest of the message 07835 */ 07836 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07837 wait_file(chan, vms, vms->introfn); 07838 } 07839 #endif 07840 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07841 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07842 res = 0; 07843 } 07844 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07845 } 07846 DISPOSE(vms->curdir, vms->curmsg); 07847 return res; 07848 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7575 of file app_voicemail.c.
References ast_callerid_parse(), ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verb, cidinternalcontexts, MAX_NUM_CID_CONTEXTS, name, VM_SPOOL_DIR, and wait_file2().
Referenced by advanced_options(), and play_message().
07576 { 07577 int res = 0; 07578 int i; 07579 char *callerid, *name; 07580 char prefile[PATH_MAX] = ""; 07581 07582 07583 /* If voicemail cid is not enabled, or we didn't get cid or context from 07584 * the attribute file, leave now. 07585 * 07586 * TODO Still need to change this so that if this function is called by the 07587 * message envelope (and someone is explicitly requesting to hear the CID), 07588 * it does not check to see if CID is enabled in the config file. 07589 */ 07590 if ((cid == NULL)||(context == NULL)) 07591 return res; 07592 07593 /* Strip off caller ID number from name */ 07594 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07595 ast_callerid_parse(cid, &name, &callerid); 07596 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07597 /* Check for internal contexts and only */ 07598 /* say extension when the call didn't come from an internal context in the list */ 07599 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07600 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07601 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07602 break; 07603 } 07604 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07605 if (!res) { 07606 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07607 if (!ast_strlen_zero(prefile)) { 07608 /* See if we can find a recorded name for this person instead of their extension number */ 07609 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07610 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07611 if (!callback) 07612 res = wait_file2(chan, vms, "vm-from"); 07613 res = ast_stream_and_wait(chan, prefile, ""); 07614 } else { 07615 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07616 /* Say "from extension" as one saying to sound smoother */ 07617 if (!callback) 07618 res = wait_file2(chan, vms, "vm-from-extension"); 07619 res = ast_say_digit_str(chan, callerid, "", chan->language); 07620 } 07621 } 07622 } 07623 } else if (!res) { 07624 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07625 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07626 if (!callback) 07627 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07628 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07629 } 07630 } else { 07631 /* Number unknown */ 07632 ast_debug(1, "VM-CID: From an unknown number\n"); 07633 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07634 res = wait_file2(chan, vms, "vm-unknown-caller"); 07635 } 07636 return res; 07637 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7486 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07487 { 07488 int res = 0; 07489 07490 if (!ast_strlen_zero(category)) 07491 res = ast_play_and_wait(chan, category); 07492 07493 if (res) { 07494 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07495 res = 0; 07496 } 07497 07498 return res; 07499 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7501 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), pbx_builtin_setvar_helper(), and ast_vm_user::zonetag.
Referenced by advanced_options(), and play_message().
07502 { 07503 int res = 0; 07504 struct vm_zone *the_zone = NULL; 07505 time_t t; 07506 07507 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07508 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07509 return 0; 07510 } 07511 07512 /* Does this user have a timezone specified? */ 07513 if (!ast_strlen_zero(vmu->zonetag)) { 07514 /* Find the zone in the list */ 07515 struct vm_zone *z; 07516 AST_LIST_LOCK(&zones); 07517 AST_LIST_TRAVERSE(&zones, z, list) { 07518 if (!strcmp(z->name, vmu->zonetag)) { 07519 the_zone = z; 07520 break; 07521 } 07522 } 07523 AST_LIST_UNLOCK(&zones); 07524 } 07525 07526 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07527 #if 0 07528 /* Set the DIFF_* variables */ 07529 ast_localtime(&t, &time_now, NULL); 07530 tv_now = ast_tvnow(); 07531 ast_localtime(&tv_now, &time_then, NULL); 07532 07533 /* Day difference */ 07534 if (time_now.tm_year == time_then.tm_year) 07535 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07536 else 07537 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07538 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07539 07540 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07541 #endif 07542 if (the_zone) { 07543 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07544 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07545 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07546 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07547 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07548 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07549 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); 07550 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07551 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07552 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07553 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07554 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07555 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07556 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07557 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); 07558 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07559 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07560 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07561 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07562 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07563 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); 07564 } else { 07565 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07566 } 07567 #if 0 07568 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07569 #endif 07570 return res; 07571 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7639 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), say_and_wait(), and wait_file2().
Referenced by play_message().
07640 { 07641 int res = 0; 07642 int durationm; 07643 int durations; 07644 /* Verify that we have a duration for the message */ 07645 if (duration == NULL) 07646 return res; 07647 07648 /* Convert from seconds to minutes */ 07649 durations = atoi(duration); 07650 durationm = (durations / 60); 07651 07652 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07653 07654 if ((!res) && (durationm >= minduration)) { 07655 res = wait_file2(chan, vms, "vm-duration"); 07656 07657 /* POLISH syntax */ 07658 if (!strncasecmp(chan->language, "pl", 2)) { 07659 div_t num = div(durationm, 10); 07660 07661 if (durationm == 1) { 07662 res = ast_play_and_wait(chan, "digits/1z"); 07663 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07664 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07665 if (num.rem == 2) { 07666 if (!num.quot) { 07667 res = ast_play_and_wait(chan, "digits/2-ie"); 07668 } else { 07669 res = say_and_wait(chan, durationm - 2 , chan->language); 07670 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07671 } 07672 } else { 07673 res = say_and_wait(chan, durationm, chan->language); 07674 } 07675 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07676 } else { 07677 res = say_and_wait(chan, durationm, chan->language); 07678 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07679 } 07680 /* DEFAULT syntax */ 07681 } else { 07682 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07683 res = wait_file2(chan, vms, "vm-minutes"); 07684 } 07685 } 07686 return res; 07687 }
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 13443 of file app_voicemail.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_LOG_WARNING, AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, maxsilence, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
Referenced by leave_voicemail(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
13446 { 13447 /* Record message & let caller review or re-record it, or set options if applicable */ 13448 int res = 0; 13449 int cmd = 0; 13450 int max_attempts = 3; 13451 int attempts = 0; 13452 int recorded = 0; 13453 int msg_exists = 0; 13454 signed char zero_gain = 0; 13455 char tempfile[PATH_MAX]; 13456 char *acceptdtmf = "#"; 13457 char *canceldtmf = ""; 13458 int canceleddtmf = 0; 13459 13460 /* Note that urgent and private are for flagging messages as such in the future */ 13461 13462 /* barf if no pointer passed to store duration in */ 13463 if (duration == NULL) { 13464 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13465 return -1; 13466 } 13467 13468 if (!outsidecaller) 13469 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13470 else 13471 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13472 13473 cmd = '3'; /* Want to start by recording */ 13474 13475 while ((cmd >= 0) && (cmd != 't')) { 13476 switch (cmd) { 13477 case '1': 13478 if (!msg_exists) { 13479 /* In this case, 1 is to record a message */ 13480 cmd = '3'; 13481 break; 13482 } else { 13483 /* Otherwise 1 is to save the existing message */ 13484 ast_verb(3, "Saving message as is\n"); 13485 if (!outsidecaller) 13486 ast_filerename(tempfile, recordfile, NULL); 13487 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13488 if (!outsidecaller) { 13489 /* Saves to IMAP server only if imapgreeting=yes */ 13490 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13491 DISPOSE(recordfile, -1); 13492 } 13493 cmd = 't'; 13494 return res; 13495 } 13496 case '2': 13497 /* Review */ 13498 ast_verb(3, "Reviewing the message\n"); 13499 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13500 break; 13501 case '3': 13502 msg_exists = 0; 13503 /* Record */ 13504 if (recorded == 1) 13505 ast_verb(3, "Re-recording the message\n"); 13506 else 13507 ast_verb(3, "Recording the message\n"); 13508 13509 if (recorded && outsidecaller) { 13510 cmd = ast_play_and_wait(chan, INTRO); 13511 cmd = ast_play_and_wait(chan, "beep"); 13512 } 13513 recorded = 1; 13514 /* 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 */ 13515 if (record_gain) 13516 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13517 if (ast_test_flag(vmu, VM_OPERATOR)) 13518 canceldtmf = "0"; 13519 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13520 if (strchr(canceldtmf, cmd)) { 13521 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13522 canceleddtmf = 1; 13523 } 13524 if (record_gain) 13525 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13526 if (cmd == -1) { 13527 /* User has hung up, no options to give */ 13528 if (!outsidecaller) { 13529 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13530 ast_filedelete(tempfile, NULL); 13531 } 13532 return cmd; 13533 } 13534 if (cmd == '0') { 13535 break; 13536 } else if (cmd == '*') { 13537 break; 13538 #if 0 13539 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13540 /* Message is too short */ 13541 ast_verb(3, "Message too short\n"); 13542 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13543 cmd = ast_filedelete(tempfile, NULL); 13544 break; 13545 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13546 /* Message is all silence */ 13547 ast_verb(3, "Nothing recorded\n"); 13548 cmd = ast_filedelete(tempfile, NULL); 13549 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13550 if (!cmd) 13551 cmd = ast_play_and_wait(chan, "vm-speakup"); 13552 break; 13553 #endif 13554 } else { 13555 /* If all is well, a message exists */ 13556 msg_exists = 1; 13557 cmd = 0; 13558 } 13559 break; 13560 case '4': 13561 if (outsidecaller) { /* only mark vm messages */ 13562 /* Mark Urgent */ 13563 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13564 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13565 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13566 strcpy(flag, "Urgent"); 13567 } else if (flag) { 13568 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13569 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13570 strcpy(flag, ""); 13571 } else { 13572 ast_play_and_wait(chan, "vm-sorry"); 13573 } 13574 cmd = 0; 13575 } else { 13576 cmd = ast_play_and_wait(chan, "vm-sorry"); 13577 } 13578 break; 13579 case '5': 13580 case '6': 13581 case '7': 13582 case '8': 13583 case '9': 13584 case '*': 13585 case '#': 13586 cmd = ast_play_and_wait(chan, "vm-sorry"); 13587 break; 13588 #if 0 13589 /* XXX Commented out for the moment because of the dangers of deleting 13590 a message while recording (can put the message numbers out of sync) */ 13591 case '*': 13592 /* Cancel recording, delete message, offer to take another message*/ 13593 cmd = ast_play_and_wait(chan, "vm-deleted"); 13594 cmd = ast_filedelete(tempfile, NULL); 13595 if (outsidecaller) { 13596 res = vm_exec(chan, NULL); 13597 return res; 13598 } 13599 else 13600 return 1; 13601 #endif 13602 case '0': 13603 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13604 cmd = ast_play_and_wait(chan, "vm-sorry"); 13605 break; 13606 } 13607 if (msg_exists || recorded) { 13608 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13609 if (!cmd) 13610 cmd = ast_waitfordigit(chan, 3000); 13611 if (cmd == '1') { 13612 ast_filerename(tempfile, recordfile, NULL); 13613 ast_play_and_wait(chan, "vm-msgsaved"); 13614 cmd = '0'; 13615 } else if (cmd == '4') { 13616 if (flag) { 13617 ast_play_and_wait(chan, "vm-marked-urgent"); 13618 strcpy(flag, "Urgent"); 13619 } 13620 ast_play_and_wait(chan, "vm-msgsaved"); 13621 cmd = '0'; 13622 } else { 13623 ast_play_and_wait(chan, "vm-deleted"); 13624 DELETE(tempfile, -1, tempfile, vmu); 13625 cmd = '0'; 13626 } 13627 } 13628 return cmd; 13629 default: 13630 /* If the caller is an ouside caller, and the review option is enabled, 13631 allow them to review the message, but let the owner of the box review 13632 their OGM's */ 13633 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13634 return cmd; 13635 if (msg_exists) { 13636 cmd = ast_play_and_wait(chan, "vm-review"); 13637 if (!cmd && outsidecaller) { 13638 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13639 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13640 } else if (flag) { 13641 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13642 } 13643 } 13644 } else { 13645 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13646 if (!cmd) 13647 cmd = ast_waitfordigit(chan, 600); 13648 } 13649 13650 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13651 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13652 if (!cmd) 13653 cmd = ast_waitfordigit(chan, 600); 13654 } 13655 #if 0 13656 if (!cmd) 13657 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13658 #endif 13659 if (!cmd) 13660 cmd = ast_waitfordigit(chan, 6000); 13661 if (!cmd) { 13662 attempts++; 13663 } 13664 if (attempts > max_attempts) { 13665 cmd = 't'; 13666 } 13667 } 13668 } 13669 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13670 /* Hang up or timeout, so delete the recording. */ 13671 ast_filedelete(tempfile, NULL); 13672 } 13673 13674 if (cmd != 't' && outsidecaller) 13675 ast_play_and_wait(chan, "vm-goodbye"); 13676 13677 return cmd; 13678 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11454 of file app_voicemail.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11455 { 11456 int new = 0, old = 0, urgent = 0; 11457 11458 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11459 11460 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11461 mwi_sub->old_urgent = urgent; 11462 mwi_sub->old_new = new; 11463 mwi_sub->old_old = old; 11464 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11465 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11466 } 11467 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11469 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
11470 { 11471 struct mwi_sub *mwi_sub; 11472 11473 AST_RWLIST_RDLOCK(&mwi_subs); 11474 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11475 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11476 poll_subscribed_mailbox(mwi_sub); 11477 } 11478 } 11479 AST_RWLIST_UNLOCK(&mwi_subs); 11480 }
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 1013 of file app_voicemail.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_free, ast_vm_user::callback, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, exitcontext, globalflags, locale, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, maxdeletedmsg, ast_vm_user::maxmsg, maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, passwordlocation, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, saydurationminfo, vmmaxsecs, vmminsecs, volgain, ast_vm_user::volgain, zonetag, and ast_vm_user::zonetag.
Referenced by actual_load_config(), append_mailbox(), AST_TEST_DEFINE(), and find_user_realtime().
01014 { 01015 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01016 vmu->passwordlocation = passwordlocation; 01017 if (saydurationminfo) { 01018 vmu->saydurationm = saydurationminfo; 01019 } 01020 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01021 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01022 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01023 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01024 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01025 if (vmminsecs) { 01026 vmu->minsecs = vmminsecs; 01027 } 01028 if (vmmaxsecs) { 01029 vmu->maxsecs = vmmaxsecs; 01030 } 01031 if (maxmsg) { 01032 vmu->maxmsg = maxmsg; 01033 } 01034 if (maxdeletedmsg) { 01035 vmu->maxdeletedmsg = maxdeletedmsg; 01036 } 01037 vmu->volgain = volgain; 01038 ast_free(vmu->emailsubject); 01039 vmu->emailsubject = NULL; 01040 ast_free(vmu->emailbody); 01041 vmu->emailbody = NULL; 01042 #ifdef IMAP_STORAGE 01043 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01044 #endif 01045 }
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 4341 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.
Referenced by make_email_file(), and sendpage().
04342 { 04343 char callerid[256]; 04344 char num[12]; 04345 char fromdir[256], fromfile[256]; 04346 struct ast_config *msg_cfg; 04347 const char *origcallerid, *origtime; 04348 char origcidname[80], origcidnum[80], origdate[80]; 04349 int inttime; 04350 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04351 04352 /* Prepare variables for substitution in email body and subject */ 04353 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04354 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04355 snprintf(num, sizeof(num), "%d", msgnum); 04356 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04357 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04358 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04359 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04360 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04361 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04362 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04363 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04364 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04365 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04366 04367 /* Retrieve info from VM attribute file */ 04368 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04369 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04370 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04371 strcat(fromfile, ".txt"); 04372 } 04373 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04374 if (option_debug > 0) { 04375 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04376 } 04377 return; 04378 } 04379 04380 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04381 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04382 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04383 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04384 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04385 } 04386 04387 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04388 struct timeval tv = { inttime, }; 04389 struct ast_tm tm; 04390 ast_localtime(&tv, &tm, NULL); 04391 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04392 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04393 } 04394 ast_config_destroy(msg_cfg); 04395 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7029 of file app_voicemail.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, and ast_strlen_zero().
Referenced by append_mailbox(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
07030 { 07031 struct ast_event *event; 07032 char *mailbox, *context; 07033 07034 /* Strip off @default */ 07035 context = mailbox = ast_strdupa(box); 07036 strsep(&context, "@"); 07037 if (ast_strlen_zero(context)) 07038 context = "default"; 07039 07040 if (!(event = ast_event_new(AST_EVENT_MWI, 07041 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07042 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07043 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07044 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07045 AST_EVENT_IE_END))) { 07046 return; 07047 } 07048 07049 ast_event_queue_and_cache(event); 07050 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12560 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().
12560 { 12561 struct ast_config *pwconf; 12562 struct ast_flags config_flags = { 0 }; 12563 12564 pwconf = ast_config_load(secretfn, config_flags); 12565 if (pwconf) { 12566 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12567 if (val) { 12568 ast_copy_string(password, val, passwordlen); 12569 ast_config_destroy(pwconf); 12570 return; 12571 } 12572 ast_config_destroy(pwconf); 12573 } 12574 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12575 }
static int reload | ( | void | ) | [static] |
Definition at line 13090 of file app_voicemail.c.
References load_config().
13091 { 13092 return load_config(1); 13093 }
static void rename_file | ( | char * | sfn, | |
char * | dfn | |||
) | [static] |
Renames a message in a mailbox folder.
sfn | The path to the mailbox information and data file to be renamed. | |
dfn | The path for where the message data and information files will be renamed to. |
This method is used by the RENAME macro when mailboxes are stored on the filesystem. (not ODBC and not IMAP).
Definition at line 4011 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04012 { 04013 char stxt[PATH_MAX]; 04014 char dtxt[PATH_MAX]; 04015 ast_filerename(sfn, dfn, NULL); 04016 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04017 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04018 if (ast_check_realtime("voicemail_data")) { 04019 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04020 } 04021 rename(stxt, dtxt); 04022 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6155 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().
06156 { 06157 /* we know the actual number of messages, so stop process when number is hit */ 06158 06159 int x, dest; 06160 char sfn[PATH_MAX]; 06161 char dfn[PATH_MAX]; 06162 06163 if (vm_lock_path(dir)) { 06164 return ERROR_LOCK_PATH; 06165 } 06166 06167 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06168 make_file(sfn, sizeof(sfn), dir, x); 06169 if (EXISTS(dir, x, sfn, NULL)) { 06170 06171 if (x != dest) { 06172 make_file(dfn, sizeof(dfn), dir, dest); 06173 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06174 } 06175 06176 dest++; 06177 } 06178 } 06179 ast_unlock_path(dir); 06180 06181 return dest; 06182 }
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 1483 of file app_voicemail.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, ast_vm_user::mailbox, and ast_vm_user::password.
Referenced by vm_change_password(), and vm_change_password_shell().
01484 { 01485 /* This function could be made to generate one from a database, too */ 01486 struct ast_vm_user *cur; 01487 int res = -1; 01488 AST_LIST_LOCK(&users); 01489 AST_LIST_TRAVERSE(&users, cur, list) { 01490 if ((!context || !strcasecmp(context, cur->context)) && 01491 (!strcasecmp(mailbox, cur->mailbox))) 01492 break; 01493 } 01494 if (cur) { 01495 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01496 res = 0; 01497 } 01498 AST_LIST_UNLOCK(&users); 01499 return res; 01500 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5526 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait_station(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, externnotify, ast_smdi_mwi_message::fwd_st, inboxcount2(), smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
05527 { 05528 char arguments[255]; 05529 char ext_context[256] = ""; 05530 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05531 struct ast_smdi_mwi_message *mwi_msg; 05532 05533 if (!ast_strlen_zero(context)) 05534 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05535 else 05536 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05537 05538 if (smdi_iface) { 05539 if (ast_app_has_voicemail(ext_context, NULL)) 05540 ast_smdi_mwi_set(smdi_iface, extension); 05541 else 05542 ast_smdi_mwi_unset(smdi_iface, extension); 05543 05544 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05545 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05546 if (!strncmp(mwi_msg->cause, "INV", 3)) 05547 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05548 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05549 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05550 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05551 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05552 } else { 05553 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05554 } 05555 } 05556 05557 if (!ast_strlen_zero(externnotify)) { 05558 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05559 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05560 } else { 05561 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05562 ast_debug(1, "Executing %s\n", arguments); 05563 ast_safe_system(arguments); 05564 } 05565 } 05566 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6192 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock, ast_mutex_unlock, ast_unlock_path(), ast_vm_user::context, COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().
Referenced by close_mailbox(), and vm_execmain().
06193 { 06194 #ifdef IMAP_STORAGE 06195 /* we must use mbox(x) folder names, and copy the message there */ 06196 /* simple. huh? */ 06197 char sequence[10]; 06198 char mailbox[256]; 06199 int res; 06200 06201 /* get the real IMAP message number for this message */ 06202 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06203 06204 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06205 ast_mutex_lock(&vms->lock); 06206 /* if save to Old folder, put in INBOX as read */ 06207 if (box == OLD_FOLDER) { 06208 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06209 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06210 } else if (box == NEW_FOLDER) { 06211 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06212 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06213 } 06214 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06215 ast_mutex_unlock(&vms->lock); 06216 return 0; 06217 } 06218 /* Create the folder if it don't exist */ 06219 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06220 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06221 if (mail_create(vms->mailstream, mailbox) == NIL) 06222 ast_debug(5, "Folder exists.\n"); 06223 else 06224 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06225 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06226 ast_mutex_unlock(&vms->lock); 06227 return res; 06228 #else 06229 char *dir = vms->curdir; 06230 char *username = vms->username; 06231 char *context = vmu->context; 06232 char sfn[PATH_MAX]; 06233 char dfn[PATH_MAX]; 06234 char ddir[PATH_MAX]; 06235 const char *dbox = mbox(vmu, box); 06236 int x, i; 06237 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06238 06239 if (vm_lock_path(ddir)) 06240 return ERROR_LOCK_PATH; 06241 06242 x = last_message_index(vmu, ddir) + 1; 06243 06244 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06245 x--; 06246 for (i = 1; i <= x; i++) { 06247 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06248 make_file(sfn, sizeof(sfn), ddir, i); 06249 make_file(dfn, sizeof(dfn), ddir, i - 1); 06250 if (EXISTS(ddir, i, sfn, NULL)) { 06251 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06252 } else 06253 break; 06254 } 06255 } else { 06256 if (x >= vmu->maxmsg) { 06257 ast_unlock_path(ddir); 06258 return -1; 06259 } 06260 } 06261 make_file(sfn, sizeof(sfn), dir, msg); 06262 make_file(dfn, sizeof(dfn), ddir, x); 06263 if (strcmp(sfn, dfn)) { 06264 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06265 } 06266 ast_unlock_path(ddir); 06267 #endif 06268 return 0; 06269 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6185 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().
06186 { 06187 int d; 06188 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06189 return d; 06190 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12546 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().
12547 { 12548 int res = -1; 12549 char dir[PATH_MAX]; 12550 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12551 ast_debug(2, "About to try retrieving name file %s\n", dir); 12552 RETRIEVE(dir, -1, mailbox, context); 12553 if (ast_fileexists(dir, NULL, NULL)) { 12554 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12555 } 12556 DISPOSE(dir, -1); 12557 return res; 12558 }
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 4856 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, ast_vm_user::mailbox, mailcmd, make_email_file(), VM_ATTACH, and vm_mkftemp().
Referenced by forward_message(), and notify_new_message().
04857 { 04858 FILE *p = NULL; 04859 char tmp[80] = "/tmp/astmail-XXXXXX"; 04860 char tmp2[256]; 04861 char *stringp; 04862 04863 if (vmu && ast_strlen_zero(vmu->email)) { 04864 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04865 return(0); 04866 } 04867 04868 /* Mail only the first format */ 04869 format = ast_strdupa(format); 04870 stringp = format; 04871 strsep(&stringp, "|"); 04872 04873 if (!strcmp(format, "wav49")) 04874 format = "WAV"; 04875 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)); 04876 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04877 command hangs */ 04878 if ((p = vm_mkftemp(tmp)) == NULL) { 04879 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04880 return -1; 04881 } else { 04882 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04883 fclose(p); 04884 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04885 ast_safe_system(tmp2); 04886 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04887 } 04888 return 0; 04889 }
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 4891 of file app_voicemail.c.
References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc, ast_free, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strftime(), ast_strftime_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, mailcmd, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
Referenced by notify_new_message().
04892 { 04893 char enc_cidnum[256], enc_cidname[256]; 04894 char date[256]; 04895 char host[MAXHOSTNAMELEN] = ""; 04896 char who[256]; 04897 char dur[PATH_MAX]; 04898 char tmp[80] = "/tmp/astmail-XXXXXX"; 04899 char tmp2[PATH_MAX]; 04900 struct ast_tm tm; 04901 FILE *p; 04902 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04903 04904 if (!str1 || !str2) { 04905 ast_free(str1); 04906 ast_free(str2); 04907 return -1; 04908 } 04909 04910 if (cidnum) { 04911 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04912 } 04913 if (cidname) { 04914 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04915 } 04916 04917 if ((p = vm_mkftemp(tmp)) == NULL) { 04918 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04919 ast_free(str1); 04920 ast_free(str2); 04921 return -1; 04922 } 04923 gethostname(host, sizeof(host)-1); 04924 if (strchr(srcemail, '@')) { 04925 ast_copy_string(who, srcemail, sizeof(who)); 04926 } else { 04927 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04928 } 04929 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04930 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04931 fprintf(p, "Date: %s\n", date); 04932 04933 /* Reformat for custom pager format */ 04934 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04935 04936 if (!ast_strlen_zero(pagerfromstring)) { 04937 struct ast_channel *ast; 04938 if ((ast = ast_dummy_channel_alloc())) { 04939 char *ptr; 04940 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04941 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04942 04943 if (check_mime(ast_str_buffer(str1))) { 04944 int first_line = 1; 04945 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04946 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04947 *ptr = '\0'; 04948 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04949 first_line = 0; 04950 /* Substring is smaller, so this will never grow */ 04951 ast_str_set(&str2, 0, "%s", ptr + 1); 04952 } 04953 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04954 } else { 04955 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04956 } 04957 ast = ast_channel_unref(ast); 04958 } else { 04959 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04960 } 04961 } else { 04962 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04963 } 04964 04965 if (check_mime(vmu->fullname)) { 04966 int first_line = 1; 04967 char *ptr; 04968 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04969 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04970 *ptr = '\0'; 04971 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04972 first_line = 0; 04973 /* Substring is smaller, so this will never grow */ 04974 ast_str_set(&str2, 0, "%s", ptr + 1); 04975 } 04976 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04977 } else { 04978 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04979 } 04980 04981 if (!ast_strlen_zero(pagersubject)) { 04982 struct ast_channel *ast; 04983 if ((ast = ast_dummy_channel_alloc())) { 04984 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04985 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04986 if (check_mime(ast_str_buffer(str1))) { 04987 int first_line = 1; 04988 char *ptr; 04989 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04990 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04991 *ptr = '\0'; 04992 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04993 first_line = 0; 04994 /* Substring is smaller, so this will never grow */ 04995 ast_str_set(&str2, 0, "%s", ptr + 1); 04996 } 04997 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04998 } else { 04999 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 05000 } 05001 ast = ast_channel_unref(ast); 05002 } else { 05003 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05004 } 05005 } else { 05006 if (ast_strlen_zero(flag)) { 05007 fprintf(p, "Subject: New VM\n\n"); 05008 } else { 05009 fprintf(p, "Subject: New %s VM\n\n", flag); 05010 } 05011 } 05012 05013 if (pagerbody) { 05014 struct ast_channel *ast; 05015 if ((ast = ast_dummy_channel_alloc())) { 05016 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05017 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05018 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05019 ast = ast_channel_unref(ast); 05020 } else { 05021 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05022 } 05023 } else { 05024 fprintf(p, "New %s long %s msg in box %s\n" 05025 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05026 } 05027 05028 fclose(p); 05029 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05030 ast_safe_system(tmp2); 05031 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05032 ast_free(str1); 05033 ast_free(str2); 05034 return 0; 05035 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11111 of file app_voicemail.c.
References ast_category_browse(), ast_cli(), ast_config_destroy(), ast_load_realtime_multientry(), ast_variable_browse(), CLI_FAILURE, CLI_SUCCESS, ast_variable::name, ast_variable::next, SENTINEL, and ast_variable::value.
Referenced by handle_voicemail_show_users().
11112 { 11113 struct ast_config *cfg; 11114 const char *cat = NULL; 11115 11116 if (!(cfg = ast_load_realtime_multientry("voicemail", 11117 "context", context, SENTINEL))) { 11118 return CLI_FAILURE; 11119 } 11120 11121 ast_cli(fd, 11122 "\n" 11123 "=============================================================\n" 11124 "=== Configured Voicemail Users ==============================\n" 11125 "=============================================================\n" 11126 "===\n"); 11127 11128 while ((cat = ast_category_browse(cfg, cat))) { 11129 struct ast_variable *var = NULL; 11130 ast_cli(fd, 11131 "=== Mailbox ...\n" 11132 "===\n"); 11133 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11134 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11135 ast_cli(fd, 11136 "===\n" 11137 "=== ---------------------------------------------------------\n" 11138 "===\n"); 11139 } 11140 11141 ast_cli(fd, 11142 "=============================================================\n" 11143 "\n"); 11144 11145 ast_config_destroy(cfg); 11146 11147 return CLI_SUCCESS; 11148 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11616 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().
11617 { 11618 int errcode; 11619 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11620 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11621 AST_EVENT_IE_END); 11622 11623 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11624 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11625 AST_EVENT_IE_END); 11626 11627 if (mwi_sub_sub) 11628 ast_event_report_subs(mwi_sub_sub); 11629 11630 poll_thread_run = 1; 11631 11632 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11633 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11634 } 11635 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11637 of file app_voicemail.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, mwi_sub_sub, mwi_unsub_sub, poll_cond, poll_thread, and poll_thread_run.
Referenced by actual_load_config(), and unload_module().
11638 { 11639 poll_thread_run = 0; 11640 11641 if (mwi_sub_sub) { 11642 ast_event_unsubscribe(mwi_sub_sub); 11643 mwi_sub_sub = NULL; 11644 } 11645 11646 if (mwi_unsub_sub) { 11647 ast_event_unsubscribe(mwi_unsub_sub); 11648 mwi_unsub_sub = NULL; 11649 } 11650 11651 ast_mutex_lock(&poll_lock); 11652 ast_cond_signal(&poll_cond); 11653 ast_mutex_unlock(&poll_lock); 11654 11655 pthread_join(poll_thread, NULL); 11656 11657 poll_thread = AST_PTHREADT_NULL; 11658 }
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 983 of file app_voicemail.c.
Referenced by make_email_file(), and sendpage().
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11783 of file app_voicemail.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_thread_get().
Referenced by actual_load_config(), apply_option(), and apply_options_full().
11784 { 11785 char *current; 11786 11787 /* Add 16 for fudge factor */ 11788 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11789 11790 ast_str_reset(str); 11791 11792 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11793 for (current = (char *) value; *current; current++) { 11794 if (*current == '\\') { 11795 current++; 11796 if (!*current) { 11797 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11798 break; 11799 } 11800 switch (*current) { 11801 case '\\': 11802 ast_str_append(&str, 0, "\\"); 11803 break; 11804 case 'r': 11805 ast_str_append(&str, 0, "\r"); 11806 break; 11807 case 'n': 11808 #ifdef IMAP_STORAGE 11809 if (!str->used || str->str[str->used - 1] != '\r') { 11810 ast_str_append(&str, 0, "\r"); 11811 } 11812 #endif 11813 ast_str_append(&str, 0, "\n"); 11814 break; 11815 case 't': 11816 ast_str_append(&str, 0, "\t"); 11817 break; 11818 default: 11819 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11820 break; 11821 } 11822 } else { 11823 ast_str_append(&str, 0, "%c", *current); 11824 } 11825 } 11826 11827 return ast_str_buffer(str); 11828 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13095 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().
13096 { 13097 int res; 13098 13099 res = ast_unregister_application(app); 13100 res |= ast_unregister_application(app2); 13101 res |= ast_unregister_application(app3); 13102 res |= ast_unregister_application(app4); 13103 res |= ast_unregister_application(sayname_app); 13104 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13105 res |= ast_manager_unregister("VoicemailUsersList"); 13106 res |= ast_data_unregister(NULL); 13107 #ifdef TEST_FRAMEWORK 13108 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13109 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13110 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13111 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13112 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13113 #endif 13114 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13115 ast_uninstall_vm_functions(); 13116 ao2_ref(inprocess_container, -1); 13117 13118 if (poll_thread != AST_PTHREADT_NULL) 13119 stop_poll_thread(); 13120 13121 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13122 ast_unload_realtime("voicemail"); 13123 ast_unload_realtime("voicemail_data"); 13124 13125 free_vm_users(); 13126 free_vm_zones(); 13127 return res; 13128 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1753 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().
01753 { 01754 01755 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01756 01757 /* remove old allocation */ 01758 if (vms->deleted) { 01759 ast_free(vms->deleted); 01760 vms->deleted = NULL; 01761 } 01762 if (vms->heard) { 01763 ast_free(vms->heard); 01764 vms->heard = NULL; 01765 } 01766 vms->dh_arraysize = 0; 01767 01768 if (arraysize > 0) { 01769 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01770 return -1; 01771 } 01772 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01773 ast_free(vms->deleted); 01774 vms->deleted = NULL; 01775 return -1; 01776 } 01777 vms->dh_arraysize = arraysize; 01778 } 01779 01780 return 0; 01781 }
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 9787 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, find_user(), ast_party_caller::id, ast_party_id::number, ast_vm_user::password, S_COR, ast_party_number::str, ast_party_number::valid, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
09790 { 09791 int useadsi = 0, valid = 0, logretries = 0; 09792 char password[AST_MAX_EXTENSION]="", *passptr; 09793 struct ast_vm_user vmus, *vmu = NULL; 09794 09795 /* If ADSI is supported, setup login screen */ 09796 adsi_begin(chan, &useadsi); 09797 if (!skipuser && useadsi) 09798 adsi_login(chan); 09799 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09800 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09801 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09802 return -1; 09803 } 09804 09805 /* Authenticate them and get their mailbox/password */ 09806 09807 while (!valid && (logretries < max_logins)) { 09808 /* Prompt for, and read in the username */ 09809 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09810 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09811 return -1; 09812 } 09813 if (ast_strlen_zero(mailbox)) { 09814 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09815 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09816 } else { 09817 ast_verb(3, "Username not entered\n"); 09818 return -1; 09819 } 09820 } else if (mailbox[0] == '*') { 09821 /* user entered '*' */ 09822 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09823 if (ast_exists_extension(chan, chan->context, "a", 1, 09824 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09825 return -1; 09826 } 09827 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09828 mailbox[0] = '\0'; 09829 } 09830 09831 if (useadsi) 09832 adsi_password(chan); 09833 09834 if (!ast_strlen_zero(prefix)) { 09835 char fullusername[80] = ""; 09836 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09837 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09838 ast_copy_string(mailbox, fullusername, mailbox_size); 09839 } 09840 09841 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09842 vmu = find_user(&vmus, context, mailbox); 09843 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09844 /* saved password is blank, so don't bother asking */ 09845 password[0] = '\0'; 09846 } else { 09847 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09848 if (ast_streamfile(chan, vm_password, chan->language)) { 09849 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09850 return -1; 09851 } 09852 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09853 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09854 return -1; 09855 } else if (password[0] == '*') { 09856 /* user entered '*' */ 09857 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09858 if (ast_exists_extension(chan, chan->context, "a", 1, 09859 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09860 mailbox[0] = '*'; 09861 return -1; 09862 } 09863 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09864 mailbox[0] = '\0'; 09865 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09866 vmu = NULL; 09867 } 09868 } 09869 09870 if (vmu) { 09871 passptr = vmu->password; 09872 if (passptr[0] == '-') passptr++; 09873 } 09874 if (vmu && !strcmp(passptr, password)) 09875 valid++; 09876 else { 09877 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09878 if (!ast_strlen_zero(prefix)) 09879 mailbox[0] = '\0'; 09880 } 09881 logretries++; 09882 if (!valid) { 09883 if (skipuser || logretries >= max_logins) { 09884 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09885 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09886 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09887 return -1; 09888 } 09889 } else { 09890 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09891 if (useadsi) 09892 adsi_login(chan); 09893 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09894 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09895 return -1; 09896 } 09897 } 09898 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09899 return -1; 09900 } 09901 } 09902 if (!valid && (logretries >= max_logins)) { 09903 ast_stopstream(chan); 09904 ast_play_and_wait(chan, "vm-goodbye"); 09905 return -1; 09906 } 09907 if (vmu && !skipuser) { 09908 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09909 } 09910 return 0; 09911 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11006 of file app_voicemail.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), find_user(), mbox(), and pbx_builtin_setvar_helper().
Referenced by load_module().
11007 { 11008 struct ast_vm_user svm; 11009 char *context, *box; 11010 AST_DECLARE_APP_ARGS(args, 11011 AST_APP_ARG(mbox); 11012 AST_APP_ARG(options); 11013 ); 11014 static int dep_warning = 0; 11015 11016 if (ast_strlen_zero(data)) { 11017 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11018 return -1; 11019 } 11020 11021 if (!dep_warning) { 11022 dep_warning = 1; 11023 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11024 } 11025 11026 box = ast_strdupa(data); 11027 11028 AST_STANDARD_APP_ARGS(args, box); 11029 11030 if (args.options) { 11031 } 11032 11033 if ((context = strchr(args.mbox, '@'))) { 11034 *context = '\0'; 11035 context++; 11036 } 11037 11038 if (find_user(&svm, context, args.mbox)) { 11039 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11040 } else 11041 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11042 11043 return 0; 11044 }
static int vm_browse_messages | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Top level method to invoke the language variant vm_browse_messages_XX function.
chan | The channel for the current user. We read the language property from this. | |
vms | passed into the language-specific vm_browse_messages function. | |
vmu | passed into the language-specific vm_browse_messages function. |
The method to be invoked is determined by the value of language code property in the user's channel. The default (when unable to match) is to use english.
Definition at line 9766 of file app_voicemail.c.
References vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), and vm_browse_messages_zh().
Referenced by vm_execmain().
09767 { 09768 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09769 return vm_browse_messages_es(chan, vms, vmu); 09770 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09771 return vm_browse_messages_gr(chan, vms, vmu); 09772 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09773 return vm_browse_messages_he(chan, vms, vmu); 09774 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09775 return vm_browse_messages_it(chan, vms, vmu); 09776 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09777 return vm_browse_messages_pt(chan, vms, vmu); 09778 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09779 return vm_browse_messages_vi(chan, vms, vmu); 09780 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09781 return vm_browse_messages_zh(chan, vms, vmu); 09782 } else { /* Default to English syntax */ 09783 return vm_browse_messages_en(chan, vms, vmu); 09784 } 09785 }
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 9605 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().
09606 { 09607 int cmd = 0; 09608 09609 if (vms->lastmsg > -1) { 09610 cmd = play_message(chan, vmu, vms); 09611 } else { 09612 cmd = ast_play_and_wait(chan, "vm-youhave"); 09613 if (!cmd) 09614 cmd = ast_play_and_wait(chan, "vm-no"); 09615 if (!cmd) { 09616 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09617 cmd = ast_play_and_wait(chan, vms->fn); 09618 } 09619 if (!cmd) 09620 cmd = ast_play_and_wait(chan, "vm-messages"); 09621 } 09622 return cmd; 09623 }
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 9659 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09660 { 09661 int cmd; 09662 09663 if (vms->lastmsg > -1) { 09664 cmd = play_message(chan, vmu, vms); 09665 } else { 09666 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09667 if (!cmd) 09668 cmd = ast_play_and_wait(chan, "vm-messages"); 09669 if (!cmd) { 09670 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09671 cmd = ast_play_and_wait(chan, vms->fn); 09672 } 09673 } 09674 return cmd; 09675 }
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 9553 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().
09554 { 09555 int cmd = 0; 09556 09557 if (vms->lastmsg > -1) { 09558 cmd = play_message(chan, vmu, vms); 09559 } else { 09560 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09561 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09562 if (!cmd) { 09563 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09564 cmd = ast_play_and_wait(chan, vms->fn); 09565 } 09566 if (!cmd) 09567 cmd = ast_play_and_wait(chan, "vm-messages"); 09568 } else { 09569 if (!cmd) 09570 cmd = ast_play_and_wait(chan, "vm-messages"); 09571 if (!cmd) { 09572 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09573 cmd = ast_play_and_wait(chan, vms->fn); 09574 } 09575 } 09576 } 09577 return cmd; 09578 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9581 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09582 { 09583 int cmd = 0; 09584 09585 if (vms->lastmsg > -1) { 09586 cmd = play_message(chan, vmu, vms); 09587 } else { 09588 if (!strcasecmp(vms->fn, "INBOX")) { 09589 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09590 } else { 09591 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09592 } 09593 } 09594 return cmd; 09595 }
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 9633 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().
09634 { 09635 int cmd; 09636 09637 if (vms->lastmsg > -1) { 09638 cmd = play_message(chan, vmu, vms); 09639 } else { 09640 cmd = ast_play_and_wait(chan, "vm-no"); 09641 if (!cmd) 09642 cmd = ast_play_and_wait(chan, "vm-message"); 09643 if (!cmd) { 09644 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09645 cmd = ast_play_and_wait(chan, vms->fn); 09646 } 09647 } 09648 return cmd; 09649 }
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 9685 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().
09686 { 09687 int cmd; 09688 09689 if (vms->lastmsg > -1) { 09690 cmd = play_message(chan, vmu, vms); 09691 } else { 09692 cmd = ast_play_and_wait(chan, "vm-no"); 09693 if (!cmd) { 09694 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09695 cmd = ast_play_and_wait(chan, vms->fn); 09696 } 09697 if (!cmd) 09698 cmd = ast_play_and_wait(chan, "vm-messages"); 09699 } 09700 return cmd; 09701 }
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 9739 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09740 { 09741 int cmd = 0; 09742 09743 if (vms->lastmsg > -1) { 09744 cmd = play_message(chan, vmu, vms); 09745 } else { 09746 cmd = ast_play_and_wait(chan, "vm-no"); 09747 if (!cmd) { 09748 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09749 cmd = ast_play_and_wait(chan, vms->fn); 09750 } 09751 } 09752 return cmd; 09753 }
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 9711 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().
09712 { 09713 int cmd; 09714 09715 if (vms->lastmsg > -1) { 09716 cmd = play_message(chan, vmu, vms); 09717 } else { 09718 cmd = ast_play_and_wait(chan, "vm-you"); 09719 if (!cmd) 09720 cmd = ast_play_and_wait(chan, "vm-haveno"); 09721 if (!cmd) 09722 cmd = ast_play_and_wait(chan, "vm-messages"); 09723 if (!cmd) { 09724 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09725 cmd = ast_play_and_wait(chan, vms->fn); 09726 } 09727 } 09728 return cmd; 09729 }
static 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 1509 of file app_voicemail.c.
References ast_alloca, 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().
01510 { 01511 struct ast_config *cfg = NULL; 01512 struct ast_variable *var = NULL; 01513 struct ast_category *cat = NULL; 01514 char *category = NULL, *value = NULL, *new = NULL; 01515 const char *tmp = NULL; 01516 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01517 char secretfn[PATH_MAX] = ""; 01518 int found = 0; 01519 01520 if (!change_password_realtime(vmu, newpassword)) 01521 return; 01522 01523 /* check if we should store the secret in the spool directory next to the messages */ 01524 switch (vmu->passwordlocation) { 01525 case OPT_PWLOC_SPOOLDIR: 01526 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01527 if (write_password_to_file(secretfn, newpassword) == 0) { 01528 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01529 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01530 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01531 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01532 break; 01533 } else { 01534 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01535 } 01536 /* Fall-through */ 01537 case OPT_PWLOC_VOICEMAILCONF: 01538 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01539 while ((category = ast_category_browse(cfg, category))) { 01540 if (!strcasecmp(category, vmu->context)) { 01541 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01542 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01543 break; 01544 } 01545 value = strstr(tmp, ","); 01546 if (!value) { 01547 new = ast_alloca(strlen(newpassword)+1); 01548 sprintf(new, "%s", newpassword); 01549 } else { 01550 new = ast_alloca((strlen(value) + strlen(newpassword) + 1)); 01551 sprintf(new, "%s%s", newpassword, value); 01552 } 01553 if (!(cat = ast_category_get(cfg, category))) { 01554 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01555 break; 01556 } 01557 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01558 found = 1; 01559 } 01560 } 01561 /* save the results */ 01562 if (found) { 01563 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01564 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01565 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01566 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01567 break; 01568 } 01569 } 01570 /* Fall-through */ 01571 case OPT_PWLOC_USERSCONF: 01572 /* check users.conf and update the password stored for the mailbox */ 01573 /* if no vmsecret entry exists create one. */ 01574 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01575 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01576 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01577 ast_debug(4, "users.conf: %s\n", category); 01578 if (!strcasecmp(category, vmu->mailbox)) { 01579 if (!ast_variable_retrieve(cfg, category, "vmsecret")) { 01580 ast_debug(3, "looks like we need to make vmsecret!\n"); 01581 var = ast_variable_new("vmsecret", newpassword, ""); 01582 } else { 01583 var = NULL; 01584 } 01585 new = ast_alloca(strlen(newpassword) + 1); 01586 sprintf(new, "%s", newpassword); 01587 if (!(cat = ast_category_get(cfg, category))) { 01588 ast_debug(4, "failed to get category!\n"); 01589 ast_free(var); 01590 break; 01591 } 01592 if (!var) { 01593 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01594 } else { 01595 ast_variable_append(cat, var); 01596 } 01597 found = 1; 01598 break; 01599 } 01600 } 01601 /* save the results and clean things up */ 01602 if (found) { 01603 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01604 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01605 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01606 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01607 } 01608 } 01609 } 01610 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1612 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().
01613 { 01614 char buf[255]; 01615 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01616 ast_debug(1, "External password: %s\n",buf); 01617 if (!ast_safe_system(buf)) { 01618 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01619 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01620 /* Reset the password in memory, too */ 01621 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01622 } 01623 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1180 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().
01181 { 01182 int fds[2], pid = 0; 01183 01184 memset(buf, 0, len); 01185 01186 if (pipe(fds)) { 01187 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01188 } else { 01189 /* good to go*/ 01190 pid = ast_safe_fork(0); 01191 01192 if (pid < 0) { 01193 /* ok maybe not */ 01194 close(fds[0]); 01195 close(fds[1]); 01196 snprintf(buf, len, "FAILURE: Fork failed"); 01197 } else if (pid) { 01198 /* parent */ 01199 close(fds[1]); 01200 if (read(fds[0], buf, len) < 0) { 01201 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01202 } 01203 close(fds[0]); 01204 } else { 01205 /* child */ 01206 AST_DECLARE_APP_ARGS(arg, 01207 AST_APP_ARG(v)[20]; 01208 ); 01209 char *mycmd = ast_strdupa(command); 01210 01211 close(fds[0]); 01212 dup2(fds[1], STDOUT_FILENO); 01213 close(fds[1]); 01214 ast_close_fds_above_n(STDOUT_FILENO); 01215 01216 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01217 01218 execv(arg.v[0], arg.v); 01219 printf("FAILURE: %s", strerror(errno)); 01220 _exit(0); 01221 } 01222 } 01223 return buf; 01224 }
static int vm_delete | ( | char * | file | ) | [static] |
Removes the voicemail sound and information file.
file | The path to the sound file. This will be the the folder and message index, without the extension. |
This is used by the DELETE macro when voicemails are stored on the file system.
Definition at line 4195 of file app_voicemail.c.
References ast_alloca, ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
Referenced by copy_message(), and notify_new_message().
04196 { 04197 char *txt; 04198 int txtsize = 0; 04199 04200 txtsize = (strlen(file) + 5)*sizeof(char); 04201 txt = ast_alloca(txtsize); 04202 /* Sprintf here would safe because we alloca'd exactly the right length, 04203 * but trying to eliminate all sprintf's anyhow 04204 */ 04205 if (ast_check_realtime("voicemail_data")) { 04206 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04207 } 04208 snprintf(txt, txtsize, "%s.txt", file); 04209 unlink(txt); 04210 return ast_filedelete(file, NULL); 04211 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10665 of file app_voicemail.c.
References ast_channel::_state, args, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_copy_flags, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_play_and_wait(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, leave_vm_options::exitcontext, leave_voicemail(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_DTMFEXIT, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and leave_vm_options::record_gain.
Referenced by load_module(), and play_record_review().
10666 { 10667 int res = 0; 10668 char *tmp; 10669 struct leave_vm_options leave_options; 10670 struct ast_flags flags = { 0 }; 10671 char *opts[OPT_ARG_ARRAY_SIZE]; 10672 AST_DECLARE_APP_ARGS(args, 10673 AST_APP_ARG(argv0); 10674 AST_APP_ARG(argv1); 10675 ); 10676 10677 memset(&leave_options, 0, sizeof(leave_options)); 10678 10679 if (chan->_state != AST_STATE_UP) 10680 ast_answer(chan); 10681 10682 if (!ast_strlen_zero(data)) { 10683 tmp = ast_strdupa(data); 10684 AST_STANDARD_APP_ARGS(args, tmp); 10685 if (args.argc == 2) { 10686 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10687 return -1; 10688 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10689 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10690 int gain; 10691 10692 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10693 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10694 return -1; 10695 } else { 10696 leave_options.record_gain = (signed char) gain; 10697 } 10698 } 10699 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10700 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10701 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10702 } 10703 } 10704 } else { 10705 char temp[256]; 10706 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10707 if (res < 0) 10708 return res; 10709 if (ast_strlen_zero(temp)) 10710 return 0; 10711 args.argv0 = ast_strdupa(temp); 10712 } 10713 10714 res = leave_voicemail(chan, args.argv0, &leave_options); 10715 if (res == 't') { 10716 ast_play_and_wait(chan, "vm-goodbye"); 10717 res = 0; 10718 } 10719 10720 if (res == OPERATOR_EXIT) { 10721 res = 0; 10722 } 10723 10724 if (res == ERROR_LOCK_PATH) { 10725 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10726 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10727 res = 0; 10728 } 10729 10730 return res; 10731 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9913 of file app_voicemail.c.
References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), AST_LOG_WARNING, ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_suite_assert, ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, vm_state::context, ast_channel::context, vm_state::curdir, vm_state::curmsg, vm_state::deleted, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), vm_state::fn, forward_message(), free_user(), get_folder2(), get_folder_by_name(), globalflags, has_voicemail(), vm_state::heard, language, ast_vm_user::language, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), maxlogins, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, vm_state::newmessages, OLD_FOLDER, vm_state::oldmessages, open_mailbox(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, parse(), ast_vm_user::password, play_message(), queue_mwi_event(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::urgentmessages, vm_state::username, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), VM_MESSAGEWRAP, vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, vm_state::vmbox, and vmfmts.
Referenced by load_module().
09914 { 09915 /* XXX This is, admittedly, some pretty horrendous code. For some 09916 reason it just seemed a lot easier to do with GOTO's. I feel 09917 like I'm back in my GWBASIC days. XXX */ 09918 int res = -1; 09919 int cmd = 0; 09920 int valid = 0; 09921 char prefixstr[80] =""; 09922 char ext_context[256]=""; 09923 int box; 09924 int useadsi = 0; 09925 int skipuser = 0; 09926 struct vm_state vms; 09927 struct ast_vm_user *vmu = NULL, vmus; 09928 char *context = NULL; 09929 int silentexit = 0; 09930 struct ast_flags flags = { 0 }; 09931 signed char record_gain = 0; 09932 int play_auto = 0; 09933 int play_folder = 0; 09934 int in_urgent = 0; 09935 #ifdef IMAP_STORAGE 09936 int deleted = 0; 09937 #endif 09938 09939 /* Add the vm_state to the active list and keep it active */ 09940 memset(&vms, 0, sizeof(vms)); 09941 09942 vms.lastmsg = -1; 09943 09944 memset(&vmus, 0, sizeof(vmus)); 09945 09946 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09947 if (chan->_state != AST_STATE_UP) { 09948 ast_debug(1, "Before ast_answer\n"); 09949 ast_answer(chan); 09950 } 09951 09952 if (!ast_strlen_zero(data)) { 09953 char *opts[OPT_ARG_ARRAY_SIZE]; 09954 char *parse; 09955 AST_DECLARE_APP_ARGS(args, 09956 AST_APP_ARG(argv0); 09957 AST_APP_ARG(argv1); 09958 ); 09959 09960 parse = ast_strdupa(data); 09961 09962 AST_STANDARD_APP_ARGS(args, parse); 09963 09964 if (args.argc == 2) { 09965 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09966 return -1; 09967 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09968 int gain; 09969 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09970 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09971 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09972 return -1; 09973 } else { 09974 record_gain = (signed char) gain; 09975 } 09976 } else { 09977 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09978 } 09979 } 09980 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09981 play_auto = 1; 09982 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09983 /* See if it is a folder name first */ 09984 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09985 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09986 play_folder = -1; 09987 } 09988 } else { 09989 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09990 } 09991 } else { 09992 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09993 } 09994 if (play_folder > 9 || play_folder < 0) { 09995 ast_log(AST_LOG_WARNING, 09996 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09997 opts[OPT_ARG_PLAYFOLDER]); 09998 play_folder = 0; 09999 } 10000 } 10001 } else { 10002 /* old style options parsing */ 10003 while (*(args.argv0)) { 10004 if (*(args.argv0) == 's') 10005 ast_set_flag(&flags, OPT_SILENT); 10006 else if (*(args.argv0) == 'p') 10007 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10008 else 10009 break; 10010 (args.argv0)++; 10011 } 10012 10013 } 10014 10015 valid = ast_test_flag(&flags, OPT_SILENT); 10016 10017 if ((context = strchr(args.argv0, '@'))) 10018 *context++ = '\0'; 10019 10020 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10021 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10022 else 10023 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10024 10025 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10026 skipuser++; 10027 else 10028 valid = 0; 10029 } 10030 10031 if (!valid) 10032 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10033 10034 ast_debug(1, "After vm_authenticate\n"); 10035 10036 if (vms.username[0] == '*') { 10037 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10038 10039 /* user entered '*' */ 10040 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10041 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10042 res = 0; /* prevent hangup */ 10043 goto out; 10044 } 10045 } 10046 10047 if (!res) { 10048 valid = 1; 10049 if (!skipuser) 10050 vmu = &vmus; 10051 } else { 10052 res = 0; 10053 } 10054 10055 /* If ADSI is supported, setup login screen */ 10056 adsi_begin(chan, &useadsi); 10057 10058 ast_test_suite_assert(valid); 10059 if (!valid) { 10060 goto out; 10061 } 10062 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10063 10064 #ifdef IMAP_STORAGE 10065 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10066 pthread_setspecific(ts_vmstate.key, &vms); 10067 10068 vms.interactive = 1; 10069 vms.updated = 1; 10070 if (vmu) 10071 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10072 vmstate_insert(&vms); 10073 init_vm_state(&vms); 10074 #endif 10075 10076 /* Set language from config to override channel language */ 10077 if (!ast_strlen_zero(vmu->language)) 10078 ast_string_field_set(chan, language, vmu->language); 10079 10080 /* Retrieve urgent, old and new message counts */ 10081 ast_debug(1, "Before open_mailbox\n"); 10082 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10083 if (res < 0) 10084 goto out; 10085 vms.oldmessages = vms.lastmsg + 1; 10086 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10087 /* check INBOX */ 10088 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10089 if (res < 0) 10090 goto out; 10091 vms.newmessages = vms.lastmsg + 1; 10092 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10093 /* Start in Urgent */ 10094 in_urgent = 1; 10095 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10096 if (res < 0) 10097 goto out; 10098 vms.urgentmessages = vms.lastmsg + 1; 10099 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10100 10101 /* Select proper mailbox FIRST!! */ 10102 if (play_auto) { 10103 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10104 if (vms.urgentmessages) { 10105 in_urgent = 1; 10106 res = open_mailbox(&vms, vmu, 11); 10107 } else { 10108 in_urgent = 0; 10109 res = open_mailbox(&vms, vmu, play_folder); 10110 } 10111 if (res < 0) 10112 goto out; 10113 10114 /* If there are no new messages, inform the user and hangup */ 10115 if (vms.lastmsg == -1) { 10116 in_urgent = 0; 10117 cmd = vm_browse_messages(chan, &vms, vmu); 10118 res = 0; 10119 goto out; 10120 } 10121 } else { 10122 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10123 /* If we only have old messages start here */ 10124 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10125 in_urgent = 0; 10126 play_folder = 1; 10127 if (res < 0) 10128 goto out; 10129 } else if (!vms.urgentmessages && vms.newmessages) { 10130 /* If we have new messages but none are urgent */ 10131 in_urgent = 0; 10132 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10133 if (res < 0) 10134 goto out; 10135 } 10136 } 10137 10138 if (useadsi) 10139 adsi_status(chan, &vms); 10140 res = 0; 10141 10142 /* Check to see if this is a new user */ 10143 if (!strcasecmp(vmu->mailbox, vmu->password) && 10144 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10145 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10146 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10147 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10148 if ((cmd == 't') || (cmd == '#')) { 10149 /* Timeout */ 10150 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10151 res = 0; 10152 goto out; 10153 } else if (cmd < 0) { 10154 /* Hangup */ 10155 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10156 res = -1; 10157 goto out; 10158 } 10159 } 10160 #ifdef IMAP_STORAGE 10161 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10162 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10163 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10164 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10165 } 10166 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10167 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10168 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10169 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10170 } 10171 #endif 10172 10173 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10174 if (play_auto) { 10175 cmd = '1'; 10176 } else { 10177 cmd = vm_intro(chan, vmu, &vms); 10178 } 10179 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10180 10181 vms.repeats = 0; 10182 vms.starting = 1; 10183 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10184 /* Run main menu */ 10185 switch (cmd) { 10186 case '1': /* First message */ 10187 vms.curmsg = 0; 10188 /* Fall through */ 10189 case '5': /* Play current message */ 10190 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10191 cmd = vm_browse_messages(chan, &vms, vmu); 10192 break; 10193 case '2': /* Change folders */ 10194 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10195 if (useadsi) 10196 adsi_folders(chan, 0, "Change to folder..."); 10197 10198 cmd = get_folder2(chan, "vm-changeto", 0); 10199 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10200 if (cmd == '#') { 10201 cmd = 0; 10202 } else if (cmd > 0) { 10203 cmd = cmd - '0'; 10204 res = close_mailbox(&vms, vmu); 10205 if (res == ERROR_LOCK_PATH) 10206 goto out; 10207 /* If folder is not urgent, set in_urgent to zero! */ 10208 if (cmd != 11) in_urgent = 0; 10209 res = open_mailbox(&vms, vmu, cmd); 10210 if (res < 0) 10211 goto out; 10212 play_folder = cmd; 10213 cmd = 0; 10214 } 10215 if (useadsi) 10216 adsi_status2(chan, &vms); 10217 10218 if (!cmd) { 10219 cmd = vm_play_folder_name(chan, vms.vmbox); 10220 } 10221 10222 vms.starting = 1; 10223 vms.curmsg = 0; 10224 break; 10225 case '3': /* Advanced options */ 10226 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10227 cmd = 0; 10228 vms.repeats = 0; 10229 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10230 switch (cmd) { 10231 case '1': /* Reply */ 10232 if (vms.lastmsg > -1 && !vms.starting) { 10233 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10234 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10235 res = cmd; 10236 goto out; 10237 } 10238 } else { 10239 cmd = ast_play_and_wait(chan, "vm-sorry"); 10240 } 10241 cmd = 't'; 10242 break; 10243 case '2': /* Callback */ 10244 if (!vms.starting) 10245 ast_verb(3, "Callback Requested\n"); 10246 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10247 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10248 if (cmd == 9) { 10249 silentexit = 1; 10250 goto out; 10251 } else if (cmd == ERROR_LOCK_PATH) { 10252 res = cmd; 10253 goto out; 10254 } 10255 } else { 10256 cmd = ast_play_and_wait(chan, "vm-sorry"); 10257 } 10258 cmd = 't'; 10259 break; 10260 case '3': /* Envelope */ 10261 if (vms.lastmsg > -1 && !vms.starting) { 10262 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10263 if (cmd == ERROR_LOCK_PATH) { 10264 res = cmd; 10265 goto out; 10266 } 10267 } else { 10268 cmd = ast_play_and_wait(chan, "vm-sorry"); 10269 } 10270 cmd = 't'; 10271 break; 10272 case '4': /* Dialout */ 10273 if (!ast_strlen_zero(vmu->dialout)) { 10274 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10275 if (cmd == 9) { 10276 silentexit = 1; 10277 goto out; 10278 } 10279 } else { 10280 cmd = ast_play_and_wait(chan, "vm-sorry"); 10281 } 10282 cmd = 't'; 10283 break; 10284 10285 case '5': /* Leave VoiceMail */ 10286 if (ast_test_flag(vmu, VM_SVMAIL)) { 10287 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10288 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10289 res = cmd; 10290 goto out; 10291 } 10292 } else { 10293 cmd = ast_play_and_wait(chan, "vm-sorry"); 10294 } 10295 cmd = 't'; 10296 break; 10297 10298 case '*': /* Return to main menu */ 10299 cmd = 't'; 10300 break; 10301 10302 default: 10303 cmd = 0; 10304 if (!vms.starting) { 10305 cmd = ast_play_and_wait(chan, "vm-toreply"); 10306 } 10307 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10308 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10309 } 10310 if (!cmd && !vms.starting) { 10311 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10312 } 10313 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10314 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10315 } 10316 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10317 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10318 } 10319 if (!cmd) { 10320 cmd = ast_play_and_wait(chan, "vm-starmain"); 10321 } 10322 if (!cmd) { 10323 cmd = ast_waitfordigit(chan, 6000); 10324 } 10325 if (!cmd) { 10326 vms.repeats++; 10327 } 10328 if (vms.repeats > 3) { 10329 cmd = 't'; 10330 } 10331 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10332 } 10333 } 10334 if (cmd == 't') { 10335 cmd = 0; 10336 vms.repeats = 0; 10337 } 10338 break; 10339 case '4': /* Go to the previous message */ 10340 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10341 if (vms.curmsg > 0) { 10342 vms.curmsg--; 10343 cmd = play_message(chan, vmu, &vms); 10344 } else { 10345 /* Check if we were listening to new 10346 messages. If so, go to Urgent messages 10347 instead of saying "no more messages" 10348 */ 10349 if (in_urgent == 0 && vms.urgentmessages > 0) { 10350 /* Check for Urgent messages */ 10351 in_urgent = 1; 10352 res = close_mailbox(&vms, vmu); 10353 if (res == ERROR_LOCK_PATH) 10354 goto out; 10355 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10356 if (res < 0) 10357 goto out; 10358 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10359 vms.curmsg = vms.lastmsg; 10360 if (vms.lastmsg < 0) { 10361 cmd = ast_play_and_wait(chan, "vm-nomore"); 10362 } 10363 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10364 vms.curmsg = vms.lastmsg; 10365 cmd = play_message(chan, vmu, &vms); 10366 } else { 10367 cmd = ast_play_and_wait(chan, "vm-nomore"); 10368 } 10369 } 10370 break; 10371 case '6': /* Go to the next message */ 10372 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10373 if (vms.curmsg < vms.lastmsg) { 10374 vms.curmsg++; 10375 cmd = play_message(chan, vmu, &vms); 10376 } else { 10377 if (in_urgent && vms.newmessages > 0) { 10378 /* Check if we were listening to urgent 10379 * messages. If so, go to regular new messages 10380 * instead of saying "no more messages" 10381 */ 10382 in_urgent = 0; 10383 res = close_mailbox(&vms, vmu); 10384 if (res == ERROR_LOCK_PATH) 10385 goto out; 10386 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10387 if (res < 0) 10388 goto out; 10389 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10390 vms.curmsg = -1; 10391 if (vms.lastmsg < 0) { 10392 cmd = ast_play_and_wait(chan, "vm-nomore"); 10393 } 10394 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10395 vms.curmsg = 0; 10396 cmd = play_message(chan, vmu, &vms); 10397 } else { 10398 cmd = ast_play_and_wait(chan, "vm-nomore"); 10399 } 10400 } 10401 break; 10402 case '7': /* Delete the current message */ 10403 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10404 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10405 if (useadsi) 10406 adsi_delete(chan, &vms); 10407 if (vms.deleted[vms.curmsg]) { 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-deleted"); 10418 } else { 10419 if (play_folder == 0) { 10420 if (in_urgent) { 10421 vms.urgentmessages++; 10422 } else { 10423 vms.newmessages++; 10424 } 10425 } 10426 else if (play_folder == 1) 10427 vms.oldmessages++; 10428 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10429 } 10430 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10431 if (vms.curmsg < vms.lastmsg) { 10432 vms.curmsg++; 10433 cmd = play_message(chan, vmu, &vms); 10434 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10435 vms.curmsg = 0; 10436 cmd = play_message(chan, vmu, &vms); 10437 } else { 10438 /* Check if we were listening to urgent 10439 messages. If so, go to regular new messages 10440 instead of saying "no more messages" 10441 */ 10442 if (in_urgent == 1) { 10443 /* Check for new messages */ 10444 in_urgent = 0; 10445 res = close_mailbox(&vms, vmu); 10446 if (res == ERROR_LOCK_PATH) 10447 goto out; 10448 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10449 if (res < 0) 10450 goto out; 10451 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10452 vms.curmsg = -1; 10453 if (vms.lastmsg < 0) { 10454 cmd = ast_play_and_wait(chan, "vm-nomore"); 10455 } 10456 } else { 10457 cmd = ast_play_and_wait(chan, "vm-nomore"); 10458 } 10459 } 10460 } 10461 } else /* Delete not valid if we haven't selected a message */ 10462 cmd = 0; 10463 #ifdef IMAP_STORAGE 10464 deleted = 1; 10465 #endif 10466 break; 10467 10468 case '8': /* Forward the current message */ 10469 if (vms.lastmsg > -1) { 10470 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10471 if (cmd == ERROR_LOCK_PATH) { 10472 res = cmd; 10473 goto out; 10474 } 10475 } else { 10476 /* Check if we were listening to urgent 10477 messages. If so, go to regular new messages 10478 instead of saying "no more messages" 10479 */ 10480 if (in_urgent == 1 && vms.newmessages > 0) { 10481 /* Check for new messages */ 10482 in_urgent = 0; 10483 res = close_mailbox(&vms, vmu); 10484 if (res == ERROR_LOCK_PATH) 10485 goto out; 10486 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10487 if (res < 0) 10488 goto out; 10489 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10490 vms.curmsg = -1; 10491 if (vms.lastmsg < 0) { 10492 cmd = ast_play_and_wait(chan, "vm-nomore"); 10493 } 10494 } else { 10495 cmd = ast_play_and_wait(chan, "vm-nomore"); 10496 } 10497 } 10498 break; 10499 case '9': /* Save message to folder */ 10500 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10501 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10502 /* No message selected */ 10503 cmd = 0; 10504 break; 10505 } 10506 if (useadsi) 10507 adsi_folders(chan, 1, "Save to folder..."); 10508 cmd = get_folder2(chan, "vm-savefolder", 1); 10509 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10510 box = 0; /* Shut up compiler */ 10511 if (cmd == '#') { 10512 cmd = 0; 10513 break; 10514 } else if (cmd > 0) { 10515 box = cmd = cmd - '0'; 10516 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10517 if (cmd == ERROR_LOCK_PATH) { 10518 res = cmd; 10519 goto out; 10520 #ifndef IMAP_STORAGE 10521 } else if (!cmd) { 10522 vms.deleted[vms.curmsg] = 1; 10523 #endif 10524 } else { 10525 vms.deleted[vms.curmsg] = 0; 10526 vms.heard[vms.curmsg] = 0; 10527 } 10528 } 10529 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10530 if (useadsi) 10531 adsi_message(chan, &vms); 10532 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10533 if (!cmd) { 10534 cmd = ast_play_and_wait(chan, "vm-message"); 10535 if (!cmd) 10536 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10537 if (!cmd) 10538 cmd = ast_play_and_wait(chan, "vm-savedto"); 10539 if (!cmd) 10540 cmd = vm_play_folder_name(chan, vms.fn); 10541 } else { 10542 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10543 } 10544 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10545 if (vms.curmsg < vms.lastmsg) { 10546 vms.curmsg++; 10547 cmd = play_message(chan, vmu, &vms); 10548 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10549 vms.curmsg = 0; 10550 cmd = play_message(chan, vmu, &vms); 10551 } else { 10552 /* Check if we were listening to urgent 10553 messages. If so, go to regular new messages 10554 instead of saying "no more messages" 10555 */ 10556 if (in_urgent == 1 && vms.newmessages > 0) { 10557 /* Check for new messages */ 10558 in_urgent = 0; 10559 res = close_mailbox(&vms, vmu); 10560 if (res == ERROR_LOCK_PATH) 10561 goto out; 10562 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10563 if (res < 0) 10564 goto out; 10565 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10566 vms.curmsg = -1; 10567 if (vms.lastmsg < 0) { 10568 cmd = ast_play_and_wait(chan, "vm-nomore"); 10569 } 10570 } else { 10571 cmd = ast_play_and_wait(chan, "vm-nomore"); 10572 } 10573 } 10574 } 10575 break; 10576 case '*': /* Help */ 10577 if (!vms.starting) { 10578 cmd = ast_play_and_wait(chan, "vm-onefor"); 10579 if (!strncasecmp(chan->language, "he", 2)) { 10580 cmd = ast_play_and_wait(chan, "vm-for"); 10581 } 10582 if (!cmd) 10583 cmd = vm_play_folder_name(chan, vms.vmbox); 10584 if (!cmd) 10585 cmd = ast_play_and_wait(chan, "vm-opts"); 10586 if (!cmd) 10587 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10588 } else 10589 cmd = 0; 10590 break; 10591 case '0': /* Mailbox options */ 10592 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10593 if (useadsi) 10594 adsi_status(chan, &vms); 10595 break; 10596 default: /* Nothing */ 10597 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10598 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10599 break; 10600 } 10601 } 10602 if ((cmd == 't') || (cmd == '#')) { 10603 /* Timeout */ 10604 res = 0; 10605 } else { 10606 /* Hangup */ 10607 res = -1; 10608 } 10609 10610 out: 10611 if (res > -1) { 10612 ast_stopstream(chan); 10613 adsi_goodbye(chan); 10614 if (valid && res != OPERATOR_EXIT) { 10615 if (silentexit) 10616 res = ast_play_and_wait(chan, "vm-dialout"); 10617 else 10618 res = ast_play_and_wait(chan, "vm-goodbye"); 10619 } 10620 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10621 res = 0; 10622 } 10623 if (useadsi) 10624 ast_adsi_unload_session(chan); 10625 } 10626 if (vmu) 10627 close_mailbox(&vms, vmu); 10628 if (valid) { 10629 int new = 0, old = 0, urgent = 0; 10630 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10631 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10632 /* Urgent flag not passwd to externnotify here */ 10633 run_externnotify(vmu->context, vmu->mailbox, NULL); 10634 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10635 queue_mwi_event(ext_context, urgent, new, old); 10636 } 10637 #ifdef IMAP_STORAGE 10638 /* expunge message - use UID Expunge if supported on IMAP server*/ 10639 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10640 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10641 ast_mutex_lock(&vms.lock); 10642 #ifdef HAVE_IMAP_TK2006 10643 if (LEVELUIDPLUS (vms.mailstream)) { 10644 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10645 } else 10646 #endif 10647 mail_expunge(vms.mailstream); 10648 ast_mutex_unlock(&vms.lock); 10649 } 10650 /* before we delete the state, we should copy pertinent info 10651 * back to the persistent model */ 10652 if (vmu) { 10653 vmstate_delete(&vms); 10654 } 10655 #endif 10656 if (vmu) 10657 free_user(vmu); 10658 10659 #ifdef IMAP_STORAGE 10660 pthread_setspecific(ts_vmstate.key, NULL); 10661 #endif 10662 return res; 10663 }
static int vm_forwardoptions | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | curdir, | |||
int | curmsg, | |||
char * | vm_fmts, | |||
char * | context, | |||
signed char | record_gain, | |||
long * | duration, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
presents the option to prepend to an existing message when forwarding it.
chan | ||
vmu | ||
curdir | ||
curmsg | ||
vm_fmts | ||
context | ||
record_gain | ||
duration | ||
vms | ||
flag |
Presents a prompt for 1 to prepend the current message, 2 to forward the message without prepending, or * to return to the main menu.
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6873 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().
06875 { 06876 int cmd = 0; 06877 int retries = 0, prepend_duration = 0, already_recorded = 0; 06878 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06879 char textfile[PATH_MAX]; 06880 struct ast_config *msg_cfg; 06881 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06882 #ifndef IMAP_STORAGE 06883 signed char zero_gain = 0; 06884 #endif 06885 const char *duration_str; 06886 06887 /* Must always populate duration correctly */ 06888 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06889 strcpy(textfile, msgfile); 06890 strcpy(backup, msgfile); 06891 strcpy(backup_textfile, msgfile); 06892 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06893 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06894 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06895 06896 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06897 *duration = atoi(duration_str); 06898 } else { 06899 *duration = 0; 06900 } 06901 06902 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06903 if (cmd) 06904 retries = 0; 06905 switch (cmd) { 06906 case '1': 06907 06908 #ifdef IMAP_STORAGE 06909 /* Record new intro file */ 06910 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06911 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06912 ast_play_and_wait(chan, INTRO); 06913 ast_play_and_wait(chan, "beep"); 06914 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06915 if (cmd == -1) { 06916 break; 06917 } 06918 cmd = 't'; 06919 #else 06920 06921 /* prepend a message to the current message, update the metadata and return */ 06922 06923 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06924 strcpy(textfile, msgfile); 06925 strncat(textfile, ".txt", sizeof(textfile) - 1); 06926 *duration = 0; 06927 06928 /* if we can't read the message metadata, stop now */ 06929 if (!msg_cfg) { 06930 cmd = 0; 06931 break; 06932 } 06933 06934 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06935 #ifndef IMAP_STORAGE 06936 if (already_recorded) { 06937 ast_filecopy(backup, msgfile, NULL); 06938 copy(backup_textfile, textfile); 06939 } 06940 else { 06941 ast_filecopy(msgfile, backup, NULL); 06942 copy(textfile, backup_textfile); 06943 } 06944 #endif 06945 already_recorded = 1; 06946 06947 if (record_gain) 06948 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06949 06950 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06951 06952 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06953 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06954 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06955 ast_filerename(backup, msgfile, NULL); 06956 } 06957 06958 if (record_gain) 06959 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06960 06961 06962 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06963 *duration = atoi(duration_str); 06964 06965 if (prepend_duration) { 06966 struct ast_category *msg_cat; 06967 /* need enough space for a maximum-length message duration */ 06968 char duration_buf[12]; 06969 06970 *duration += prepend_duration; 06971 msg_cat = ast_category_get(msg_cfg, "message"); 06972 snprintf(duration_buf, 11, "%ld", *duration); 06973 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06974 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06975 } 06976 } 06977 06978 #endif 06979 break; 06980 case '2': 06981 /* NULL out introfile so we know there is no intro! */ 06982 #ifdef IMAP_STORAGE 06983 *vms->introfn = '\0'; 06984 #endif 06985 cmd = 't'; 06986 break; 06987 case '*': 06988 cmd = '*'; 06989 break; 06990 default: 06991 /* If time_out and return to menu, reset already_recorded */ 06992 already_recorded = 0; 06993 06994 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06995 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06996 if (!cmd) { 06997 cmd = ast_play_and_wait(chan, "vm-starmain"); 06998 /* "press star to return to the main menu" */ 06999 } 07000 if (!cmd) { 07001 cmd = ast_waitfordigit(chan, 6000); 07002 } 07003 if (!cmd) { 07004 retries++; 07005 } 07006 if (retries > 3) { 07007 cmd = '*'; /* Let's cancel this beast */ 07008 } 07009 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07010 } 07011 } 07012 07013 if (msg_cfg) 07014 ast_config_destroy(msg_cfg); 07015 if (prepend_duration) 07016 *duration = prepend_duration; 07017 07018 if (already_recorded && cmd == -1) { 07019 /* restore original message if prepention cancelled */ 07020 ast_filerename(backup, msgfile, NULL); 07021 rename(backup_textfile, textfile); 07022 } 07023 07024 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07025 cmd = 0; 07026 return cmd; 07027 }
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 9228 of file app_voicemail.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09229 { 09230 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09231 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09232 } else { /* Default to ENGLISH */ 09233 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09234 } 09235 }
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 9116 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().
09117 { 09118 int res = 0; 09119 /* Play instructions and wait for new command */ 09120 while (!res) { 09121 if (vms->starting) { 09122 if (vms->lastmsg > -1) { 09123 if (skipadvanced) 09124 res = ast_play_and_wait(chan, "vm-onefor-full"); 09125 else 09126 res = ast_play_and_wait(chan, "vm-onefor"); 09127 if (!res) 09128 res = vm_play_folder_name(chan, vms->vmbox); 09129 } 09130 if (!res) { 09131 if (skipadvanced) 09132 res = ast_play_and_wait(chan, "vm-opts-full"); 09133 else 09134 res = ast_play_and_wait(chan, "vm-opts"); 09135 } 09136 } else { 09137 /* Added for additional help */ 09138 if (skipadvanced) { 09139 res = ast_play_and_wait(chan, "vm-onefor-full"); 09140 if (!res) 09141 res = vm_play_folder_name(chan, vms->vmbox); 09142 res = ast_play_and_wait(chan, "vm-opts-full"); 09143 } 09144 /* Logic: 09145 * If the current message is not the first OR 09146 * if we're listening to the first new message and there are 09147 * also urgent messages, then prompt for navigation to the 09148 * previous message 09149 */ 09150 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09151 res = ast_play_and_wait(chan, "vm-prev"); 09152 } 09153 if (!res && !skipadvanced) 09154 res = ast_play_and_wait(chan, "vm-advopts"); 09155 if (!res) 09156 res = ast_play_and_wait(chan, "vm-repeat"); 09157 /* Logic: 09158 * If we're not listening to the last message OR 09159 * we're listening to the last urgent message and there are 09160 * also new non-urgent messages, then prompt for navigation 09161 * to the next message 09162 */ 09163 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09164 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09165 res = ast_play_and_wait(chan, "vm-next"); 09166 } 09167 if (!res) { 09168 int curmsg_deleted; 09169 #ifdef IMAP_STORAGE 09170 ast_mutex_lock(&vms->lock); 09171 #endif 09172 curmsg_deleted = vms->deleted[vms->curmsg]; 09173 #ifdef IMAP_STORAGE 09174 ast_mutex_unlock(&vms->lock); 09175 #endif 09176 if (!curmsg_deleted) { 09177 res = ast_play_and_wait(chan, "vm-delete"); 09178 } else { 09179 res = ast_play_and_wait(chan, "vm-undelete"); 09180 } 09181 if (!res) { 09182 res = ast_play_and_wait(chan, "vm-toforward"); 09183 } 09184 if (!res) { 09185 res = ast_play_and_wait(chan, "vm-savemessage"); 09186 } 09187 } 09188 } 09189 if (!res) { 09190 res = ast_play_and_wait(chan, "vm-helpexit"); 09191 } 09192 if (!res) 09193 res = ast_waitfordigit(chan, 6000); 09194 if (!res) { 09195 vms->repeats++; 09196 if (vms->repeats > 2) { 09197 res = 't'; 09198 } 09199 } 09200 } 09201 return res; 09202 }
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 9204 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().
09205 { 09206 int res = 0; 09207 /* Play instructions and wait for new command */ 09208 while (!res) { 09209 if (vms->lastmsg > -1) { 09210 res = ast_play_and_wait(chan, "vm-listen"); 09211 if (!res) 09212 res = vm_play_folder_name(chan, vms->vmbox); 09213 if (!res) 09214 res = ast_play_and_wait(chan, "press"); 09215 if (!res) 09216 res = ast_play_and_wait(chan, "digits/1"); 09217 } 09218 if (!res) 09219 res = ast_play_and_wait(chan, "vm-opts"); 09220 if (!res) { 09221 vms->starting = 0; 09222 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09223 } 09224 } 09225 return res; 09226 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9054 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, LOG_WARNING, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_vi(), vm_intro_zh(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.
Referenced by vm_execmain().
09055 { 09056 char prefile[256]; 09057 09058 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09059 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09060 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09061 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09062 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09063 ast_play_and_wait(chan, "vm-tempgreetactive"); 09064 } 09065 DISPOSE(prefile, -1); 09066 } 09067 09068 /* Play voicemail intro - syntax is different for different languages */ 09069 if (0) { 09070 return 0; 09071 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09072 return vm_intro_cs(chan, vms); 09073 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09074 static int deprecation_warning = 0; 09075 if (deprecation_warning++ % 10 == 0) { 09076 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09077 } 09078 return vm_intro_cs(chan, vms); 09079 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09080 return vm_intro_de(chan, vms); 09081 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09082 return vm_intro_es(chan, vms); 09083 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09084 return vm_intro_fr(chan, vms); 09085 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09086 return vm_intro_gr(chan, vms); 09087 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09088 return vm_intro_he(chan, vms); 09089 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09090 return vm_intro_it(chan, vms); 09091 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09092 return vm_intro_nl(chan, vms); 09093 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09094 return vm_intro_no(chan, vms); 09095 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09096 return vm_intro_pl(chan, vms); 09097 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09098 return vm_intro_pt_BR(chan, vms); 09099 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09100 return vm_intro_pt(chan, vms); 09101 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09102 return vm_intro_multilang(chan, vms, "n"); 09103 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09104 return vm_intro_se(chan, vms); 09105 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09106 return vm_intro_multilang(chan, vms, "n"); 09107 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09108 return vm_intro_vi(chan, vms); 09109 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09110 return vm_intro_zh(chan, vms); 09111 } else { /* Default to ENGLISH */ 09112 return vm_intro_en(chan, vms); 09113 } 09114 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8924 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08925 { 08926 int res; 08927 res = ast_play_and_wait(chan, "vm-youhave"); 08928 if (!res) { 08929 if (vms->newmessages) { 08930 if (vms->newmessages == 1) { 08931 res = ast_play_and_wait(chan, "digits/jednu"); 08932 } else { 08933 res = say_and_wait(chan, vms->newmessages, chan->language); 08934 } 08935 if (!res) { 08936 if ((vms->newmessages == 1)) 08937 res = ast_play_and_wait(chan, "vm-novou"); 08938 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08939 res = ast_play_and_wait(chan, "vm-nove"); 08940 if (vms->newmessages > 4) 08941 res = ast_play_and_wait(chan, "vm-novych"); 08942 } 08943 if (vms->oldmessages && !res) 08944 res = ast_play_and_wait(chan, "vm-and"); 08945 else if (!res) { 08946 if ((vms->newmessages == 1)) 08947 res = ast_play_and_wait(chan, "vm-zpravu"); 08948 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08949 res = ast_play_and_wait(chan, "vm-zpravy"); 08950 if (vms->newmessages > 4) 08951 res = ast_play_and_wait(chan, "vm-zprav"); 08952 } 08953 } 08954 if (!res && vms->oldmessages) { 08955 res = say_and_wait(chan, vms->oldmessages, chan->language); 08956 if (!res) { 08957 if ((vms->oldmessages == 1)) 08958 res = ast_play_and_wait(chan, "vm-starou"); 08959 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08960 res = ast_play_and_wait(chan, "vm-stare"); 08961 if (vms->oldmessages > 4) 08962 res = ast_play_and_wait(chan, "vm-starych"); 08963 } 08964 if (!res) { 08965 if ((vms->oldmessages == 1)) 08966 res = ast_play_and_wait(chan, "vm-zpravu"); 08967 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08968 res = ast_play_and_wait(chan, "vm-zpravy"); 08969 if (vms->oldmessages > 4) 08970 res = ast_play_and_wait(chan, "vm-zprav"); 08971 } 08972 } 08973 if (!res) { 08974 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08975 res = ast_play_and_wait(chan, "vm-no"); 08976 if (!res) 08977 res = ast_play_and_wait(chan, "vm-zpravy"); 08978 } 08979 } 08980 } 08981 return res; 08982 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8620 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08621 { 08622 /* Introduce messages they have */ 08623 int res; 08624 res = ast_play_and_wait(chan, "vm-youhave"); 08625 if (!res) { 08626 if (vms->newmessages) { 08627 if ((vms->newmessages == 1)) 08628 res = ast_play_and_wait(chan, "digits/1F"); 08629 else 08630 res = say_and_wait(chan, vms->newmessages, chan->language); 08631 if (!res) 08632 res = ast_play_and_wait(chan, "vm-INBOX"); 08633 if (vms->oldmessages && !res) 08634 res = ast_play_and_wait(chan, "vm-and"); 08635 else if (!res) { 08636 if ((vms->newmessages == 1)) 08637 res = ast_play_and_wait(chan, "vm-message"); 08638 else 08639 res = ast_play_and_wait(chan, "vm-messages"); 08640 } 08641 08642 } 08643 if (!res && vms->oldmessages) { 08644 if (vms->oldmessages == 1) 08645 res = ast_play_and_wait(chan, "digits/1F"); 08646 else 08647 res = say_and_wait(chan, vms->oldmessages, chan->language); 08648 if (!res) 08649 res = ast_play_and_wait(chan, "vm-Old"); 08650 if (!res) { 08651 if (vms->oldmessages == 1) 08652 res = ast_play_and_wait(chan, "vm-message"); 08653 else 08654 res = ast_play_and_wait(chan, "vm-messages"); 08655 } 08656 } 08657 if (!res) { 08658 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08659 res = ast_play_and_wait(chan, "vm-no"); 08660 if (!res) 08661 res = ast_play_and_wait(chan, "vm-messages"); 08662 } 08663 } 08664 } 08665 return res; 08666 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8369 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08370 { 08371 int res; 08372 08373 /* Introduce messages they have */ 08374 res = ast_play_and_wait(chan, "vm-youhave"); 08375 if (!res) { 08376 if (vms->urgentmessages) { 08377 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08378 if (!res) 08379 res = ast_play_and_wait(chan, "vm-Urgent"); 08380 if ((vms->oldmessages || vms->newmessages) && !res) { 08381 res = ast_play_and_wait(chan, "vm-and"); 08382 } else if (!res) { 08383 if ((vms->urgentmessages == 1)) 08384 res = ast_play_and_wait(chan, "vm-message"); 08385 else 08386 res = ast_play_and_wait(chan, "vm-messages"); 08387 } 08388 } 08389 if (vms->newmessages) { 08390 res = say_and_wait(chan, vms->newmessages, chan->language); 08391 if (!res) 08392 res = ast_play_and_wait(chan, "vm-INBOX"); 08393 if (vms->oldmessages && !res) 08394 res = ast_play_and_wait(chan, "vm-and"); 08395 else if (!res) { 08396 if ((vms->newmessages == 1)) 08397 res = ast_play_and_wait(chan, "vm-message"); 08398 else 08399 res = ast_play_and_wait(chan, "vm-messages"); 08400 } 08401 08402 } 08403 if (!res && vms->oldmessages) { 08404 res = say_and_wait(chan, vms->oldmessages, chan->language); 08405 if (!res) 08406 res = ast_play_and_wait(chan, "vm-Old"); 08407 if (!res) { 08408 if (vms->oldmessages == 1) 08409 res = ast_play_and_wait(chan, "vm-message"); 08410 else 08411 res = ast_play_and_wait(chan, "vm-messages"); 08412 } 08413 } 08414 if (!res) { 08415 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08416 res = ast_play_and_wait(chan, "vm-no"); 08417 if (!res) 08418 res = ast_play_and_wait(chan, "vm-messages"); 08419 } 08420 } 08421 } 08422 return res; 08423 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8669 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08670 { 08671 /* Introduce messages they have */ 08672 int res; 08673 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08674 res = ast_play_and_wait(chan, "vm-youhaveno"); 08675 if (!res) 08676 res = ast_play_and_wait(chan, "vm-messages"); 08677 } else { 08678 res = ast_play_and_wait(chan, "vm-youhave"); 08679 } 08680 if (!res) { 08681 if (vms->newmessages) { 08682 if (!res) { 08683 if ((vms->newmessages == 1)) { 08684 res = ast_play_and_wait(chan, "digits/1M"); 08685 if (!res) 08686 res = ast_play_and_wait(chan, "vm-message"); 08687 if (!res) 08688 res = ast_play_and_wait(chan, "vm-INBOXs"); 08689 } else { 08690 res = say_and_wait(chan, vms->newmessages, chan->language); 08691 if (!res) 08692 res = ast_play_and_wait(chan, "vm-messages"); 08693 if (!res) 08694 res = ast_play_and_wait(chan, "vm-INBOX"); 08695 } 08696 } 08697 if (vms->oldmessages && !res) 08698 res = ast_play_and_wait(chan, "vm-and"); 08699 } 08700 if (vms->oldmessages) { 08701 if (!res) { 08702 if (vms->oldmessages == 1) { 08703 res = ast_play_and_wait(chan, "digits/1M"); 08704 if (!res) 08705 res = ast_play_and_wait(chan, "vm-message"); 08706 if (!res) 08707 res = ast_play_and_wait(chan, "vm-Olds"); 08708 } else { 08709 res = say_and_wait(chan, vms->oldmessages, chan->language); 08710 if (!res) 08711 res = ast_play_and_wait(chan, "vm-messages"); 08712 if (!res) 08713 res = ast_play_and_wait(chan, "vm-Old"); 08714 } 08715 } 08716 } 08717 } 08718 return res; 08719 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8767 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08768 { 08769 /* Introduce messages they have */ 08770 int res; 08771 res = ast_play_and_wait(chan, "vm-youhave"); 08772 if (!res) { 08773 if (vms->newmessages) { 08774 res = say_and_wait(chan, vms->newmessages, chan->language); 08775 if (!res) 08776 res = ast_play_and_wait(chan, "vm-INBOX"); 08777 if (vms->oldmessages && !res) 08778 res = ast_play_and_wait(chan, "vm-and"); 08779 else if (!res) { 08780 if ((vms->newmessages == 1)) 08781 res = ast_play_and_wait(chan, "vm-message"); 08782 else 08783 res = ast_play_and_wait(chan, "vm-messages"); 08784 } 08785 08786 } 08787 if (!res && vms->oldmessages) { 08788 res = say_and_wait(chan, vms->oldmessages, chan->language); 08789 if (!res) 08790 res = ast_play_and_wait(chan, "vm-Old"); 08791 if (!res) { 08792 if (vms->oldmessages == 1) 08793 res = ast_play_and_wait(chan, "vm-message"); 08794 else 08795 res = ast_play_and_wait(chan, "vm-messages"); 08796 } 08797 } 08798 if (!res) { 08799 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08800 res = ast_play_and_wait(chan, "vm-no"); 08801 if (!res) 08802 res = ast_play_and_wait(chan, "vm-messages"); 08803 } 08804 } 08805 } 08806 return res; 08807 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8168 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08169 { 08170 int res = 0; 08171 08172 if (vms->newmessages) { 08173 res = ast_play_and_wait(chan, "vm-youhave"); 08174 if (!res) 08175 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08176 if (!res) { 08177 if ((vms->newmessages == 1)) { 08178 res = ast_play_and_wait(chan, "vm-INBOX"); 08179 if (!res) 08180 res = ast_play_and_wait(chan, "vm-message"); 08181 } else { 08182 res = ast_play_and_wait(chan, "vm-INBOXs"); 08183 if (!res) 08184 res = ast_play_and_wait(chan, "vm-messages"); 08185 } 08186 } 08187 } else if (vms->oldmessages){ 08188 res = ast_play_and_wait(chan, "vm-youhave"); 08189 if (!res) 08190 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08191 if ((vms->oldmessages == 1)){ 08192 res = ast_play_and_wait(chan, "vm-Old"); 08193 if (!res) 08194 res = ast_play_and_wait(chan, "vm-message"); 08195 } else { 08196 res = ast_play_and_wait(chan, "vm-Olds"); 08197 if (!res) 08198 res = ast_play_and_wait(chan, "vm-messages"); 08199 } 08200 } else if (!vms->oldmessages && !vms->newmessages) 08201 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08202 return res; 08203 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8302 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08303 { 08304 int res = 0; 08305 08306 /* Introduce messages they have */ 08307 if (!res) { 08308 if ((vms->newmessages) || (vms->oldmessages)) { 08309 res = ast_play_and_wait(chan, "vm-youhave"); 08310 } 08311 /* 08312 * The word "shtei" refers to the number 2 in hebrew when performing a count 08313 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08314 * an element, this is one of them. 08315 */ 08316 if (vms->newmessages) { 08317 if (!res) { 08318 if (vms->newmessages == 1) { 08319 res = ast_play_and_wait(chan, "vm-INBOX1"); 08320 } else { 08321 if (vms->newmessages == 2) { 08322 res = ast_play_and_wait(chan, "vm-shtei"); 08323 } else { 08324 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08325 } 08326 res = ast_play_and_wait(chan, "vm-INBOX"); 08327 } 08328 } 08329 if (vms->oldmessages && !res) { 08330 res = ast_play_and_wait(chan, "vm-and"); 08331 if (vms->oldmessages == 1) { 08332 res = ast_play_and_wait(chan, "vm-Old1"); 08333 } else { 08334 if (vms->oldmessages == 2) { 08335 res = ast_play_and_wait(chan, "vm-shtei"); 08336 } else { 08337 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08338 } 08339 res = ast_play_and_wait(chan, "vm-Old"); 08340 } 08341 } 08342 } 08343 if (!res && vms->oldmessages && !vms->newmessages) { 08344 if (!res) { 08345 if (vms->oldmessages == 1) { 08346 res = ast_play_and_wait(chan, "vm-Old1"); 08347 } else { 08348 if (vms->oldmessages == 2) { 08349 res = ast_play_and_wait(chan, "vm-shtei"); 08350 } else { 08351 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08352 } 08353 res = ast_play_and_wait(chan, "vm-Old"); 08354 } 08355 } 08356 } 08357 if (!res) { 08358 if (!vms->oldmessages && !vms->newmessages) { 08359 if (!res) { 08360 res = ast_play_and_wait(chan, "vm-nomessages"); 08361 } 08362 } 08363 } 08364 } 08365 return res; 08366 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8426 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08427 { 08428 /* Introduce messages they have */ 08429 int res; 08430 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08431 res = ast_play_and_wait(chan, "vm-no") || 08432 ast_play_and_wait(chan, "vm-message"); 08433 else 08434 res = ast_play_and_wait(chan, "vm-youhave"); 08435 if (!res && vms->newmessages) { 08436 res = (vms->newmessages == 1) ? 08437 ast_play_and_wait(chan, "digits/un") || 08438 ast_play_and_wait(chan, "vm-nuovo") || 08439 ast_play_and_wait(chan, "vm-message") : 08440 /* 2 or more new messages */ 08441 say_and_wait(chan, vms->newmessages, chan->language) || 08442 ast_play_and_wait(chan, "vm-nuovi") || 08443 ast_play_and_wait(chan, "vm-messages"); 08444 if (!res && vms->oldmessages) 08445 res = ast_play_and_wait(chan, "vm-and"); 08446 } 08447 if (!res && vms->oldmessages) { 08448 res = (vms->oldmessages == 1) ? 08449 ast_play_and_wait(chan, "digits/un") || 08450 ast_play_and_wait(chan, "vm-vecchio") || 08451 ast_play_and_wait(chan, "vm-message") : 08452 /* 2 or more old messages */ 08453 say_and_wait(chan, vms->oldmessages, chan->language) || 08454 ast_play_and_wait(chan, "vm-vecchi") || 08455 ast_play_and_wait(chan, "vm-messages"); 08456 } 08457 return res; 08458 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8262 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08263 { 08264 int res; 08265 int lastnum = 0; 08266 08267 res = ast_play_and_wait(chan, "vm-youhave"); 08268 08269 if (!res && vms->newmessages) { 08270 lastnum = vms->newmessages; 08271 08272 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08273 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08274 } 08275 08276 if (!res && vms->oldmessages) { 08277 res = ast_play_and_wait(chan, "vm-and"); 08278 } 08279 } 08280 08281 if (!res && vms->oldmessages) { 08282 lastnum = vms->oldmessages; 08283 08284 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08285 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08286 } 08287 } 08288 08289 if (!res) { 08290 if (lastnum == 0) { 08291 res = ast_play_and_wait(chan, "vm-no"); 08292 } 08293 if (!res) { 08294 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08295 } 08296 } 08297 08298 return res; 08299 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8810 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08811 { 08812 /* Introduce messages they have */ 08813 int res; 08814 res = ast_play_and_wait(chan, "vm-youhave"); 08815 if (!res) { 08816 if (vms->newmessages) { 08817 res = say_and_wait(chan, vms->newmessages, chan->language); 08818 if (!res) { 08819 if (vms->newmessages == 1) 08820 res = ast_play_and_wait(chan, "vm-INBOXs"); 08821 else 08822 res = ast_play_and_wait(chan, "vm-INBOX"); 08823 } 08824 if (vms->oldmessages && !res) 08825 res = ast_play_and_wait(chan, "vm-and"); 08826 else if (!res) { 08827 if ((vms->newmessages == 1)) 08828 res = ast_play_and_wait(chan, "vm-message"); 08829 else 08830 res = ast_play_and_wait(chan, "vm-messages"); 08831 } 08832 08833 } 08834 if (!res && vms->oldmessages) { 08835 res = say_and_wait(chan, vms->oldmessages, chan->language); 08836 if (!res) { 08837 if (vms->oldmessages == 1) 08838 res = ast_play_and_wait(chan, "vm-Olds"); 08839 else 08840 res = ast_play_and_wait(chan, "vm-Old"); 08841 } 08842 if (!res) { 08843 if (vms->oldmessages == 1) 08844 res = ast_play_and_wait(chan, "vm-message"); 08845 else 08846 res = ast_play_and_wait(chan, "vm-messages"); 08847 } 08848 } 08849 if (!res) { 08850 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08851 res = ast_play_and_wait(chan, "vm-no"); 08852 if (!res) 08853 res = ast_play_and_wait(chan, "vm-messages"); 08854 } 08855 } 08856 } 08857 return res; 08858 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8576 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08577 { 08578 /* Introduce messages they have */ 08579 int res; 08580 08581 res = ast_play_and_wait(chan, "vm-youhave"); 08582 if (res) 08583 return res; 08584 08585 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08586 res = ast_play_and_wait(chan, "vm-no"); 08587 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08588 return res; 08589 } 08590 08591 if (vms->newmessages) { 08592 if ((vms->newmessages == 1)) { 08593 res = ast_play_and_wait(chan, "digits/1"); 08594 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08595 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08596 } else { 08597 res = say_and_wait(chan, vms->newmessages, chan->language); 08598 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08599 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08600 } 08601 if (!res && vms->oldmessages) 08602 res = ast_play_and_wait(chan, "vm-and"); 08603 } 08604 if (!res && vms->oldmessages) { 08605 if (vms->oldmessages == 1) { 08606 res = ast_play_and_wait(chan, "digits/1"); 08607 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08608 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08609 } else { 08610 res = say_and_wait(chan, vms->oldmessages, chan->language); 08611 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08612 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08613 } 08614 } 08615 08616 return res; 08617 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8461 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08462 { 08463 /* Introduce messages they have */ 08464 int res; 08465 div_t num; 08466 08467 if (!vms->oldmessages && !vms->newmessages) { 08468 res = ast_play_and_wait(chan, "vm-no"); 08469 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08470 return res; 08471 } else { 08472 res = ast_play_and_wait(chan, "vm-youhave"); 08473 } 08474 08475 if (vms->newmessages) { 08476 num = div(vms->newmessages, 10); 08477 if (vms->newmessages == 1) { 08478 res = ast_play_and_wait(chan, "digits/1-a"); 08479 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08480 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08481 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08482 if (num.rem == 2) { 08483 if (!num.quot) { 08484 res = ast_play_and_wait(chan, "digits/2-ie"); 08485 } else { 08486 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08487 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08488 } 08489 } else { 08490 res = say_and_wait(chan, vms->newmessages, chan->language); 08491 } 08492 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08493 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08494 } else { 08495 res = say_and_wait(chan, vms->newmessages, chan->language); 08496 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08497 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08498 } 08499 if (!res && vms->oldmessages) 08500 res = ast_play_and_wait(chan, "vm-and"); 08501 } 08502 if (!res && vms->oldmessages) { 08503 num = div(vms->oldmessages, 10); 08504 if (vms->oldmessages == 1) { 08505 res = ast_play_and_wait(chan, "digits/1-a"); 08506 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08507 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08508 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08509 if (num.rem == 2) { 08510 if (!num.quot) { 08511 res = ast_play_and_wait(chan, "digits/2-ie"); 08512 } else { 08513 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08514 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08515 } 08516 } else { 08517 res = say_and_wait(chan, vms->oldmessages, chan->language); 08518 } 08519 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08520 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08521 } else { 08522 res = say_and_wait(chan, vms->oldmessages, chan->language); 08523 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08524 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08525 } 08526 } 08527 08528 return res; 08529 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8861 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08862 { 08863 /* Introduce messages they have */ 08864 int res; 08865 res = ast_play_and_wait(chan, "vm-youhave"); 08866 if (!res) { 08867 if (vms->newmessages) { 08868 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08869 if (!res) { 08870 if ((vms->newmessages == 1)) { 08871 res = ast_play_and_wait(chan, "vm-message"); 08872 if (!res) 08873 res = ast_play_and_wait(chan, "vm-INBOXs"); 08874 } else { 08875 res = ast_play_and_wait(chan, "vm-messages"); 08876 if (!res) 08877 res = ast_play_and_wait(chan, "vm-INBOX"); 08878 } 08879 } 08880 if (vms->oldmessages && !res) 08881 res = ast_play_and_wait(chan, "vm-and"); 08882 } 08883 if (!res && vms->oldmessages) { 08884 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08885 if (!res) { 08886 if (vms->oldmessages == 1) { 08887 res = ast_play_and_wait(chan, "vm-message"); 08888 if (!res) 08889 res = ast_play_and_wait(chan, "vm-Olds"); 08890 } else { 08891 res = ast_play_and_wait(chan, "vm-messages"); 08892 if (!res) 08893 res = ast_play_and_wait(chan, "vm-Old"); 08894 } 08895 } 08896 } 08897 if (!res) { 08898 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08899 res = ast_play_and_wait(chan, "vm-no"); 08900 if (!res) 08901 res = ast_play_and_wait(chan, "vm-messages"); 08902 } 08903 } 08904 } 08905 return res; 08906 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8722 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08722 { 08723 /* Introduce messages they have */ 08724 int res; 08725 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08726 res = ast_play_and_wait(chan, "vm-nomessages"); 08727 return res; 08728 } else { 08729 res = ast_play_and_wait(chan, "vm-youhave"); 08730 } 08731 if (vms->newmessages) { 08732 if (!res) 08733 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08734 if ((vms->newmessages == 1)) { 08735 if (!res) 08736 res = ast_play_and_wait(chan, "vm-message"); 08737 if (!res) 08738 res = ast_play_and_wait(chan, "vm-INBOXs"); 08739 } else { 08740 if (!res) 08741 res = ast_play_and_wait(chan, "vm-messages"); 08742 if (!res) 08743 res = ast_play_and_wait(chan, "vm-INBOX"); 08744 } 08745 if (vms->oldmessages && !res) 08746 res = ast_play_and_wait(chan, "vm-and"); 08747 } 08748 if (vms->oldmessages) { 08749 if (!res) 08750 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08751 if (vms->oldmessages == 1) { 08752 if (!res) 08753 res = ast_play_and_wait(chan, "vm-message"); 08754 if (!res) 08755 res = ast_play_and_wait(chan, "vm-Olds"); 08756 } else { 08757 if (!res) 08758 res = ast_play_and_wait(chan, "vm-messages"); 08759 if (!res) 08760 res = ast_play_and_wait(chan, "vm-Old"); 08761 } 08762 } 08763 return res; 08764 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8532 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08533 { 08534 /* Introduce messages they have */ 08535 int res; 08536 08537 res = ast_play_and_wait(chan, "vm-youhave"); 08538 if (res) 08539 return res; 08540 08541 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08542 res = ast_play_and_wait(chan, "vm-no"); 08543 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08544 return res; 08545 } 08546 08547 if (vms->newmessages) { 08548 if ((vms->newmessages == 1)) { 08549 res = ast_play_and_wait(chan, "digits/ett"); 08550 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08551 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08552 } else { 08553 res = say_and_wait(chan, vms->newmessages, chan->language); 08554 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08555 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08556 } 08557 if (!res && vms->oldmessages) 08558 res = ast_play_and_wait(chan, "vm-and"); 08559 } 08560 if (!res && vms->oldmessages) { 08561 if (vms->oldmessages == 1) { 08562 res = ast_play_and_wait(chan, "digits/ett"); 08563 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08564 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08565 } else { 08566 res = say_and_wait(chan, vms->oldmessages, chan->language); 08567 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08568 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08569 } 08570 } 08571 08572 return res; 08573 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9024 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09025 { 09026 int res; 09027 09028 /* Introduce messages they have */ 09029 res = ast_play_and_wait(chan, "vm-youhave"); 09030 if (!res) { 09031 if (vms->newmessages) { 09032 res = say_and_wait(chan, vms->newmessages, chan->language); 09033 if (!res) 09034 res = ast_play_and_wait(chan, "vm-INBOX"); 09035 if (vms->oldmessages && !res) 09036 res = ast_play_and_wait(chan, "vm-and"); 09037 } 09038 if (!res && vms->oldmessages) { 09039 res = say_and_wait(chan, vms->oldmessages, chan->language); 09040 if (!res) 09041 res = ast_play_and_wait(chan, "vm-Old"); 09042 } 09043 if (!res) { 09044 if (!vms->oldmessages && !vms->newmessages) { 09045 res = ast_play_and_wait(chan, "vm-no"); 09046 if (!res) 09047 res = ast_play_and_wait(chan, "vm-message"); 09048 } 09049 } 09050 } 09051 return res; 09052 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8985 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08986 { 08987 int res; 08988 /* Introduce messages they have */ 08989 res = ast_play_and_wait(chan, "vm-you"); 08990 08991 if (!res && vms->newmessages) { 08992 res = ast_play_and_wait(chan, "vm-have"); 08993 if (!res) 08994 res = say_and_wait(chan, vms->newmessages, chan->language); 08995 if (!res) 08996 res = ast_play_and_wait(chan, "vm-tong"); 08997 if (!res) 08998 res = ast_play_and_wait(chan, "vm-INBOX"); 08999 if (vms->oldmessages && !res) 09000 res = ast_play_and_wait(chan, "vm-and"); 09001 else if (!res) 09002 res = ast_play_and_wait(chan, "vm-messages"); 09003 } 09004 if (!res && vms->oldmessages) { 09005 res = ast_play_and_wait(chan, "vm-have"); 09006 if (!res) 09007 res = say_and_wait(chan, vms->oldmessages, chan->language); 09008 if (!res) 09009 res = ast_play_and_wait(chan, "vm-tong"); 09010 if (!res) 09011 res = ast_play_and_wait(chan, "vm-Old"); 09012 if (!res) 09013 res = ast_play_and_wait(chan, "vm-messages"); 09014 } 09015 if (!res && !vms->oldmessages && !vms->newmessages) { 09016 res = ast_play_and_wait(chan, "vm-haveno"); 09017 if (!res) 09018 res = ast_play_and_wait(chan, "vm-messages"); 09019 } 09020 return res; 09021 }
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 3270 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by close_mailbox(), copy_message(), count_messages(), leave_voicemail(), open_mailbox(), resequence_mailbox(), and save_to_folder().
03271 { 03272 switch (ast_lock_path(path)) { 03273 case AST_LOCK_TIMEOUT: 03274 return -1; 03275 default: 03276 return 0; 03277 } 03278 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1661 of file app_voicemail.c.
References my_umask, and VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01662 { 01663 FILE *p = NULL; 01664 int pfd = mkstemp(template); 01665 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01666 if (pfd > -1) { 01667 p = fdopen(pfd, "w+"); 01668 if (!p) { 01669 close(pfd); 01670 pfd = -1; 01671 } 01672 } 01673 return p; 01674 }
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 9238 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().
09239 { 09240 int cmd = 0; 09241 int duration = 0; 09242 int tries = 0; 09243 char newpassword[80] = ""; 09244 char newpassword2[80] = ""; 09245 char prefile[PATH_MAX] = ""; 09246 unsigned char buf[256]; 09247 int bytes = 0; 09248 09249 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09250 if (ast_adsi_available(chan)) { 09251 bytes += adsi_logo(buf + bytes); 09252 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09253 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09254 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09255 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09256 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09257 } 09258 09259 /* If forcename is set, have the user record their name */ 09260 if (ast_test_flag(vmu, VM_FORCENAME)) { 09261 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09262 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09263 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09264 if (cmd < 0 || cmd == 't' || cmd == '#') 09265 return cmd; 09266 } 09267 } 09268 09269 /* If forcegreetings is set, have the user record their greetings */ 09270 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09271 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09272 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09273 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09274 if (cmd < 0 || cmd == 't' || cmd == '#') 09275 return cmd; 09276 } 09277 09278 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09279 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09280 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09281 if (cmd < 0 || cmd == 't' || cmd == '#') 09282 return cmd; 09283 } 09284 } 09285 09286 /* 09287 * Change the password last since new users will be able to skip over any steps this one comes before 09288 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09289 */ 09290 for (;;) { 09291 newpassword[1] = '\0'; 09292 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09293 if (cmd == '#') 09294 newpassword[0] = '\0'; 09295 if (cmd < 0 || cmd == 't' || cmd == '#') 09296 return cmd; 09297 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09298 if (cmd < 0 || cmd == 't' || cmd == '#') 09299 return cmd; 09300 cmd = check_password(vmu, newpassword); /* perform password validation */ 09301 if (cmd != 0) { 09302 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09303 cmd = ast_play_and_wait(chan, vm_invalid_password); 09304 } else { 09305 newpassword2[1] = '\0'; 09306 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09307 if (cmd == '#') 09308 newpassword2[0] = '\0'; 09309 if (cmd < 0 || cmd == 't' || cmd == '#') 09310 return cmd; 09311 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09312 if (cmd < 0 || cmd == 't' || cmd == '#') 09313 return cmd; 09314 if (!strcmp(newpassword, newpassword2)) 09315 break; 09316 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09317 cmd = ast_play_and_wait(chan, vm_mismatch); 09318 } 09319 if (++tries == 3) 09320 return -1; 09321 if (cmd != 0) { 09322 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09323 } 09324 } 09325 if (pwdchange & PWDCHANGE_INTERNAL) 09326 vm_change_password(vmu, newpassword); 09327 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09328 vm_change_password_shell(vmu, newpassword); 09329 09330 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09331 cmd = ast_play_and_wait(chan, vm_passchanged); 09332 09333 return cmd; 09334 }
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 9336 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().
09337 { 09338 int cmd = 0; 09339 int retries = 0; 09340 int duration = 0; 09341 char newpassword[80] = ""; 09342 char newpassword2[80] = ""; 09343 char prefile[PATH_MAX] = ""; 09344 unsigned char buf[256]; 09345 int bytes = 0; 09346 09347 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09348 if (ast_adsi_available(chan)) { 09349 bytes += adsi_logo(buf + bytes); 09350 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09351 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09352 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09353 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09354 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09355 } 09356 while ((cmd >= 0) && (cmd != 't')) { 09357 if (cmd) 09358 retries = 0; 09359 switch (cmd) { 09360 case '1': /* Record your unavailable message */ 09361 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09362 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09363 break; 09364 case '2': /* Record your busy message */ 09365 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09366 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09367 break; 09368 case '3': /* Record greeting */ 09369 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09370 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09371 break; 09372 case '4': /* manage the temporary greeting */ 09373 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09374 break; 09375 case '5': /* change password */ 09376 if (vmu->password[0] == '-') { 09377 cmd = ast_play_and_wait(chan, "vm-no"); 09378 break; 09379 } 09380 newpassword[1] = '\0'; 09381 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09382 if (cmd == '#') 09383 newpassword[0] = '\0'; 09384 else { 09385 if (cmd < 0) 09386 break; 09387 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09388 break; 09389 } 09390 } 09391 cmd = check_password(vmu, newpassword); /* perform password validation */ 09392 if (cmd != 0) { 09393 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09394 cmd = ast_play_and_wait(chan, vm_invalid_password); 09395 if (!cmd) { 09396 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09397 } 09398 break; 09399 } 09400 newpassword2[1] = '\0'; 09401 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09402 if (cmd == '#') 09403 newpassword2[0] = '\0'; 09404 else { 09405 if (cmd < 0) 09406 break; 09407 09408 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09409 break; 09410 } 09411 } 09412 if (strcmp(newpassword, newpassword2)) { 09413 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09414 cmd = ast_play_and_wait(chan, vm_mismatch); 09415 if (!cmd) { 09416 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09417 } 09418 break; 09419 } 09420 09421 if (pwdchange & PWDCHANGE_INTERNAL) { 09422 vm_change_password(vmu, newpassword); 09423 } 09424 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09425 vm_change_password_shell(vmu, newpassword); 09426 } 09427 09428 ast_debug(1, "User %s set password to %s of length %d\n", 09429 vms->username, newpassword, (int) strlen(newpassword)); 09430 cmd = ast_play_and_wait(chan, vm_passchanged); 09431 break; 09432 case '*': 09433 cmd = 't'; 09434 break; 09435 default: 09436 cmd = 0; 09437 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09438 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09439 if (ast_fileexists(prefile, NULL, NULL)) { 09440 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09441 } 09442 DISPOSE(prefile, -1); 09443 if (!cmd) { 09444 cmd = ast_play_and_wait(chan, "vm-options"); 09445 } 09446 if (!cmd) { 09447 cmd = ast_waitfordigit(chan, 6000); 09448 } 09449 if (!cmd) { 09450 retries++; 09451 } 09452 if (retries > 3) { 09453 cmd = 't'; 09454 } 09455 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09456 } 09457 } 09458 if (cmd == 't') 09459 cmd = 0; 09460 return cmd; 09461 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8131 of file app_voicemail.c.
References ast_play_and_wait(), vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().
Referenced by get_folder(), vm_execmain(), vm_instructions_en(), and vm_instructions_zh().
08132 { 08133 int cmd; 08134 08135 if ( !strncasecmp(chan->language, "it", 2) || 08136 !strncasecmp(chan->language, "es", 2) || 08137 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08138 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08139 return cmd ? cmd : ast_play_and_wait(chan, box); 08140 } else if (!strncasecmp(chan->language, "gr", 2)) { 08141 return vm_play_folder_name_gr(chan, box); 08142 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08143 return ast_play_and_wait(chan, box); 08144 } else if (!strncasecmp(chan->language, "pl", 2)) { 08145 return vm_play_folder_name_pl(chan, box); 08146 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08147 return vm_play_folder_name_ua(chan, box); 08148 } else if (!strncasecmp(chan->language, "vi", 2)) { 08149 return ast_play_and_wait(chan, box); 08150 } else { /* Default English */ 08151 cmd = ast_play_and_wait(chan, box); 08152 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08153 } 08154 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8084 of file app_voicemail.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08085 { 08086 int cmd; 08087 char *buf; 08088 08089 buf = ast_alloca(strlen(box) + 2); 08090 strcpy(buf, box); 08091 strcat(buf, "s"); 08092 08093 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08094 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08095 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08096 } else { 08097 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08098 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08099 } 08100 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8102 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08103 { 08104 int cmd; 08105 08106 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08107 if (!strcasecmp(box, "vm-INBOX")) 08108 cmd = ast_play_and_wait(chan, "vm-new-e"); 08109 else 08110 cmd = ast_play_and_wait(chan, "vm-old-e"); 08111 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08112 } else { 08113 cmd = ast_play_and_wait(chan, "vm-messages"); 08114 return cmd ? cmd : ast_play_and_wait(chan, box); 08115 } 08116 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8118 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08119 { 08120 int cmd; 08121 08122 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08123 cmd = ast_play_and_wait(chan, "vm-messages"); 08124 return cmd ? cmd : ast_play_and_wait(chan, box); 08125 } else { 08126 cmd = ast_play_and_wait(chan, box); 08127 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08128 } 08129 }
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 9479 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().
09480 { 09481 int cmd = 0; 09482 int retries = 0; 09483 int duration = 0; 09484 char prefile[PATH_MAX] = ""; 09485 unsigned char buf[256]; 09486 int bytes = 0; 09487 09488 if (ast_adsi_available(chan)) { 09489 bytes += adsi_logo(buf + bytes); 09490 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09491 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09492 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09493 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09494 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09495 } 09496 09497 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09498 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09499 while ((cmd >= 0) && (cmd != 't')) { 09500 if (cmd) 09501 retries = 0; 09502 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09503 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09504 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09505 if (cmd == -1) { 09506 break; 09507 } 09508 cmd = 't'; 09509 } else { 09510 switch (cmd) { 09511 case '1': 09512 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09513 break; 09514 case '2': 09515 DELETE(prefile, -1, prefile, vmu); 09516 ast_play_and_wait(chan, "vm-tempremoved"); 09517 cmd = 't'; 09518 break; 09519 case '*': 09520 cmd = 't'; 09521 break; 09522 default: 09523 cmd = ast_play_and_wait(chan, 09524 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09525 "vm-tempgreeting2" : "vm-tempgreeting"); 09526 if (!cmd) { 09527 cmd = ast_waitfordigit(chan, 6000); 09528 } 09529 if (!cmd) { 09530 retries++; 09531 } 09532 if (retries > 3) { 09533 cmd = 't'; 09534 } 09535 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09536 } 09537 } 09538 DISPOSE(prefile, -1); 09539 } 09540 if (cmd == 't') 09541 cmd = 0; 09542 return cmd; 09543 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11431 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11433 { 11434 struct ast_vm_user *user; 11435 11436 AST_LIST_LOCK(&users); 11437 AST_LIST_TRAVERSE(&users, user, list) { 11438 vm_users_data_provider_get_helper(search, data_root, user); 11439 } 11440 AST_LIST_UNLOCK(&users); 11441 11442 return 0; 11443 }
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 11384 of file app_voicemail.c.
References ast_data_add_int(), ast_data_add_node(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, inboxcount2(), ast_vm_user::mailbox, and ast_vm_user::zonetag.
Referenced by vm_users_data_provider_get().
11386 { 11387 struct ast_data *data_user, *data_zone; 11388 struct ast_data *data_state; 11389 struct vm_zone *zone = NULL; 11390 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11391 char ext_context[256] = ""; 11392 11393 data_user = ast_data_add_node(data_root, "user"); 11394 if (!data_user) { 11395 return -1; 11396 } 11397 11398 ast_data_add_structure(ast_vm_user, data_user, user); 11399 11400 AST_LIST_LOCK(&zones); 11401 AST_LIST_TRAVERSE(&zones, zone, list) { 11402 if (!strcmp(zone->name, user->zonetag)) { 11403 break; 11404 } 11405 } 11406 AST_LIST_UNLOCK(&zones); 11407 11408 /* state */ 11409 data_state = ast_data_add_node(data_user, "state"); 11410 if (!data_state) { 11411 return -1; 11412 } 11413 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11414 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11415 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11416 ast_data_add_int(data_state, "newmsg", newmsg); 11417 ast_data_add_int(data_state, "oldmsg", oldmsg); 11418 11419 if (zone) { 11420 data_zone = ast_data_add_node(data_user, "zone"); 11421 ast_data_add_structure(vm_zone, data_zone, zone); 11422 } 11423 11424 if (!ast_data_search_match(search, data_user)) { 11425 ast_data_remove_node(data_root, data_user); 11426 } 11427 11428 return 0; 11429 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11070 of file app_voicemail.c.
References ast_copy_string(), ast_goto_if_exists(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_channel::context, ast_vm_user::context, pbx_builtin_setvar_helper(), and vm_authenticate().
Referenced by load_module().
11071 { 11072 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11073 struct ast_vm_user vmus; 11074 char *options = NULL; 11075 int silent = 0, skipuser = 0; 11076 int res = -1; 11077 11078 if (data) { 11079 s = ast_strdupa(data); 11080 user = strsep(&s, ","); 11081 options = strsep(&s, ","); 11082 if (user) { 11083 s = user; 11084 user = strsep(&s, "@"); 11085 context = strsep(&s, ""); 11086 if (!ast_strlen_zero(user)) 11087 skipuser++; 11088 ast_copy_string(mailbox, user, sizeof(mailbox)); 11089 } 11090 } 11091 11092 if (options) { 11093 silent = (strchr(options, 's')) != NULL; 11094 } 11095 11096 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11097 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11098 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11099 ast_play_and_wait(chan, "auth-thankyou"); 11100 res = 0; 11101 } else if (mailbox[0] == '*') { 11102 /* user entered '*' */ 11103 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11104 res = 0; /* prevent hangup */ 11105 } 11106 } 11107 11108 return res; 11109 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12610 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_log(), ast_say_character_str(), ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), LOG_WARNING, and sayname().
Referenced by load_module().
12611 { 12612 char *context; 12613 char *args_copy; 12614 int res; 12615 12616 if (ast_strlen_zero(data)) { 12617 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12618 return -1; 12619 } 12620 12621 args_copy = ast_strdupa(data); 12622 if ((context = strchr(args_copy, '@'))) { 12623 *context++ = '\0'; 12624 } else { 12625 context = "default"; 12626 } 12627 12628 if ((res = sayname(chan, args_copy, context) < 0)) { 12629 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12630 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12631 if (!res) { 12632 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12633 } 12634 } 12635 12636 return res; 12637 }
static struct ast_tm* vmu_tm | ( | const struct ast_vm_user * | vmu, | |
struct ast_tm * | tm | |||
) | [static, read] |
fill in *tm for current time according to the proper timezone, if any.
Definition at line 4427 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_tvnow(), and ast_vm_user::zonetag.
Referenced by make_email_file(), and sendpage().
04428 { 04429 const struct vm_zone *z = NULL; 04430 struct timeval t = ast_tvnow(); 04431 04432 /* Does this user have a timezone specified? */ 04433 if (!ast_strlen_zero(vmu->zonetag)) { 04434 /* Find the zone in the list */ 04435 AST_LIST_LOCK(&zones); 04436 AST_LIST_TRAVERSE(&zones, z, list) { 04437 if (!strcmp(z->name, vmu->zonetag)) 04438 break; 04439 } 04440 AST_LIST_UNLOCK(&zones); 04441 } 04442 ast_localtime(&t, tm, z ? z->timezone : NULL); 04443 return tm; 04444 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7480 of file app_voicemail.c.
References ast_control_streamfile(), ast_test_suite_event_notify, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, and skipms.
Referenced by advanced_options(), and play_message().
07481 { 07482 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07483 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); 07484 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7472 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_log(), AST_LOG_WARNING, and ast_stream_and_wait().
Referenced by play_message(), play_message_callerid(), and play_message_duration().
07473 { 07474 int res; 07475 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07476 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07477 return res; 07478 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12577 of file app_voicemail.c.
References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), and LOG_ERROR.
Referenced by vm_change_password().
12577 { 12578 struct ast_config *conf; 12579 struct ast_category *cat; 12580 struct ast_variable *var; 12581 int res = -1; 12582 12583 if (!(conf = ast_config_new())) { 12584 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12585 return res; 12586 } 12587 if (!(cat = ast_category_new("general", "", 1))) { 12588 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12589 ast_config_destroy(conf); 12590 return res; 12591 } 12592 if (!(var = ast_variable_new("password", password, ""))) { 12593 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12594 ast_config_destroy(conf); 12595 ast_category_destroy(cat); 12596 return res; 12597 } 12598 ast_category_append(conf, cat); 12599 ast_variable_append(cat, var); 12600 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12601 res = 0; 12602 } else { 12603 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12604 } 12605 12606 ast_config_destroy(conf); 12607 return res; 12608 }
char* addesc = "Comedian Mail" [static] |
Definition at line 768 of file app_voicemail.c.
Referenced by adsi_load_vmail().
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 895 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 896 of file app_voicemail.c.
Referenced by actual_load_config(), and adsi_load_vmail().
int adsiver = 1 [static] |
Definition at line 897 of file app_voicemail.c.
Referenced by actual_load_config(), adsi_begin(), and adsi_load_vmail().
char* app = "VoiceMail" [static] |
Definition at line 771 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app2 = "VoiceMailMain" [static] |
Definition at line 774 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app3 = "MailboxExists" [static] |
Definition at line 776 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* app4 = "VMAuthenticate" [static] |
Definition at line 777 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 881 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 893 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 884 of file app_voicemail.c.
Referenced by actual_load_config(), and play_message_callerid().
struct ast_cli_entry cli_voicemail[] [static] |
{ AST_CLI_DEFINE(handle_voicemail_show_users, "List defined voicemail boxes"), AST_CLI_DEFINE(handle_voicemail_show_zones, "List zone message formats"), AST_CLI_DEFINE(handle_voicemail_reload, "Reload voicemail configuration"), }
Definition at line 11309 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 880 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 887 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 898 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 888 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 882 of file app_voicemail.c.
Referenced by actual_load_config(), common_exec(), conf_run(), and populate_defaults().
char ext_pass_check_cmd[128] [static] |
Definition at line 748 of file app_voicemail.c.
Referenced by actual_load_config(), and check_password().
char ext_pass_cmd[128] [static] |
Definition at line 747 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 791 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char fromstring[100] [static] |
Definition at line 891 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
struct ast_flags globalflags = {0} [static] |
Definition at line 876 of file app_voicemail.c.
Referenced by actual_load_config(), find_or_create(), find_user(), find_user_realtime(), forward_message(), make_email_file(), populate_defaults(), sendmail(), and vm_execmain().
struct ao2_container* inprocess_container |
Definition at line 920 of file app_voicemail.c.
Referenced by inprocess_count(), load_module(), and unload_module().
char listen_control_forward_key[12] [static] |
Definition at line 849 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_pause_key[12] [static] |
Definition at line 851 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_restart_key[12] [static] |
Definition at line 852 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_reverse_key[12] [static] |
Definition at line 850 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char listen_control_stop_key[12] [static] |
Definition at line 853 of file app_voicemail.c.
Referenced by actual_load_config(), and wait_file().
char locale[20] [static] |
Definition at line 784 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
struct ast_custom_function mailbox_exists_acf [static] |
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11065 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
const char* const mailbox_folders[] [static] |
Definition at line 1697 of file app_voicemail.c.
Referenced by get_folder_by_name(), and mbox().
char mailcmd[160] [static] |
Definition at line 790 of file app_voicemail.c.
Referenced by actual_load_config(), manager_list_voicemail_users(), sendmail(), and sendpage().
int maxdeletedmsg [static] |
Definition at line 787 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
int maxgreet [static] |
Definition at line 797 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), vm_options(), and vm_tempgreeting().
int maxlogins [static] |
Definition at line 799 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_execmain().
int maxmsg [static] |
Definition at line 786 of file app_voicemail.c.
Referenced by actual_load_config(), copy_message(), and populate_defaults().
int maxsilence [static] |
Definition at line 785 of file app_voicemail.c.
Referenced by actual_load_config(), ast_record_review(), play_record_review(), and vm_forwardoptions().
int minpassword [static] |
Definition at line 800 of file app_voicemail.c.
Referenced by actual_load_config(), and check_password().
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 818 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 844 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 820 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
int my_umask [static] |
Definition at line 750 of file app_voicemail.c.
Referenced by add_email_attachment(), leave_voicemail(), load_module(), and vm_mkftemp().
char* pagerbody = NULL [static] |
Definition at line 889 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 899 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char pagerfromstring[100] [static] |
Definition at line 892 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
char* pagersubject = NULL [static] |
Definition at line 890 of file app_voicemail.c.
Referenced by actual_load_config(), and sendpage().
int passwordlocation [static] |
Definition at line 801 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 813 of file app_voicemail.c.
Referenced by mb_poll_thread(), and stop_poll_thread().
unsigned int poll_freq [static] |
Polling frequency
Definition at line 808 of file app_voicemail.c.
Referenced by actual_load_config(), and mb_poll_thread().
unsigned int poll_mailboxes [static] |
Poll mailboxes for changes since there is something external to app_voicemail that may change them.
Definition at line 805 of file app_voicemail.c.
Referenced by actual_load_config().
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 814 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 815 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 754 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
int saydurationminfo [static] |
Definition at line 878 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char* sayname_app = "VMSayName" [static] |
Definition at line 779 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char serveremail[80] [static] |
Definition at line 789 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), manager_list_voicemail_users(), and notify_new_message().
int silencethreshold = 128 [static] |
Definition at line 788 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 798 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 792 of file app_voicemail.c.
Referenced by actual_load_config(), and run_externnotify().
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 766 of file app_voicemail.c.
Referenced by actual_load_config().
struct ast_data_entry vm_data_providers[] [static] |
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 861 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 860 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 857 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 858 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 856 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 862 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 874 of file app_voicemail.c.
Referenced by actual_load_config(), and vm_forwardoptions().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 859 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 745 of file app_voicemail.c.
Referenced by __has_voicemail(), actual_load_config(), append_mailbox(), forward_message(), invent_message(), leave_voicemail(), load_module(), make_dir(), notify_new_message(), play_message_callerid(), sayname(), vm_change_password(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
struct ast_data_handler vm_users_data_provider [static] |
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11445 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 793 of file app_voicemail.c.
Referenced by actual_load_config(), forward_message(), leave_voicemail(), and vm_execmain().
int vmmaxsecs [static] |
Definition at line 796 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and populate_defaults().
int vmminsecs [static] |
Definition at line 795 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and populate_defaults().
double volgain [static] |
Definition at line 794 of file app_voicemail.c.
Referenced by actual_load_config(), and populate_defaults().
char zonetag[80] [static] |
Definition at line 783 of file app_voicemail.c.
Referenced by actual_load_config(), build_peer(), and populate_defaults().