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_imapstorage.c.
#define ASTERISK_USERNAME "asterisk" |
Definition at line 438 of file app_voicemail_imapstorage.c.
#define BASELINELEN 72 |
Definition at line 461 of file app_voicemail_imapstorage.c.
#define BASEMAXINLINE 256 |
Definition at line 462 of file app_voicemail_imapstorage.c.
#define CHUNKSIZE 65536 |
Definition at line 435 of file app_voicemail_imapstorage.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 431 of file app_voicemail_imapstorage.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
Definition at line 748 of file app_voicemail_imapstorage.c.
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11351 of file app_voicemail_imapstorage.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 11378 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 443 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 445 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 446 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 444 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 447 of file app_voicemail_imapstorage.c.
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 818 of file app_voicemail_imapstorage.c.
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 749 of file app_voicemail_imapstorage.c.
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 744 of file app_voicemail_imapstorage.c.
#define ENDL "\n" |
Definition at line 466 of file app_voicemail_imapstorage.c.
#define ERROR_LOCK_PATH -100 |
Definition at line 491 of file app_voicemail_imapstorage.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 746 of file app_voicemail_imapstorage.c.
#define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define INTRO "vm-intro" |
Definition at line 454 of file app_voicemail_imapstorage.c.
#define MAX_DATETIME_FORMAT 512 |
Definition at line 469 of file app_voicemail_imapstorage.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 470 of file app_voicemail_imapstorage.c.
#define MAXMSG 100 |
Definition at line 456 of file app_voicemail_imapstorage.c.
#define MAXMSGLIMIT 9999 |
Definition at line 457 of file app_voicemail_imapstorage.c.
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 459 of file app_voicemail_imapstorage.c.
#define OPERATOR_EXIT 300 |
Definition at line 492 of file app_voicemail_imapstorage.c.
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 761 of file app_voicemail_imapstorage.c.
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 760 of file app_voicemail_imapstorage.c.
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 747 of file app_voicemail_imapstorage.c.
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 743 of file app_voicemail_imapstorage.c.
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 452 of file app_voicemail_imapstorage.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 429 of file app_voicemail_imapstorage.c.
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 745 of file app_voicemail_imapstorage.c.
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 770 of file app_voicemail_imapstorage.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 448 of file app_voicemail_imapstorage.c.
#define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 485 of file app_voicemail_imapstorage.c.
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 483 of file app_voicemail_imapstorage.c.
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 484 of file app_voicemail_imapstorage.c.
#define VM_DIRECFORWARD (1 << 10) |
Permit caller to use the Directory app for selecting to which mailbox to forward a VM
Definition at line 482 of file app_voicemail_imapstorage.c.
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 476 of file app_voicemail_imapstorage.c.
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 480 of file app_voicemail_imapstorage.c.
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 479 of file app_voicemail_imapstorage.c.
#define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 490 of file app_voicemail_imapstorage.c.
#define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 489 of file app_voicemail_imapstorage.c.
#define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 488 of file app_voicemail_imapstorage.c.
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 473 of file app_voicemail_imapstorage.c.
#define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 481 of file app_voicemail_imapstorage.c.
#define VM_REVIEW (1 << 0) |
After recording, permit the caller to review the recording before saving
Definition at line 472 of file app_voicemail_imapstorage.c.
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 474 of file app_voicemail_imapstorage.c.
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 477 of file app_voicemail_imapstorage.c.
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 486 of file app_voicemail_imapstorage.c.
#define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 478 of file app_voicemail_imapstorage.c.
#define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 475 of file app_voicemail_imapstorage.c.
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 487 of file app_voicemail_imapstorage.c.
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 685 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 437 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 433 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 434 of file app_voicemail_imapstorage.c.
enum vm_box |
Definition at line 495 of file app_voicemail_imapstorage.c.
00495 { 00496 NEW_FOLDER, 00497 OLD_FOLDER, 00498 WORK_FOLDER, 00499 FAMILY_FOLDER, 00500 FRIENDS_FOLDER, 00501 GREETINGS_FOLDER 00502 };
enum vm_option_args |
Definition at line 516 of file app_voicemail_imapstorage.c.
00516 { 00517 OPT_ARG_RECORDGAIN = 0, 00518 OPT_ARG_PLAYFOLDER = 1, 00519 OPT_ARG_DTMFEXIT = 2, 00520 /* This *must* be the last value in this enum! */ 00521 OPT_ARG_ARRAY_SIZE = 3, 00522 };
enum vm_option_flags |
Definition at line 504 of file app_voicemail_imapstorage.c.
00504 { 00505 OPT_SILENT = (1 << 0), 00506 OPT_BUSY_GREETING = (1 << 1), 00507 OPT_UNAVAIL_GREETING = (1 << 2), 00508 OPT_RECORDGAIN = (1 << 3), 00509 OPT_PREPEND_MAILBOX = (1 << 4), 00510 OPT_AUTOPLAY = (1 << 6), 00511 OPT_DTMFEXIT = (1 << 7), 00512 OPT_MESSAGE_Urgent = (1 << 8), 00513 OPT_MESSAGE_PRIORITY = (1 << 9) 00514 };
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 524 of file app_voicemail_imapstorage.c.
00524 { 00525 OPT_PWLOC_VOICEMAILCONF = 0, 00526 OPT_PWLOC_SPOOLDIR = 1, 00527 OPT_PWLOC_USERSCONF = 2, 00528 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5396 of file app_voicemail_imapstorage.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05397 { 05398 DIR *dir; 05399 struct dirent *de; 05400 char fn[256]; 05401 int ret = 0; 05402 05403 /* If no mailbox, return immediately */ 05404 if (ast_strlen_zero(mailbox)) 05405 return 0; 05406 05407 if (ast_strlen_zero(folder)) 05408 folder = "INBOX"; 05409 if (ast_strlen_zero(context)) 05410 context = "default"; 05411 05412 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05413 05414 if (!(dir = opendir(fn))) 05415 return 0; 05416 05417 while ((de = readdir(dir))) { 05418 if (!strncasecmp(de->d_name, "msg", 3)) { 05419 if (shortcircuit) { 05420 ret = 1; 05421 break; 05422 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05423 ret++; 05424 } 05425 } 05426 } 05427 05428 closedir(dir); 05429 05430 return ret; 05431 }
static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | args, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 11054 of file app_voicemail_imapstorage.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().
11055 { 11056 struct ast_vm_user svm; 11057 AST_DECLARE_APP_ARGS(arg, 11058 AST_APP_ARG(mbox); 11059 AST_APP_ARG(context); 11060 ); 11061 11062 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11063 11064 if (ast_strlen_zero(arg.mbox)) { 11065 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11066 return -1; 11067 } 11068 11069 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11070 return 0; 11071 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11888 of file app_voicemail_imapstorage.c.
References 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, 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, find_or_create(), free_vm_users(), free_vm_zones(), is_valid_dtmf(), ast_variable::lineno, LOG_ERROR, ast_vm_user::mailbox, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, ast_variable::name, ast_variable::next, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), SENDMAIL, start_poll_thread(), stop_poll_thread(), substitute_escapes(), THRESHOLD_SILENCE, ast_variable::value, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, and VM_TEMPGREETWARN.
Referenced by load_config().
11889 { 11890 struct ast_vm_user *current; 11891 char *cat; 11892 struct ast_variable *var; 11893 const char *val; 11894 char *q, *stringp, *tmp; 11895 int x; 11896 int tmpadsi[4]; 11897 char secretfn[PATH_MAX] = ""; 11898 11899 #ifdef IMAP_STORAGE 11900 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11901 #endif 11902 /* set audio control prompts */ 11903 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11904 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11905 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11906 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11907 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11908 11909 /* Free all the users structure */ 11910 free_vm_users(); 11911 11912 /* Free all the zones structure */ 11913 free_vm_zones(); 11914 11915 AST_LIST_LOCK(&users); 11916 11917 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11918 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11919 11920 if (cfg) { 11921 /* General settings */ 11922 11923 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11924 val = "default"; 11925 ast_copy_string(userscontext, val, sizeof(userscontext)); 11926 /* Attach voice message to mail message ? */ 11927 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11928 val = "yes"; 11929 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11930 11931 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11932 val = "no"; 11933 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11934 11935 volgain = 0.0; 11936 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11937 sscanf(val, "%30lf", &volgain); 11938 11939 #ifdef ODBC_STORAGE 11940 strcpy(odbc_database, "asterisk"); 11941 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11942 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11943 } 11944 strcpy(odbc_table, "voicemessages"); 11945 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11946 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11947 } 11948 #endif 11949 /* Mail command */ 11950 strcpy(mailcmd, SENDMAIL); 11951 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11952 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11953 11954 maxsilence = 0; 11955 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11956 maxsilence = atoi(val); 11957 if (maxsilence > 0) 11958 maxsilence *= 1000; 11959 } 11960 11961 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11962 maxmsg = MAXMSG; 11963 } else { 11964 maxmsg = atoi(val); 11965 if (maxmsg < 0) { 11966 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11967 maxmsg = MAXMSG; 11968 } else if (maxmsg > MAXMSGLIMIT) { 11969 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11970 maxmsg = MAXMSGLIMIT; 11971 } 11972 } 11973 11974 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11975 maxdeletedmsg = 0; 11976 } else { 11977 if (sscanf(val, "%30d", &x) == 1) 11978 maxdeletedmsg = x; 11979 else if (ast_true(val)) 11980 maxdeletedmsg = MAXMSG; 11981 else 11982 maxdeletedmsg = 0; 11983 11984 if (maxdeletedmsg < 0) { 11985 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11986 maxdeletedmsg = MAXMSG; 11987 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11988 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11989 maxdeletedmsg = MAXMSGLIMIT; 11990 } 11991 } 11992 11993 /* Load date format config for voicemail mail */ 11994 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11995 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11996 } 11997 11998 /* Load date format config for voicemail pager mail */ 11999 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 12000 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 12001 } 12002 12003 /* External password changing command */ 12004 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 12005 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12006 pwdchange = PWDCHANGE_EXTERNAL; 12007 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12008 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12009 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12010 } 12011 12012 /* External password validation command */ 12013 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12014 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12015 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12016 } 12017 12018 #ifdef IMAP_STORAGE 12019 /* IMAP server address */ 12020 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12021 ast_copy_string(imapserver, val, sizeof(imapserver)); 12022 } else { 12023 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12024 } 12025 /* IMAP server port */ 12026 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12027 ast_copy_string(imapport, val, sizeof(imapport)); 12028 } else { 12029 ast_copy_string(imapport, "143", sizeof(imapport)); 12030 } 12031 /* IMAP server flags */ 12032 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12033 ast_copy_string(imapflags, val, sizeof(imapflags)); 12034 } 12035 /* IMAP server master username */ 12036 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12037 ast_copy_string(authuser, val, sizeof(authuser)); 12038 } 12039 /* IMAP server master password */ 12040 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12041 ast_copy_string(authpassword, val, sizeof(authpassword)); 12042 } 12043 /* Expunge on exit */ 12044 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12045 if (ast_false(val)) 12046 expungeonhangup = 0; 12047 else 12048 expungeonhangup = 1; 12049 } else { 12050 expungeonhangup = 1; 12051 } 12052 /* IMAP voicemail folder */ 12053 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12054 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12055 } else { 12056 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12057 } 12058 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12059 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12060 } 12061 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12062 imapgreetings = ast_true(val); 12063 } else { 12064 imapgreetings = 0; 12065 } 12066 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12067 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12068 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12069 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12070 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12071 } else { 12072 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12073 } 12074 12075 /* There is some very unorthodox casting done here. This is due 12076 * to the way c-client handles the argument passed in. It expects a 12077 * void pointer and casts the pointer directly to a long without 12078 * first dereferencing it. */ 12079 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12080 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12081 } else { 12082 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12083 } 12084 12085 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12086 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12087 } else { 12088 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12089 } 12090 12091 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12092 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12093 } else { 12094 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12095 } 12096 12097 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12098 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12099 } else { 12100 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12101 } 12102 12103 /* Increment configuration version */ 12104 imapversion++; 12105 #endif 12106 /* External voicemail notify application */ 12107 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12108 ast_copy_string(externnotify, val, sizeof(externnotify)); 12109 ast_debug(1, "found externnotify: %s\n", externnotify); 12110 } else { 12111 externnotify[0] = '\0'; 12112 } 12113 12114 /* SMDI voicemail notification */ 12115 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12116 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12117 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12118 smdi_iface = ast_smdi_interface_find(val); 12119 } else { 12120 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12121 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12122 } 12123 if (!smdi_iface) { 12124 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12125 } 12126 } 12127 12128 /* Silence treshold */ 12129 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12130 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12131 silencethreshold = atoi(val); 12132 12133 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12134 val = ASTERISK_USERNAME; 12135 ast_copy_string(serveremail, val, sizeof(serveremail)); 12136 12137 vmmaxsecs = 0; 12138 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12139 if (sscanf(val, "%30d", &x) == 1) { 12140 vmmaxsecs = x; 12141 } else { 12142 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12143 } 12144 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12145 static int maxmessage_deprecate = 0; 12146 if (maxmessage_deprecate == 0) { 12147 maxmessage_deprecate = 1; 12148 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12149 } 12150 if (sscanf(val, "%30d", &x) == 1) { 12151 vmmaxsecs = x; 12152 } else { 12153 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12154 } 12155 } 12156 12157 vmminsecs = 0; 12158 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12159 if (sscanf(val, "%30d", &x) == 1) { 12160 vmminsecs = x; 12161 if (maxsilence / 1000 >= vmminsecs) { 12162 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12163 } 12164 } else { 12165 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12166 } 12167 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12168 static int maxmessage_deprecate = 0; 12169 if (maxmessage_deprecate == 0) { 12170 maxmessage_deprecate = 1; 12171 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12172 } 12173 if (sscanf(val, "%30d", &x) == 1) { 12174 vmminsecs = x; 12175 if (maxsilence / 1000 >= vmminsecs) { 12176 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12177 } 12178 } else { 12179 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12180 } 12181 } 12182 12183 val = ast_variable_retrieve(cfg, "general", "format"); 12184 if (!val) { 12185 val = "wav"; 12186 } else { 12187 tmp = ast_strdupa(val); 12188 val = ast_format_str_reduce(tmp); 12189 if (!val) { 12190 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12191 val = "wav"; 12192 } 12193 } 12194 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12195 12196 skipms = 3000; 12197 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12198 if (sscanf(val, "%30d", &x) == 1) { 12199 maxgreet = x; 12200 } else { 12201 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12202 } 12203 } 12204 12205 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12206 if (sscanf(val, "%30d", &x) == 1) { 12207 skipms = x; 12208 } else { 12209 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12210 } 12211 } 12212 12213 maxlogins = 3; 12214 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12215 if (sscanf(val, "%30d", &x) == 1) { 12216 maxlogins = x; 12217 } else { 12218 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12219 } 12220 } 12221 12222 minpassword = MINPASSWORD; 12223 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12224 if (sscanf(val, "%30d", &x) == 1) { 12225 minpassword = x; 12226 } else { 12227 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12228 } 12229 } 12230 12231 /* Force new user to record name ? */ 12232 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12233 val = "no"; 12234 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12235 12236 /* Force new user to record greetings ? */ 12237 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12238 val = "no"; 12239 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12240 12241 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12242 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12243 stringp = ast_strdupa(val); 12244 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12245 if (!ast_strlen_zero(stringp)) { 12246 q = strsep(&stringp, ","); 12247 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12248 q++; 12249 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12250 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12251 } else { 12252 cidinternalcontexts[x][0] = '\0'; 12253 } 12254 } 12255 } 12256 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12257 ast_debug(1, "VM Review Option disabled globally\n"); 12258 val = "no"; 12259 } 12260 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12261 12262 /* Temporary greeting reminder */ 12263 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12264 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12265 val = "no"; 12266 } else { 12267 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12268 } 12269 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12270 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12271 ast_debug(1, "VM next message wrap disabled globally\n"); 12272 val = "no"; 12273 } 12274 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12275 12276 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12277 ast_debug(1, "VM Operator break disabled globally\n"); 12278 val = "no"; 12279 } 12280 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12281 12282 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12283 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12284 val = "no"; 12285 } 12286 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12287 12288 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12289 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12290 val = "no"; 12291 } 12292 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12293 12294 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12295 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12296 val = "yes"; 12297 } 12298 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12299 12300 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12301 ast_debug(1, "Move Heard enabled globally\n"); 12302 val = "yes"; 12303 } 12304 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12305 12306 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12307 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12308 val = "no"; 12309 } 12310 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12311 12312 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12313 ast_debug(1, "Duration info before msg enabled globally\n"); 12314 val = "yes"; 12315 } 12316 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12317 12318 saydurationminfo = 2; 12319 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12320 if (sscanf(val, "%30d", &x) == 1) { 12321 saydurationminfo = x; 12322 } else { 12323 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12324 } 12325 } 12326 12327 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12328 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12329 val = "no"; 12330 } 12331 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12332 12333 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12334 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12335 ast_debug(1, "found dialout context: %s\n", dialcontext); 12336 } else { 12337 dialcontext[0] = '\0'; 12338 } 12339 12340 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12341 ast_copy_string(callcontext, val, sizeof(callcontext)); 12342 ast_debug(1, "found callback context: %s\n", callcontext); 12343 } else { 12344 callcontext[0] = '\0'; 12345 } 12346 12347 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12348 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12349 ast_debug(1, "found operator context: %s\n", exitcontext); 12350 } else { 12351 exitcontext[0] = '\0'; 12352 } 12353 12354 /* load password sounds configuration */ 12355 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12356 ast_copy_string(vm_password, val, sizeof(vm_password)); 12357 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12358 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12359 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12360 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12361 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12362 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12363 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12364 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12365 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12366 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12367 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12368 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12369 } 12370 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12371 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12372 } 12373 /* load configurable audio prompts */ 12374 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12375 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12376 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12377 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12378 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12379 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12380 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12381 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12382 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12383 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12384 12385 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12386 val = "no"; 12387 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12388 12389 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12390 val = "voicemail.conf"; 12391 } 12392 if (!(strcmp(val, "spooldir"))) { 12393 passwordlocation = OPT_PWLOC_SPOOLDIR; 12394 } else { 12395 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12396 } 12397 12398 poll_freq = DEFAULT_POLL_FREQ; 12399 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12400 if (sscanf(val, "%30u", &poll_freq) != 1) { 12401 poll_freq = DEFAULT_POLL_FREQ; 12402 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12403 } 12404 } 12405 12406 poll_mailboxes = 0; 12407 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12408 poll_mailboxes = ast_true(val); 12409 12410 memset(fromstring, 0, sizeof(fromstring)); 12411 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12412 strcpy(charset, "ISO-8859-1"); 12413 if (emailbody) { 12414 ast_free(emailbody); 12415 emailbody = NULL; 12416 } 12417 if (emailsubject) { 12418 ast_free(emailsubject); 12419 emailsubject = NULL; 12420 } 12421 if (pagerbody) { 12422 ast_free(pagerbody); 12423 pagerbody = NULL; 12424 } 12425 if (pagersubject) { 12426 ast_free(pagersubject); 12427 pagersubject = NULL; 12428 } 12429 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12430 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12431 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12432 ast_copy_string(fromstring, val, sizeof(fromstring)); 12433 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12434 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12435 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12436 ast_copy_string(charset, val, sizeof(charset)); 12437 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12438 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12439 for (x = 0; x < 4; x++) { 12440 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12441 } 12442 } 12443 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12444 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12445 for (x = 0; x < 4; x++) { 12446 memcpy(&adsisec[x], &tmpadsi[x], 1); 12447 } 12448 } 12449 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12450 if (atoi(val)) { 12451 adsiver = atoi(val); 12452 } 12453 } 12454 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12455 ast_copy_string(zonetag, val, sizeof(zonetag)); 12456 } 12457 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12458 ast_copy_string(locale, val, sizeof(locale)); 12459 } 12460 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12461 emailsubject = ast_strdup(substitute_escapes(val)); 12462 } 12463 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12464 emailbody = ast_strdup(substitute_escapes(val)); 12465 } 12466 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12467 pagersubject = ast_strdup(substitute_escapes(val)); 12468 } 12469 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12470 pagerbody = ast_strdup(substitute_escapes(val)); 12471 } 12472 12473 /* load mailboxes from users.conf */ 12474 if (ucfg) { 12475 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12476 if (!strcasecmp(cat, "general")) { 12477 continue; 12478 } 12479 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12480 continue; 12481 if ((current = find_or_create(userscontext, cat))) { 12482 populate_defaults(current); 12483 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12484 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12485 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12486 current->passwordlocation = OPT_PWLOC_USERSCONF; 12487 } 12488 12489 switch (current->passwordlocation) { 12490 case OPT_PWLOC_SPOOLDIR: 12491 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12492 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12493 } 12494 } 12495 } 12496 } 12497 12498 /* load mailboxes from voicemail.conf */ 12499 cat = ast_category_browse(cfg, NULL); 12500 while (cat) { 12501 if (strcasecmp(cat, "general")) { 12502 var = ast_variable_browse(cfg, cat); 12503 if (strcasecmp(cat, "zonemessages")) { 12504 /* Process mailboxes in this context */ 12505 while (var) { 12506 append_mailbox(cat, var->name, var->value); 12507 var = var->next; 12508 } 12509 } else { 12510 /* Timezones in this context */ 12511 while (var) { 12512 struct vm_zone *z; 12513 if ((z = ast_malloc(sizeof(*z)))) { 12514 char *msg_format, *tzone; 12515 msg_format = ast_strdupa(var->value); 12516 tzone = strsep(&msg_format, "|,"); 12517 if (msg_format) { 12518 ast_copy_string(z->name, var->name, sizeof(z->name)); 12519 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12520 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12521 AST_LIST_LOCK(&zones); 12522 AST_LIST_INSERT_HEAD(&zones, z, list); 12523 AST_LIST_UNLOCK(&zones); 12524 } else { 12525 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12526 ast_free(z); 12527 } 12528 } else { 12529 AST_LIST_UNLOCK(&users); 12530 return -1; 12531 } 12532 var = var->next; 12533 } 12534 } 12535 } 12536 cat = ast_category_browse(cfg, cat); 12537 } 12538 12539 AST_LIST_UNLOCK(&users); 12540 12541 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12542 start_poll_thread(); 12543 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12544 stop_poll_thread();; 12545 12546 return 0; 12547 } else { 12548 AST_LIST_UNLOCK(&users); 12549 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12550 return 0; 12551 } 12552 }
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 4810 of file app_voicemail_imapstorage.c.
References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
Referenced by make_email_file().
04811 { 04812 char tmpdir[256], newtmp[256]; 04813 char fname[256]; 04814 char tmpcmd[256]; 04815 int tmpfd = -1; 04816 int soxstatus = 0; 04817 04818 /* Eww. We want formats to tell us their own MIME type */ 04819 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04820 04821 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04822 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04823 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04824 tmpfd = mkstemp(newtmp); 04825 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04826 ast_debug(3, "newtmp: %s\n", newtmp); 04827 if (tmpfd > -1) { 04828 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04829 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04830 attach = newtmp; 04831 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04832 } else { 04833 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04834 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04835 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04836 } 04837 } 04838 } 04839 fprintf(p, "--%s" ENDL, bound); 04840 if (msgnum > -1) 04841 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04842 else 04843 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04844 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04845 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04846 if (msgnum > -1) 04847 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04848 else 04849 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04850 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04851 base_encode(fname, p); 04852 if (last) 04853 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04854 if (tmpfd > -1) { 04855 if (soxstatus == 0) { 04856 unlink(fname); 04857 } 04858 close(tmpfd); 04859 unlink(newtmp); 04860 } 04861 return 0; 04862 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6416 of file app_voicemail_imapstorage.c.
References adsi_load_vmail(), ast_adsi_available(), ast_adsi_load_session(), ast_log(), and AST_LOG_WARNING.
Referenced by vm_authenticate(), and vm_execmain().
06417 { 06418 int x; 06419 if (!ast_adsi_available(chan)) 06420 return; 06421 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06422 if (x < 0) 06423 return; 06424 if (!x) { 06425 if (adsi_load_vmail(chan, useadsi)) { 06426 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06427 return; 06428 } 06429 } else 06430 *useadsi = 1; 06431 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6611 of file app_voicemail_imapstorage.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().
06612 { 06613 int bytes = 0; 06614 unsigned char buf[256]; 06615 unsigned char keys[8]; 06616 06617 int x; 06618 06619 if (!ast_adsi_available(chan)) 06620 return; 06621 06622 /* New meaning for keys */ 06623 for (x = 0; x < 5; x++) 06624 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06625 06626 keys[6] = 0x0; 06627 keys[7] = 0x0; 06628 06629 if (!vms->curmsg) { 06630 /* No prev key, provide "Folder" instead */ 06631 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06632 } 06633 if (vms->curmsg >= vms->lastmsg) { 06634 /* If last message ... */ 06635 if (vms->curmsg) { 06636 /* but not only message, provide "Folder" instead */ 06637 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06638 } else { 06639 /* Otherwise if only message, leave blank */ 06640 keys[3] = 1; 06641 } 06642 } 06643 06644 /* If deleted, show "undeleted" */ 06645 #ifdef IMAP_STORAGE 06646 ast_mutex_lock(&vms->lock); 06647 #endif 06648 if (vms->deleted[vms->curmsg]) { 06649 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06650 } 06651 #ifdef IMAP_STORAGE 06652 ast_mutex_unlock(&vms->lock); 06653 #endif 06654 06655 /* Except "Exit" */ 06656 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06657 bytes += ast_adsi_set_keys(buf + bytes, keys); 06658 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06659 06660 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06661 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6481 of file app_voicemail_imapstorage.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().
06482 { 06483 unsigned char buf[256]; 06484 int bytes = 0; 06485 unsigned char keys[8]; 06486 int x, y; 06487 06488 if (!ast_adsi_available(chan)) 06489 return; 06490 06491 for (x = 0; x < 5; x++) { 06492 y = ADSI_KEY_APPS + 12 + start + x; 06493 if (y > ADSI_KEY_APPS + 12 + 4) 06494 y = 0; 06495 keys[x] = ADSI_KEY_SKT | y; 06496 } 06497 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06498 keys[6] = 0; 06499 keys[7] = 0; 06500 06501 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06502 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06503 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06504 bytes += ast_adsi_set_keys(buf + bytes, keys); 06505 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06506 06507 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06508 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6766 of file app_voicemail_imapstorage.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().
06767 { 06768 unsigned char buf[256]; 06769 int bytes = 0; 06770 06771 if (!ast_adsi_available(chan)) 06772 return; 06773 bytes += adsi_logo(buf + bytes); 06774 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06775 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06776 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06777 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06778 06779 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06780 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6287 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, 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().
06288 { 06289 unsigned char buf[256]; 06290 int bytes = 0; 06291 int x; 06292 char num[5]; 06293 06294 *useadsi = 0; 06295 bytes += ast_adsi_data_mode(buf + bytes); 06296 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06297 06298 bytes = 0; 06299 bytes += adsi_logo(buf); 06300 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06301 #ifdef DISPLAY 06302 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06303 #endif 06304 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06305 bytes += ast_adsi_data_mode(buf + bytes); 06306 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06307 06308 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06309 bytes = 0; 06310 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06311 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06312 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06313 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06314 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06315 return 0; 06316 } 06317 06318 #ifdef DISPLAY 06319 /* Add a dot */ 06320 bytes = 0; 06321 bytes += ast_adsi_logo(buf); 06322 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06323 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06324 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06325 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06326 #endif 06327 bytes = 0; 06328 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06329 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06330 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06331 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06332 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06333 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06334 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06335 06336 #ifdef DISPLAY 06337 /* Add another dot */ 06338 bytes = 0; 06339 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06340 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06341 06342 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06343 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06344 #endif 06345 06346 bytes = 0; 06347 /* These buttons we load but don't use yet */ 06348 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06349 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06350 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06351 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06352 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06353 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06354 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06355 06356 #ifdef DISPLAY 06357 /* Add another dot */ 06358 bytes = 0; 06359 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06360 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06361 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06362 #endif 06363 06364 bytes = 0; 06365 for (x = 0; x < 5; x++) { 06366 snprintf(num, sizeof(num), "%d", x); 06367 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06368 } 06369 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06370 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06371 06372 #ifdef DISPLAY 06373 /* Add another dot */ 06374 bytes = 0; 06375 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06376 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06377 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06378 #endif 06379 06380 if (ast_adsi_end_download(chan)) { 06381 bytes = 0; 06382 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06383 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06384 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06385 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06386 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06387 return 0; 06388 } 06389 bytes = 0; 06390 bytes += ast_adsi_download_disconnect(buf + bytes); 06391 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06392 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06393 06394 ast_debug(1, "Done downloading scripts...\n"); 06395 06396 #ifdef DISPLAY 06397 /* Add last dot */ 06398 bytes = 0; 06399 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06400 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06401 #endif 06402 ast_debug(1, "Restarting session...\n"); 06403 06404 bytes = 0; 06405 /* Load the session now */ 06406 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06407 *useadsi = 1; 06408 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06409 } else 06410 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06411 06412 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06413 return 0; 06414 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6433 of file app_voicemail_imapstorage.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().
06434 { 06435 unsigned char buf[256]; 06436 int bytes = 0; 06437 unsigned char keys[8]; 06438 int x; 06439 if (!ast_adsi_available(chan)) 06440 return; 06441 06442 for (x = 0; x < 8; x++) 06443 keys[x] = 0; 06444 /* Set one key for next */ 06445 keys[3] = ADSI_KEY_APPS + 3; 06446 06447 bytes += adsi_logo(buf + bytes); 06448 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06449 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06450 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06451 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06452 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06453 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06454 bytes += ast_adsi_set_keys(buf + bytes, keys); 06455 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06456 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06457 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6279 of file app_voicemail_imapstorage.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().
06280 { 06281 int bytes = 0; 06282 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06283 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06284 return bytes; 06285 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6510 of file app_voicemail_imapstorage.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, and vm_state::lastmsg.
Referenced by play_message(), and vm_execmain().
06511 { 06512 int bytes = 0; 06513 unsigned char buf[256]; 06514 char buf1[256], buf2[256]; 06515 char fn2[PATH_MAX]; 06516 06517 char cid[256] = ""; 06518 char *val; 06519 char *name, *num; 06520 char datetime[21] = ""; 06521 FILE *f; 06522 06523 unsigned char keys[8]; 06524 06525 int x; 06526 06527 if (!ast_adsi_available(chan)) 06528 return; 06529 06530 /* Retrieve important info */ 06531 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06532 f = fopen(fn2, "r"); 06533 if (f) { 06534 while (!feof(f)) { 06535 if (!fgets((char *) buf, sizeof(buf), f)) { 06536 continue; 06537 } 06538 if (!feof(f)) { 06539 char *stringp = NULL; 06540 stringp = (char *) buf; 06541 strsep(&stringp, "="); 06542 val = strsep(&stringp, "="); 06543 if (!ast_strlen_zero(val)) { 06544 if (!strcmp((char *) buf, "callerid")) 06545 ast_copy_string(cid, val, sizeof(cid)); 06546 if (!strcmp((char *) buf, "origdate")) 06547 ast_copy_string(datetime, val, sizeof(datetime)); 06548 } 06549 } 06550 } 06551 fclose(f); 06552 } 06553 /* New meaning for keys */ 06554 for (x = 0; x < 5; x++) 06555 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06556 keys[6] = 0x0; 06557 keys[7] = 0x0; 06558 06559 if (!vms->curmsg) { 06560 /* No prev key, provide "Folder" instead */ 06561 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06562 } 06563 if (vms->curmsg >= vms->lastmsg) { 06564 /* If last message ... */ 06565 if (vms->curmsg) { 06566 /* but not only message, provide "Folder" instead */ 06567 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06568 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06569 06570 } else { 06571 /* Otherwise if only message, leave blank */ 06572 keys[3] = 1; 06573 } 06574 } 06575 06576 if (!ast_strlen_zero(cid)) { 06577 ast_callerid_parse(cid, &name, &num); 06578 if (!name) 06579 name = num; 06580 } else 06581 name = "Unknown Caller"; 06582 06583 /* If deleted, show "undeleted" */ 06584 #ifdef IMAP_STORAGE 06585 ast_mutex_lock(&vms->lock); 06586 #endif 06587 if (vms->deleted[vms->curmsg]) { 06588 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06589 } 06590 #ifdef IMAP_STORAGE 06591 ast_mutex_unlock(&vms->lock); 06592 #endif 06593 06594 /* Except "Exit" */ 06595 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06596 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06597 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06598 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06599 06600 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06601 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06602 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06603 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06604 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06605 bytes += ast_adsi_set_keys(buf + bytes, keys); 06606 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06607 06608 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06609 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6459 of file app_voicemail_imapstorage.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().
06460 { 06461 unsigned char buf[256]; 06462 int bytes = 0; 06463 unsigned char keys[8]; 06464 int x; 06465 if (!ast_adsi_available(chan)) 06466 return; 06467 06468 for (x = 0; x < 8; x++) 06469 keys[x] = 0; 06470 /* Set one key for next */ 06471 keys[3] = ADSI_KEY_APPS + 3; 06472 06473 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06474 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06475 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06476 bytes += ast_adsi_set_keys(buf + bytes, keys); 06477 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06478 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06479 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6663 of file app_voicemail_imapstorage.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().
06664 { 06665 unsigned char buf[256] = ""; 06666 char buf1[256] = "", buf2[256] = ""; 06667 int bytes = 0; 06668 unsigned char keys[8]; 06669 int x; 06670 06671 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06672 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06673 if (!ast_adsi_available(chan)) 06674 return; 06675 if (vms->newmessages) { 06676 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06677 if (vms->oldmessages) { 06678 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06679 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06680 } else { 06681 snprintf(buf2, sizeof(buf2), "%s.", newm); 06682 } 06683 } else if (vms->oldmessages) { 06684 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06685 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06686 } else { 06687 strcpy(buf1, "You have no messages."); 06688 buf2[0] = ' '; 06689 buf2[1] = '\0'; 06690 } 06691 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06692 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06693 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06694 06695 for (x = 0; x < 6; x++) 06696 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06697 keys[6] = 0; 06698 keys[7] = 0; 06699 06700 /* Don't let them listen if there are none */ 06701 if (vms->lastmsg < 0) 06702 keys[0] = 1; 06703 bytes += ast_adsi_set_keys(buf + bytes, keys); 06704 06705 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06706 06707 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06708 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6710 of file app_voicemail_imapstorage.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().
06711 { 06712 unsigned char buf[256] = ""; 06713 char buf1[256] = "", buf2[256] = ""; 06714 int bytes = 0; 06715 unsigned char keys[8]; 06716 int x; 06717 06718 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06719 06720 if (!ast_adsi_available(chan)) 06721 return; 06722 06723 /* Original command keys */ 06724 for (x = 0; x < 6; x++) 06725 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06726 06727 keys[6] = 0; 06728 keys[7] = 0; 06729 06730 if ((vms->lastmsg + 1) < 1) 06731 keys[0] = 0; 06732 06733 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06734 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06735 06736 if (vms->lastmsg + 1) 06737 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06738 else 06739 strcpy(buf2, "no messages."); 06740 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06741 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06742 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06743 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06744 bytes += ast_adsi_set_keys(buf + bytes, keys); 06745 06746 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06747 06748 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06749 06750 }
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 13259 of file app_voicemail_imapstorage.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
13260 { 13261 int res = 0; 13262 char filename[PATH_MAX]; 13263 struct ast_config *msg_cfg = NULL; 13264 const char *origtime, *context; 13265 char *name, *num; 13266 int retries = 0; 13267 char *cid; 13268 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13269 13270 vms->starting = 0; 13271 13272 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13273 13274 /* Retrieve info from VM attribute file */ 13275 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13276 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13277 msg_cfg = ast_config_load(filename, config_flags); 13278 DISPOSE(vms->curdir, vms->curmsg); 13279 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13280 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13281 return 0; 13282 } 13283 13284 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13285 ast_config_destroy(msg_cfg); 13286 return 0; 13287 } 13288 13289 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13290 13291 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13292 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13293 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13294 switch (option) { 13295 case 3: /* Play message envelope */ 13296 if (!res) 13297 res = play_message_datetime(chan, vmu, origtime, filename); 13298 if (!res) 13299 res = play_message_callerid(chan, vms, cid, context, 0); 13300 13301 res = 't'; 13302 break; 13303 13304 case 2: /* Call back */ 13305 13306 if (ast_strlen_zero(cid)) 13307 break; 13308 13309 ast_callerid_parse(cid, &name, &num); 13310 while ((res > -1) && (res != 't')) { 13311 switch (res) { 13312 case '1': 13313 if (num) { 13314 /* Dial the CID number */ 13315 res = dialout(chan, vmu, num, vmu->callback); 13316 if (res) { 13317 ast_config_destroy(msg_cfg); 13318 return 9; 13319 } 13320 } else { 13321 res = '2'; 13322 } 13323 break; 13324 13325 case '2': 13326 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13327 if (!ast_strlen_zero(vmu->dialout)) { 13328 res = dialout(chan, vmu, NULL, vmu->dialout); 13329 if (res) { 13330 ast_config_destroy(msg_cfg); 13331 return 9; 13332 } 13333 } else { 13334 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13335 res = ast_play_and_wait(chan, "vm-sorry"); 13336 } 13337 ast_config_destroy(msg_cfg); 13338 return res; 13339 case '*': 13340 res = 't'; 13341 break; 13342 case '3': 13343 case '4': 13344 case '5': 13345 case '6': 13346 case '7': 13347 case '8': 13348 case '9': 13349 case '0': 13350 13351 res = ast_play_and_wait(chan, "vm-sorry"); 13352 retries++; 13353 break; 13354 default: 13355 if (num) { 13356 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13357 res = ast_play_and_wait(chan, "vm-num-i-have"); 13358 if (!res) 13359 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13360 if (!res) 13361 res = ast_play_and_wait(chan, "vm-tocallnum"); 13362 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13363 if (!ast_strlen_zero(vmu->dialout)) { 13364 if (!res) 13365 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13366 } 13367 } else { 13368 res = ast_play_and_wait(chan, "vm-nonumber"); 13369 if (!ast_strlen_zero(vmu->dialout)) { 13370 if (!res) 13371 res = ast_play_and_wait(chan, "vm-toenternumber"); 13372 } 13373 } 13374 if (!res) { 13375 res = ast_play_and_wait(chan, "vm-star-cancel"); 13376 } 13377 if (!res) { 13378 res = ast_waitfordigit(chan, 6000); 13379 } 13380 if (!res) { 13381 retries++; 13382 if (retries > 3) { 13383 res = 't'; 13384 } 13385 } 13386 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13387 break; 13388 13389 } 13390 if (res == 't') 13391 res = 0; 13392 else if (res == '*') 13393 res = -1; 13394 } 13395 break; 13396 13397 case 1: /* Reply */ 13398 /* Send reply directly to sender */ 13399 if (ast_strlen_zero(cid)) 13400 break; 13401 13402 ast_callerid_parse(cid, &name, &num); 13403 if (!num) { 13404 ast_verb(3, "No CID number available, no reply sent\n"); 13405 if (!res) 13406 res = ast_play_and_wait(chan, "vm-nonumber"); 13407 ast_config_destroy(msg_cfg); 13408 return res; 13409 } else { 13410 struct ast_vm_user vmu2; 13411 if (find_user(&vmu2, vmu->context, num)) { 13412 struct leave_vm_options leave_options; 13413 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13414 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13415 13416 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13417 13418 memset(&leave_options, 0, sizeof(leave_options)); 13419 leave_options.record_gain = record_gain; 13420 res = leave_voicemail(chan, mailbox, &leave_options); 13421 if (!res) 13422 res = 't'; 13423 ast_config_destroy(msg_cfg); 13424 return res; 13425 } else { 13426 /* Sender has no mailbox, can't reply */ 13427 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13428 ast_play_and_wait(chan, "vm-nobox"); 13429 res = 't'; 13430 ast_config_destroy(msg_cfg); 13431 return res; 13432 } 13433 } 13434 res = 0; 13435 13436 break; 13437 } 13438 13439 #ifndef IMAP_STORAGE 13440 ast_config_destroy(msg_cfg); 13441 13442 if (!res) { 13443 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13444 vms->heard[msg] = 1; 13445 res = wait_file(chan, vms, vms->fn); 13446 } 13447 #endif 13448 return res; 13449 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10781 of file app_voicemail_imapstorage.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(), and read_password_from_file().
Referenced by actual_load_config().
10782 { 10783 /* Assumes lock is already held */ 10784 char *tmp; 10785 char *stringp; 10786 char *s; 10787 struct ast_vm_user *vmu; 10788 char *mailbox_full; 10789 int new = 0, old = 0, urgent = 0; 10790 char secretfn[PATH_MAX] = ""; 10791 10792 tmp = ast_strdupa(data); 10793 10794 if (!(vmu = find_or_create(context, box))) 10795 return -1; 10796 10797 populate_defaults(vmu); 10798 10799 stringp = tmp; 10800 if ((s = strsep(&stringp, ","))) { 10801 if (!ast_strlen_zero(s) && s[0] == '*') { 10802 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10803 "\n\tmust be reset in voicemail.conf.\n", box); 10804 } 10805 /* assign password regardless of validity to prevent NULL password from being assigned */ 10806 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10807 } 10808 if (stringp && (s = strsep(&stringp, ","))) { 10809 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10810 } 10811 if (stringp && (s = strsep(&stringp, ","))) { 10812 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10813 } 10814 if (stringp && (s = strsep(&stringp, ","))) { 10815 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10816 } 10817 if (stringp && (s = strsep(&stringp, ","))) { 10818 apply_options(vmu, s); 10819 } 10820 10821 switch (vmu->passwordlocation) { 10822 case OPT_PWLOC_SPOOLDIR: 10823 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10824 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10825 } 10826 10827 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10828 strcpy(mailbox_full, box); 10829 strcat(mailbox_full, "@"); 10830 strcat(mailbox_full, context); 10831 10832 inboxcount2(mailbox_full, &urgent, &new, &old); 10833 queue_mwi_event(mailbox_full, urgent, new, old); 10834 10835 return 0; 10836 }
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 1063 of file app_voicemail_imapstorage.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_strdup, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::locale, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::serveremail, substitute_escapes(), VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
01064 { 01065 int x; 01066 if (!strcasecmp(var, "attach")) { 01067 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01068 } else if (!strcasecmp(var, "attachfmt")) { 01069 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01070 } else if (!strcasecmp(var, "serveremail")) { 01071 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01072 } else if (!strcasecmp(var, "emailbody")) { 01073 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01074 } else if (!strcasecmp(var, "emailsubject")) { 01075 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01076 } else if (!strcasecmp(var, "language")) { 01077 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01078 } else if (!strcasecmp(var, "tz")) { 01079 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01080 } else if (!strcasecmp(var, "locale")) { 01081 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01082 #ifdef IMAP_STORAGE 01083 } else if (!strcasecmp(var, "imapuser")) { 01084 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01085 vmu->imapversion = imapversion; 01086 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01087 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01088 vmu->imapversion = imapversion; 01089 } else if (!strcasecmp(var, "imapfolder")) { 01090 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01091 } else if (!strcasecmp(var, "imapvmshareid")) { 01092 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01093 vmu->imapversion = imapversion; 01094 #endif 01095 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01096 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01097 } else if (!strcasecmp(var, "saycid")){ 01098 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01099 } else if (!strcasecmp(var, "sendvoicemail")){ 01100 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01101 } else if (!strcasecmp(var, "review")){ 01102 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01103 } else if (!strcasecmp(var, "tempgreetwarn")){ 01104 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01105 } else if (!strcasecmp(var, "messagewrap")){ 01106 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01107 } else if (!strcasecmp(var, "operator")) { 01108 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01109 } else if (!strcasecmp(var, "envelope")){ 01110 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01111 } else if (!strcasecmp(var, "moveheard")){ 01112 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01113 } else if (!strcasecmp(var, "sayduration")){ 01114 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01115 } else if (!strcasecmp(var, "saydurationm")){ 01116 if (sscanf(value, "%30d", &x) == 1) { 01117 vmu->saydurationm = x; 01118 } else { 01119 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01120 } 01121 } else if (!strcasecmp(var, "forcename")){ 01122 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01123 } else if (!strcasecmp(var, "forcegreetings")){ 01124 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01125 } else if (!strcasecmp(var, "callback")) { 01126 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01127 } else if (!strcasecmp(var, "dialout")) { 01128 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01129 } else if (!strcasecmp(var, "exitcontext")) { 01130 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01131 } else if (!strcasecmp(var, "minsecs")) { 01132 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01133 vmu->minsecs = x; 01134 } else { 01135 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01136 vmu->minsecs = vmminsecs; 01137 } 01138 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01139 vmu->maxsecs = atoi(value); 01140 if (vmu->maxsecs <= 0) { 01141 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01142 vmu->maxsecs = vmmaxsecs; 01143 } else { 01144 vmu->maxsecs = atoi(value); 01145 } 01146 if (!strcasecmp(var, "maxmessage")) 01147 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01148 } else if (!strcasecmp(var, "maxmsg")) { 01149 vmu->maxmsg = atoi(value); 01150 /* Accept maxmsg=0 (Greetings only voicemail) */ 01151 if (vmu->maxmsg < 0) { 01152 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01153 vmu->maxmsg = MAXMSG; 01154 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01155 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01156 vmu->maxmsg = MAXMSGLIMIT; 01157 } 01158 } else if (!strcasecmp(var, "nextaftercmd")) { 01159 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01160 } else if (!strcasecmp(var, "backupdeleted")) { 01161 if (sscanf(value, "%30d", &x) == 1) 01162 vmu->maxdeletedmsg = x; 01163 else if (ast_true(value)) 01164 vmu->maxdeletedmsg = MAXMSG; 01165 else 01166 vmu->maxdeletedmsg = 0; 01167 01168 if (vmu->maxdeletedmsg < 0) { 01169 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01170 vmu->maxdeletedmsg = MAXMSG; 01171 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01172 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01173 vmu->maxdeletedmsg = MAXMSGLIMIT; 01174 } 01175 } else if (!strcasecmp(var, "volgain")) { 01176 sscanf(value, "%30lf", &vmu->volgain); 01177 } else if (!strcasecmp(var, "passwordlocation")) { 01178 if (!strcasecmp(value, "spooldir")) { 01179 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01180 } else { 01181 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01182 } 01183 } else if (!strcasecmp(var, "options")) { 01184 apply_options(vmu, value); 01185 } 01186 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1304 of file app_voicemail_imapstorage.c.
References apply_option(), ast_strdupa, value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01305 { 01306 char *stringp; 01307 char *s; 01308 char *var, *value; 01309 stringp = ast_strdupa(options); 01310 while ((s = strsep(&stringp, "|"))) { 01311 value = s; 01312 if ((var = strsep(&value, "=")) && value) { 01313 apply_option(vmu, var, value); 01314 } 01315 } 01316 }
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 1323 of file app_voicemail_imapstorage.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().
01324 { 01325 for (; var; var = var->next) { 01326 if (!strcasecmp(var->name, "vmsecret")) { 01327 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01328 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01329 if (ast_strlen_zero(retval->password)) { 01330 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01331 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01332 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01333 } else { 01334 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01335 } 01336 } 01337 } else if (!strcasecmp(var->name, "uniqueid")) { 01338 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01339 } else if (!strcasecmp(var->name, "pager")) { 01340 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01341 } else if (!strcasecmp(var->name, "email")) { 01342 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01343 } else if (!strcasecmp(var->name, "fullname")) { 01344 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01345 } else if (!strcasecmp(var->name, "context")) { 01346 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01347 } else if (!strcasecmp(var->name, "emailsubject")) { 01348 ast_free(retval->emailsubject); 01349 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01350 } else if (!strcasecmp(var->name, "emailbody")) { 01351 ast_free(retval->emailbody); 01352 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01353 #ifdef IMAP_STORAGE 01354 } else if (!strcasecmp(var->name, "imapuser")) { 01355 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01356 retval->imapversion = imapversion; 01357 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01358 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01359 retval->imapversion = imapversion; 01360 } else if (!strcasecmp(var->name, "imapfolder")) { 01361 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01362 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01363 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01364 retval->imapversion = imapversion; 01365 #endif 01366 } else 01367 apply_option(retval, var->name, var->value); 01368 } 01369 }
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 4485 of file app_voicemail_imapstorage.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), and ast_str_strlen().
Referenced by make_email_file(), and sendpage().
04486 { 04487 struct ast_str *tmp = ast_str_alloca(80); 04488 int first_section = 1; 04489 04490 ast_str_reset(*end); 04491 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04492 for (; *start; start++) { 04493 int need_encoding = 0; 04494 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04495 need_encoding = 1; 04496 } 04497 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04498 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04499 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04500 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04501 /* Start new line */ 04502 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04503 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04504 first_section = 0; 04505 } 04506 if (need_encoding && *start == ' ') { 04507 ast_str_append(&tmp, -1, "_"); 04508 } else if (need_encoding) { 04509 ast_str_append(&tmp, -1, "=%hhX", *start); 04510 } else { 04511 ast_str_append(&tmp, -1, "%c", *start); 04512 } 04513 } 04514 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04515 return ast_str_buffer(*end); 04516 }
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 4413 of file app_voicemail_imapstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), and sendpage().
04414 { 04415 const char *ptr; 04416 04417 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04418 ast_str_set(buf, maxlen, "\""); 04419 for (ptr = from; *ptr; ptr++) { 04420 if (*ptr == '"' || *ptr == '\\') { 04421 ast_str_append(buf, maxlen, "\\%c", *ptr); 04422 } else { 04423 ast_str_append(buf, maxlen, "%c", *ptr); 04424 } 04425 } 04426 ast_str_append(buf, maxlen, "\""); 04427 04428 return ast_str_buffer(*buf); 04429 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10838 of file app_voicemail_imapstorage.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.
10839 { 10840 int res = 0; 10841 struct ast_vm_user *vmu; 10842 /* language parameter seems to only be used for display in manager action */ 10843 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10844 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10845 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10846 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10847 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10848 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10849 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10850 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10851 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10852 #ifdef IMAP_STORAGE 10853 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10854 "imapfolder=INBOX|imapvmshareid=6000"; 10855 #endif 10856 10857 switch (cmd) { 10858 case TEST_INIT: 10859 info->name = "vmuser"; 10860 info->category = "/apps/app_voicemail/"; 10861 info->summary = "Vmuser unit test"; 10862 info->description = 10863 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10864 return AST_TEST_NOT_RUN; 10865 case TEST_EXECUTE: 10866 break; 10867 } 10868 10869 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10870 return AST_TEST_NOT_RUN; 10871 } 10872 populate_defaults(vmu); 10873 ast_set_flag(vmu, VM_ALLOCED); 10874 10875 apply_options(vmu, options_string); 10876 10877 if (!ast_test_flag(vmu, VM_ATTACH)) { 10878 ast_test_status_update(test, "Parse failure for attach option\n"); 10879 res = 1; 10880 } 10881 if (strcasecmp(vmu->attachfmt, "wav49")) { 10882 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10883 res = 1; 10884 } 10885 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10886 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10887 res = 1; 10888 } 10889 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10890 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10891 res = 1; 10892 } 10893 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10894 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10895 res = 1; 10896 } 10897 if (strcasecmp(vmu->zonetag, "central")) { 10898 ast_test_status_update(test, "Parse failure for tz option\n"); 10899 res = 1; 10900 } 10901 if (!ast_test_flag(vmu, VM_DELETE)) { 10902 ast_test_status_update(test, "Parse failure for delete option\n"); 10903 res = 1; 10904 } 10905 if (!ast_test_flag(vmu, VM_SAYCID)) { 10906 ast_test_status_update(test, "Parse failure for saycid option\n"); 10907 res = 1; 10908 } 10909 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10910 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10911 res = 1; 10912 } 10913 if (!ast_test_flag(vmu, VM_REVIEW)) { 10914 ast_test_status_update(test, "Parse failure for review option\n"); 10915 res = 1; 10916 } 10917 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10918 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10919 res = 1; 10920 } 10921 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10922 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10923 res = 1; 10924 } 10925 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10926 ast_test_status_update(test, "Parse failure for operator option\n"); 10927 res = 1; 10928 } 10929 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10930 ast_test_status_update(test, "Parse failure for envelope option\n"); 10931 res = 1; 10932 } 10933 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10934 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10935 res = 1; 10936 } 10937 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10938 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10939 res = 1; 10940 } 10941 if (vmu->saydurationm != 5) { 10942 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10943 res = 1; 10944 } 10945 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10946 ast_test_status_update(test, "Parse failure for forcename option\n"); 10947 res = 1; 10948 } 10949 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10950 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10951 res = 1; 10952 } 10953 if (strcasecmp(vmu->callback, "somecontext")) { 10954 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10955 res = 1; 10956 } 10957 if (strcasecmp(vmu->dialout, "somecontext2")) { 10958 ast_test_status_update(test, "Parse failure for dialout option\n"); 10959 res = 1; 10960 } 10961 if (strcasecmp(vmu->exit, "somecontext3")) { 10962 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10963 res = 1; 10964 } 10965 if (vmu->minsecs != 10) { 10966 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10967 res = 1; 10968 } 10969 if (vmu->maxsecs != 100) { 10970 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10971 res = 1; 10972 } 10973 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10974 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10975 res = 1; 10976 } 10977 if (vmu->maxdeletedmsg != 50) { 10978 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10979 res = 1; 10980 } 10981 if (vmu->volgain != 1.3) { 10982 ast_test_status_update(test, "Parse failure for volgain option\n"); 10983 res = 1; 10984 } 10985 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10986 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10987 res = 1; 10988 } 10989 #ifdef IMAP_STORAGE 10990 apply_options(vmu, option_string2); 10991 10992 if (strcasecmp(vmu->imapuser, "imapuser")) { 10993 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10994 res = 1; 10995 } 10996 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10997 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10998 res = 1; 10999 } 11000 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11001 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 11002 res = 1; 11003 } 11004 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11005 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11006 res = 1; 11007 } 11008 #endif 11009 11010 free_user(vmu); 11011 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11012 }
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 4289 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
Referenced by add_email_attachment().
04290 { 04291 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04292 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04293 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04294 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04295 int i, hiteof = 0; 04296 FILE *fi; 04297 struct baseio bio; 04298 04299 memset(&bio, 0, sizeof(bio)); 04300 bio.iocp = BASEMAXINLINE; 04301 04302 if (!(fi = fopen(filename, "rb"))) { 04303 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04304 return -1; 04305 } 04306 04307 while (!hiteof){ 04308 unsigned char igroup[3], ogroup[4]; 04309 int c, n; 04310 04311 memset(igroup, 0, sizeof(igroup)); 04312 04313 for (n = 0; n < 3; n++) { 04314 if ((c = inchar(&bio, fi)) == EOF) { 04315 hiteof = 1; 04316 break; 04317 } 04318 04319 igroup[n] = (unsigned char) c; 04320 } 04321 04322 if (n > 0) { 04323 ogroup[0]= dtable[igroup[0] >> 2]; 04324 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04325 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04326 ogroup[3]= dtable[igroup[2] & 0x3F]; 04327 04328 if (n < 3) { 04329 ogroup[3] = '='; 04330 04331 if (n < 2) 04332 ogroup[2] = '='; 04333 } 04334 04335 for (i = 0; i < 4; i++) 04336 ochar(&bio, ogroup[i], so); 04337 } 04338 } 04339 04340 fclose(fi); 04341 04342 if (fputs(ENDL, so) == EOF) { 04343 return 0; 04344 } 04345 04346 return 1; 04347 }
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 1282 of file app_voicemail_imapstorage.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().
01283 { 01284 int res = -1; 01285 if (!strcmp(vmu->password, password)) { 01286 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01287 return 0; 01288 } 01289 01290 if (strlen(password) > 10) { 01291 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01292 } 01293 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01294 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01295 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01296 res = 0; 01297 } 01298 return res; 01299 }
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 4458 of file app_voicemail_imapstorage.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 1241 of file app_voicemail_imapstorage.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().
Referenced by vm_newuser(), and vm_options().
01242 { 01243 /* check minimum length */ 01244 if (strlen(password) < minpassword) 01245 return 1; 01246 /* check that password does not contain '*' character */ 01247 if (!ast_strlen_zero(password) && password[0] == '*') 01248 return 1; 01249 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01250 char cmd[255], buf[255]; 01251 01252 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01253 01254 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01255 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01256 ast_debug(5, "Result: %s\n", buf); 01257 if (!strncasecmp(buf, "VALID", 5)) { 01258 ast_debug(3, "Passed password check: '%s'\n", buf); 01259 return 0; 01260 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01261 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01262 return 0; 01263 } else { 01264 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01265 return 1; 01266 } 01267 } 01268 } 01269 return 0; 01270 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7976 of file app_voicemail_imapstorage.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().
07977 { 07978 int x = 0; 07979 int last_msg_idx = 0; 07980 07981 #ifndef IMAP_STORAGE 07982 int res = 0, nummsg; 07983 char fn2[PATH_MAX]; 07984 #endif 07985 07986 if (vms->lastmsg <= -1) { 07987 goto done; 07988 } 07989 07990 vms->curmsg = -1; 07991 #ifndef IMAP_STORAGE 07992 /* Get the deleted messages fixed */ 07993 if (vm_lock_path(vms->curdir)) { 07994 return ERROR_LOCK_PATH; 07995 } 07996 07997 /* update count as message may have arrived while we've got mailbox open */ 07998 last_msg_idx = last_message_index(vmu, vms->curdir); 07999 if (last_msg_idx != vms->lastmsg) { 08000 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08001 } 08002 08003 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08004 for (x = 0; x < last_msg_idx + 1; x++) { 08005 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08006 /* Save this message. It's not in INBOX or hasn't been heard */ 08007 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08008 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08009 break; 08010 } 08011 vms->curmsg++; 08012 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08013 if (strcmp(vms->fn, fn2)) { 08014 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08015 } 08016 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08017 /* Move to old folder before deleting */ 08018 res = save_to_folder(vmu, vms, x, 1); 08019 if (res == ERROR_LOCK_PATH) { 08020 /* If save failed do not delete the message */ 08021 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08022 vms->deleted[x] = 0; 08023 vms->heard[x] = 0; 08024 --x; 08025 } 08026 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08027 /* Move to deleted folder */ 08028 res = save_to_folder(vmu, vms, x, 10); 08029 if (res == ERROR_LOCK_PATH) { 08030 /* If save failed do not delete the message */ 08031 vms->deleted[x] = 0; 08032 vms->heard[x] = 0; 08033 --x; 08034 } 08035 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08036 /* If realtime storage enabled - we should explicitly delete this message, 08037 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08038 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08039 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08040 DELETE(vms->curdir, x, vms->fn, vmu); 08041 } 08042 } 08043 } 08044 08045 /* Delete ALL remaining messages */ 08046 nummsg = x - 1; 08047 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08048 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08049 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08050 DELETE(vms->curdir, x, vms->fn, vmu); 08051 } 08052 } 08053 ast_unlock_path(vms->curdir); 08054 #else /* defined(IMAP_STORAGE) */ 08055 ast_mutex_lock(&vms->lock); 08056 if (vms->deleted) { 08057 /* Since we now expunge after each delete, deleting in reverse order 08058 * ensures that no reordering occurs between each step. */ 08059 last_msg_idx = vms->dh_arraysize; 08060 for (x = last_msg_idx - 1; x >= 0; x--) { 08061 if (vms->deleted[x]) { 08062 ast_debug(3, "IMAP delete of %d\n", x); 08063 DELETE(vms->curdir, x, vms->fn, vmu); 08064 } 08065 } 08066 } 08067 #endif 08068 08069 done: 08070 if (vms->deleted) { 08071 ast_free(vms->deleted); 08072 vms->deleted = NULL; 08073 } 08074 if (vms->heard) { 08075 ast_free(vms->heard); 08076 vms->heard = NULL; 08077 } 08078 vms->dh_arraysize = 0; 08079 #ifdef IMAP_STORAGE 08080 ast_mutex_unlock(&vms->lock); 08081 #endif 08082 08083 return 0; 08084 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11158 of file app_voicemail_imapstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11159 { 11160 int which = 0; 11161 int wordlen; 11162 struct ast_vm_user *vmu; 11163 const char *context = ""; 11164 11165 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11166 if (pos > 4) 11167 return NULL; 11168 if (pos == 3) 11169 return (state == 0) ? ast_strdup("for") : NULL; 11170 wordlen = strlen(word); 11171 AST_LIST_TRAVERSE(&users, vmu, list) { 11172 if (!strncasecmp(word, vmu->context, wordlen)) { 11173 if (context && strcmp(context, vmu->context) && ++which > state) 11174 return ast_strdup(vmu->context); 11175 /* ignore repeated contexts ? */ 11176 context = vmu->context; 11177 } 11178 } 11179 return NULL; 11180 }
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 4094 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by copy_plain_file(), and vm_forwardoptions().
04095 { 04096 int ifd; 04097 int ofd; 04098 int res; 04099 int len; 04100 char buf[4096]; 04101 04102 #ifdef HARDLINK_WHEN_POSSIBLE 04103 /* Hard link if possible; saves disk space & is faster */ 04104 if (link(infile, outfile)) { 04105 #endif 04106 if ((ifd = open(infile, O_RDONLY)) < 0) { 04107 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04108 return -1; 04109 } 04110 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04111 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04112 close(ifd); 04113 return -1; 04114 } 04115 do { 04116 len = read(ifd, buf, sizeof(buf)); 04117 if (len < 0) { 04118 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04119 close(ifd); 04120 close(ofd); 04121 unlink(outfile); 04122 } else if (len) { 04123 res = write(ofd, buf, len); 04124 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04125 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04126 close(ifd); 04127 close(ofd); 04128 unlink(outfile); 04129 } 04130 } 04131 } while (len); 04132 close(ifd); 04133 close(ofd); 04134 return 0; 04135 #ifdef HARDLINK_WHEN_POSSIBLE 04136 } else { 04137 /* Hard link succeeded */ 04138 return 0; 04139 } 04140 #endif 04141 }
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 5330 of file app_voicemail_imapstorage.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(), 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().
05331 { 05332 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05333 const char *frombox = mbox(vmu, imbox); 05334 const char *userfolder; 05335 int recipmsgnum; 05336 int res = 0; 05337 05338 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05339 05340 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05341 userfolder = "Urgent"; 05342 } else { 05343 userfolder = "INBOX"; 05344 } 05345 05346 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05347 05348 if (!dir) 05349 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05350 else 05351 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05352 05353 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05354 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05355 05356 if (vm_lock_path(todir)) 05357 return ERROR_LOCK_PATH; 05358 05359 recipmsgnum = last_message_index(recip, todir) + 1; 05360 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05361 make_file(topath, sizeof(topath), todir, recipmsgnum); 05362 #ifndef ODBC_STORAGE 05363 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05364 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05365 } else { 05366 #endif 05367 /* If we are prepending a message for ODBC, then the message already 05368 * exists in the database, but we want to force copying from the 05369 * filesystem (since only the FS contains the prepend). */ 05370 copy_plain_file(frompath, topath); 05371 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05372 vm_delete(topath); 05373 #ifndef ODBC_STORAGE 05374 } 05375 #endif 05376 } else { 05377 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05378 res = -1; 05379 } 05380 ast_unlock_path(todir); 05381 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05382 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05383 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05384 flag); 05385 05386 return res; 05387 }
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 4152 of file app_voicemail_imapstorage.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().
04153 { 04154 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04155 struct ast_variable *tmp,*var = NULL; 04156 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04157 ast_filecopy(frompath, topath, NULL); 04158 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04159 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04160 if (ast_check_realtime("voicemail_data")) { 04161 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04162 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04163 for (tmp = var; tmp; tmp = tmp->next) { 04164 if (!strcasecmp(tmp->name, "origmailbox")) { 04165 origmailbox = tmp->value; 04166 } else if (!strcasecmp(tmp->name, "context")) { 04167 context = tmp->value; 04168 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04169 macrocontext = tmp->value; 04170 } else if (!strcasecmp(tmp->name, "exten")) { 04171 exten = tmp->value; 04172 } else if (!strcasecmp(tmp->name, "priority")) { 04173 priority = tmp->value; 04174 } else if (!strcasecmp(tmp->name, "callerchan")) { 04175 callerchan = tmp->value; 04176 } else if (!strcasecmp(tmp->name, "callerid")) { 04177 callerid = tmp->value; 04178 } else if (!strcasecmp(tmp->name, "origdate")) { 04179 origdate = tmp->value; 04180 } else if (!strcasecmp(tmp->name, "origtime")) { 04181 origtime = tmp->value; 04182 } else if (!strcasecmp(tmp->name, "category")) { 04183 category = tmp->value; 04184 } else if (!strcasecmp(tmp->name, "duration")) { 04185 duration = tmp->value; 04186 } 04187 } 04188 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); 04189 } 04190 copy(frompath2, topath2); 04191 ast_variables_destroy(var); 04192 }
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 3989 of file app_voicemail_imapstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().
03990 { 03991 03992 int vmcount = 0; 03993 DIR *vmdir = NULL; 03994 struct dirent *vment = NULL; 03995 03996 if (vm_lock_path(dir)) 03997 return ERROR_LOCK_PATH; 03998 03999 if ((vmdir = opendir(dir))) { 04000 while ((vment = readdir(vmdir))) { 04001 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 04002 vmcount++; 04003 } 04004 } 04005 closedir(vmdir); 04006 } 04007 ast_unlock_path(dir); 04008 04009 return vmcount; 04010 }
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 1692 of file app_voicemail_imapstorage.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().
01693 { 01694 mode_t mode = VOICEMAIL_DIR_MODE; 01695 int res; 01696 01697 make_dir(dest, len, context, ext, folder); 01698 if ((res = ast_mkdir(dest, mode))) { 01699 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01700 return -1; 01701 } 01702 return 0; 01703 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13186 of file app_voicemail_imapstorage.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().
13187 { 13188 int cmd = 0; 13189 char destination[80] = ""; 13190 int retries = 0; 13191 13192 if (!num) { 13193 ast_verb(3, "Destination number will be entered manually\n"); 13194 while (retries < 3 && cmd != 't') { 13195 destination[1] = '\0'; 13196 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13197 if (!cmd) 13198 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13199 if (!cmd) 13200 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13201 if (!cmd) { 13202 cmd = ast_waitfordigit(chan, 6000); 13203 if (cmd) 13204 destination[0] = cmd; 13205 } 13206 if (!cmd) { 13207 retries++; 13208 } else { 13209 13210 if (cmd < 0) 13211 return 0; 13212 if (cmd == '*') { 13213 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13214 return 0; 13215 } 13216 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13217 retries++; 13218 else 13219 cmd = 't'; 13220 } 13221 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13222 } 13223 if (retries >= 3) { 13224 return 0; 13225 } 13226 13227 } else { 13228 if (option_verbose > 2) 13229 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13230 ast_copy_string(destination, num, sizeof(destination)); 13231 } 13232 13233 if (!ast_strlen_zero(destination)) { 13234 if (destination[strlen(destination) -1 ] == '*') 13235 return 0; 13236 if (option_verbose > 2) 13237 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13238 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13239 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13240 chan->priority = 0; 13241 return 9; 13242 } 13243 return 0; 13244 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10741 of file app_voicemail_imapstorage.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, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by actual_load_config(), and append_mailbox().
10742 { 10743 struct ast_vm_user *vmu; 10744 10745 if (!ast_strlen_zero(box) && box[0] == '*') { 10746 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10747 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10748 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10749 "\n\tand will be ignored.\n", box, context); 10750 return NULL; 10751 } 10752 10753 AST_LIST_TRAVERSE(&users, vmu, list) { 10754 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10755 if (strcasecmp(vmu->context, context)) { 10756 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10757 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10758 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10759 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10760 } 10761 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10762 return NULL; 10763 } 10764 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10765 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10766 return NULL; 10767 } 10768 } 10769 10770 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10771 return NULL; 10772 10773 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10774 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10775 10776 AST_LIST_INSERT_TAIL(&users, vmu, list); 10777 10778 return vmu; 10779 }
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 1444 of file app_voicemail_imapstorage.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(), VM_ALLOCED, and VM_SEARCH.
Referenced by acf_mailbox_exists(), advanced_options(), forward_message(), leave_voicemail(), vm_authenticate(), vm_box_exists(), and vm_execmain().
01445 { 01446 /* This function could be made to generate one from a database, too */ 01447 struct ast_vm_user *vmu = NULL, *cur; 01448 AST_LIST_LOCK(&users); 01449 01450 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01451 context = "default"; 01452 01453 AST_LIST_TRAVERSE(&users, cur, list) { 01454 #ifdef IMAP_STORAGE 01455 if (cur->imapversion != imapversion) { 01456 continue; 01457 } 01458 #endif 01459 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01460 break; 01461 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01462 break; 01463 } 01464 if (cur) { 01465 /* Make a copy, so that on a reload, we have no race */ 01466 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01467 *vmu = *cur; 01468 if (!ivm) { 01469 vmu->emailbody = ast_strdup(cur->emailbody); 01470 vmu->emailsubject = ast_strdup(cur->emailsubject); 01471 } 01472 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01473 AST_LIST_NEXT(vmu, list) = NULL; 01474 } 01475 } else 01476 vmu = find_user_realtime(ivm, context, mailbox); 01477 AST_LIST_UNLOCK(&users); 01478 return vmu; 01479 }
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 1403 of file app_voicemail_imapstorage.c.
References apply_options_full(), ast_calloc, ast_copy_string(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free_user(), ast_vm_user::mailbox, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
Referenced by find_user().
01404 { 01405 struct ast_variable *var; 01406 struct ast_vm_user *retval; 01407 01408 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01409 if (ivm) { 01410 memset(retval, 0, sizeof(*retval)); 01411 } 01412 populate_defaults(retval); 01413 if (!ivm) { 01414 ast_set_flag(retval, VM_ALLOCED); 01415 } 01416 if (mailbox) { 01417 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01418 } 01419 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01420 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01421 } else { 01422 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01423 } 01424 if (var) { 01425 apply_options_full(retval, var); 01426 ast_variables_destroy(var); 01427 } else { 01428 if (!ivm) 01429 free_user(retval); 01430 retval = NULL; 01431 } 01432 } 01433 return retval; 01434 }
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 7177 of file app_voicemail_imapstorage.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(), ast_party_caller::id, inboxcount(), inprocess_count(), leave_voicemail(), LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_party_id::name, ast_party_id::number, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), STORE, ast_party_name::str, ast_party_number::str, vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
Referenced by vm_execmain().
07178 { 07179 #ifdef IMAP_STORAGE 07180 int todircount = 0; 07181 struct vm_state *dstvms; 07182 #endif 07183 char username[70]=""; 07184 char fn[PATH_MAX]; /* for playback of name greeting */ 07185 char ecodes[16] = "#"; 07186 int res = 0, cmd = 0; 07187 struct ast_vm_user *receiver = NULL, *vmtmp; 07188 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07189 char *stringp; 07190 const char *s; 07191 int saved_messages = 0; 07192 int valid_extensions = 0; 07193 char *dir; 07194 int curmsg; 07195 char urgent_str[7] = ""; 07196 int prompt_played = 0; 07197 #ifndef IMAP_STORAGE 07198 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07199 #endif 07200 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07201 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07202 } 07203 07204 if (vms == NULL) return -1; 07205 dir = vms->curdir; 07206 curmsg = vms->curmsg; 07207 07208 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07209 while (!res && !valid_extensions) { 07210 int use_directory = 0; 07211 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07212 int done = 0; 07213 int retries = 0; 07214 cmd = 0; 07215 while ((cmd >= 0) && !done ){ 07216 if (cmd) 07217 retries = 0; 07218 switch (cmd) { 07219 case '1': 07220 use_directory = 0; 07221 done = 1; 07222 break; 07223 case '2': 07224 use_directory = 1; 07225 done = 1; 07226 break; 07227 case '*': 07228 cmd = 't'; 07229 done = 1; 07230 break; 07231 default: 07232 /* Press 1 to enter an extension press 2 to use the directory */ 07233 cmd = ast_play_and_wait(chan, "vm-forward"); 07234 if (!cmd) { 07235 cmd = ast_waitfordigit(chan, 3000); 07236 } 07237 if (!cmd) { 07238 retries++; 07239 } 07240 if (retries > 3) { 07241 cmd = 't'; 07242 done = 1; 07243 } 07244 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07245 } 07246 } 07247 if (cmd < 0 || cmd == 't') 07248 break; 07249 } 07250 07251 if (use_directory) { 07252 /* use app_directory */ 07253 07254 char old_context[sizeof(chan->context)]; 07255 char old_exten[sizeof(chan->exten)]; 07256 int old_priority; 07257 struct ast_app* directory_app; 07258 07259 directory_app = pbx_findapp("Directory"); 07260 if (directory_app) { 07261 char vmcontext[256]; 07262 /* make backup copies */ 07263 memcpy(old_context, chan->context, sizeof(chan->context)); 07264 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07265 old_priority = chan->priority; 07266 07267 /* call the the Directory, changes the channel */ 07268 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07269 res = pbx_exec(chan, directory_app, vmcontext); 07270 07271 ast_copy_string(username, chan->exten, sizeof(username)); 07272 07273 /* restore the old context, exten, and priority */ 07274 memcpy(chan->context, old_context, sizeof(chan->context)); 07275 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07276 chan->priority = old_priority; 07277 } else { 07278 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07279 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07280 } 07281 } else { 07282 /* Ask for an extension */ 07283 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07284 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07285 prompt_played++; 07286 if (res || prompt_played > 4) 07287 break; 07288 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07289 break; 07290 } 07291 07292 /* start all over if no username */ 07293 if (ast_strlen_zero(username)) 07294 continue; 07295 stringp = username; 07296 s = strsep(&stringp, "*"); 07297 /* start optimistic */ 07298 valid_extensions = 1; 07299 while (s) { 07300 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07301 int oldmsgs; 07302 int newmsgs; 07303 int capacity; 07304 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07305 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07306 /* Shouldn't happen, but allow trying another extension if it does */ 07307 res = ast_play_and_wait(chan, "pbx-invalid"); 07308 valid_extensions = 0; 07309 break; 07310 } 07311 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07312 if ((newmsgs + oldmsgs) >= capacity) { 07313 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07314 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07315 valid_extensions = 0; 07316 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07317 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07318 free_user(vmtmp); 07319 } 07320 inprocess_count(receiver->mailbox, receiver->context, -1); 07321 break; 07322 } 07323 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07324 } else { 07325 /* XXX Optimization for the future. When we encounter a single bad extension, 07326 * bailing out on all of the extensions may not be the way to go. We should 07327 * probably just bail on that single extension, then allow the user to enter 07328 * several more. XXX 07329 */ 07330 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07331 free_user(receiver); 07332 } 07333 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07334 /* "I am sorry, that's not a valid extension. Please try again." */ 07335 res = ast_play_and_wait(chan, "pbx-invalid"); 07336 valid_extensions = 0; 07337 break; 07338 } 07339 07340 /* play name if available, else play extension number */ 07341 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07342 RETRIEVE(fn, -1, s, receiver->context); 07343 if (ast_fileexists(fn, NULL, NULL) > 0) { 07344 res = ast_stream_and_wait(chan, fn, ecodes); 07345 if (res) { 07346 DISPOSE(fn, -1); 07347 return res; 07348 } 07349 } else { 07350 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07351 } 07352 DISPOSE(fn, -1); 07353 07354 s = strsep(&stringp, "*"); 07355 } 07356 /* break from the loop of reading the extensions */ 07357 if (valid_extensions) 07358 break; 07359 } 07360 /* check if we're clear to proceed */ 07361 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07362 return res; 07363 if (is_new_message == 1) { 07364 struct leave_vm_options leave_options; 07365 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07366 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07367 07368 /* Send VoiceMail */ 07369 memset(&leave_options, 0, sizeof(leave_options)); 07370 leave_options.record_gain = record_gain; 07371 cmd = leave_voicemail(chan, mailbox, &leave_options); 07372 } else { 07373 /* Forward VoiceMail */ 07374 long duration = 0; 07375 struct vm_state vmstmp; 07376 int copy_msg_result = 0; 07377 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07378 07379 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07380 07381 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07382 if (!cmd) { 07383 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07384 #ifdef IMAP_STORAGE 07385 int attach_user_voicemail; 07386 char *myserveremail = serveremail; 07387 07388 /* get destination mailbox */ 07389 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07390 if (!dstvms) { 07391 dstvms = create_vm_state_from_user(vmtmp); 07392 } 07393 if (dstvms) { 07394 init_mailstream(dstvms, 0); 07395 if (!dstvms->mailstream) { 07396 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07397 } else { 07398 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07399 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07400 } 07401 } else { 07402 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07403 } 07404 if (!ast_strlen_zero(vmtmp->serveremail)) 07405 myserveremail = vmtmp->serveremail; 07406 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07407 /* NULL category for IMAP storage */ 07408 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07409 dstvms->curbox, 07410 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07411 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07412 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07413 NULL, urgent_str); 07414 #else 07415 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07416 #endif 07417 saved_messages++; 07418 AST_LIST_REMOVE_CURRENT(list); 07419 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07420 free_user(vmtmp); 07421 if (res) 07422 break; 07423 } 07424 AST_LIST_TRAVERSE_SAFE_END; 07425 if (saved_messages > 0 && !copy_msg_result) { 07426 /* give confirmation that the message was saved */ 07427 /* commented out since we can't forward batches yet 07428 if (saved_messages == 1) 07429 res = ast_play_and_wait(chan, "vm-message"); 07430 else 07431 res = ast_play_and_wait(chan, "vm-messages"); 07432 if (!res) 07433 res = ast_play_and_wait(chan, "vm-saved"); */ 07434 #ifdef IMAP_STORAGE 07435 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07436 if (ast_strlen_zero(vmstmp.introfn)) 07437 #endif 07438 res = ast_play_and_wait(chan, "vm-msgsaved"); 07439 } 07440 #ifndef IMAP_STORAGE 07441 else { 07442 /* with IMAP, mailbox full warning played by imap_check_limits */ 07443 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07444 } 07445 /* Restore original message without prepended message if backup exists */ 07446 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07447 strcpy(textfile, msgfile); 07448 strcpy(backup, msgfile); 07449 strcpy(backup_textfile, msgfile); 07450 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07451 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07452 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07453 if (ast_fileexists(backup, NULL, NULL) > 0) { 07454 ast_filerename(backup, msgfile, NULL); 07455 rename(backup_textfile, textfile); 07456 } 07457 #endif 07458 } 07459 DISPOSE(dir, curmsg); 07460 #ifndef IMAP_STORAGE 07461 if (cmd) { /* assuming hangup, cleanup backup file */ 07462 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07463 strcpy(textfile, msgfile); 07464 strcpy(backup_textfile, msgfile); 07465 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07466 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07467 rename(backup_textfile, textfile); 07468 } 07469 #endif 07470 } 07471 07472 /* If anything failed above, we still have this list to free */ 07473 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07474 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07475 free_user(vmtmp); 07476 } 07477 return res ? res : cmd; 07478 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1747 of file app_voicemail_imapstorage.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().
01748 { 01749 if (ast_test_flag(vmu, VM_ALLOCED)) { 01750 01751 ast_free(vmu->emailbody); 01752 vmu->emailbody = NULL; 01753 01754 ast_free(vmu->emailsubject); 01755 vmu->emailsubject = NULL; 01756 01757 ast_free(vmu); 01758 } 01759 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11770 of file app_voicemail_imapstorage.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().
11771 { 11772 struct ast_vm_user *current; 11773 AST_LIST_LOCK(&users); 11774 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11775 ast_set_flag(current, VM_ALLOCED); 11776 free_user(current); 11777 } 11778 AST_LIST_UNLOCK(&users); 11779 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11782 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by actual_load_config(), and unload_module().
11783 { 11784 struct vm_zone *zcur; 11785 AST_LIST_LOCK(&zones); 11786 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11787 free_zone(zcur); 11788 AST_LIST_UNLOCK(&zones); 11789 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5098 of file app_voicemail_imapstorage.c.
References ast_free.
Referenced by free_vm_zones().
05099 { 05100 ast_free(z); 05101 }
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 5054 of file app_voicemail_imapstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
05055 { 05056 struct ast_tm tm; 05057 struct timeval t = ast_tvnow(); 05058 05059 ast_localtime(&t, &tm, "UTC"); 05060 05061 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05062 }
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 6786 of file app_voicemail_imapstorage.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().
06787 { 06788 int x; 06789 int d; 06790 char fn[PATH_MAX]; 06791 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06792 if (d) 06793 return d; 06794 for (x = start; x < 5; x++) { /* For all folders */ 06795 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06796 return d; 06797 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06798 if (d) 06799 return d; 06800 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06801 06802 /* The inbox folder can have its name changed under certain conditions 06803 * so this checks if the sound file exists for the inbox folder name and 06804 * if it doesn't, plays the default name instead. */ 06805 if (x == 0) { 06806 if (ast_fileexists(fn, NULL, NULL)) { 06807 d = vm_play_folder_name(chan, fn); 06808 } else { 06809 ast_verb(1, "failed to find %s\n", fn); 06810 d = vm_play_folder_name(chan, "vm-INBOX"); 06811 } 06812 } else { 06813 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06814 d = vm_play_folder_name(chan, fn); 06815 } 06816 06817 if (d) 06818 return d; 06819 d = ast_waitfordigit(chan, 500); 06820 if (d) 06821 return d; 06822 } 06823 06824 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06825 if (d) 06826 return d; 06827 d = ast_waitfordigit(chan, 4000); 06828 return d; 06829 }
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 6843 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06844 { 06845 int res = 0; 06846 int loops = 0; 06847 06848 res = ast_play_and_wait(chan, fn); /* Folder name */ 06849 while (((res < '0') || (res > '9')) && 06850 (res != '#') && (res >= 0) && 06851 loops < 4) { 06852 res = get_folder(chan, 0); 06853 loops++; 06854 } 06855 if (loops == 4) { /* give up */ 06856 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06857 return '#'; 06858 } 06859 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06860 return res; 06861 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1734 of file app_voicemail_imapstorage.c.
References ARRAY_LEN.
Referenced by vm_execmain().
01735 { 01736 size_t i; 01737 01738 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01739 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01740 return i; 01741 } 01742 } 01743 01744 return -1; 01745 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11540 of file app_voicemail_imapstorage.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().
11541 { 11542 unsigned int len; 11543 struct mwi_sub *mwi_sub; 11544 struct mwi_sub_task *p = datap; 11545 11546 len = sizeof(*mwi_sub); 11547 if (!ast_strlen_zero(p->mailbox)) 11548 len += strlen(p->mailbox); 11549 11550 if (!ast_strlen_zero(p->context)) 11551 len += strlen(p->context) + 1; /* Allow for seperator */ 11552 11553 if (!(mwi_sub = ast_calloc(1, len))) 11554 return -1; 11555 11556 mwi_sub->uniqueid = p->uniqueid; 11557 if (!ast_strlen_zero(p->mailbox)) 11558 strcpy(mwi_sub->mailbox, p->mailbox); 11559 11560 if (!ast_strlen_zero(p->context)) { 11561 strcat(mwi_sub->mailbox, "@"); 11562 strcat(mwi_sub->mailbox, p->context); 11563 } 11564 11565 AST_RWLIST_WRLOCK(&mwi_subs); 11566 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11567 AST_RWLIST_UNLOCK(&mwi_subs); 11568 ast_free((void *) p->mailbox); 11569 ast_free((void *) p->context); 11570 ast_free(p); 11571 poll_subscribed_mailbox(mwi_sub); 11572 return 0; 11573 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11518 of file app_voicemail_imapstorage.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().
11519 { 11520 struct mwi_sub *mwi_sub; 11521 uint32_t *uniqueid = datap; 11522 11523 AST_RWLIST_WRLOCK(&mwi_subs); 11524 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11525 if (mwi_sub->uniqueid == *uniqueid) { 11526 AST_LIST_REMOVE_CURRENT(entry); 11527 break; 11528 } 11529 } 11530 AST_RWLIST_TRAVERSE_SAFE_END 11531 AST_RWLIST_UNLOCK(&mwi_subs); 11532 11533 if (mwi_sub) 11534 mwi_sub_destroy(mwi_sub); 11535 11536 ast_free(uniqueid); 11537 return 0; 11538 }
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 11295 of file app_voicemail_imapstorage.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.
11296 { 11297 switch (cmd) { 11298 case CLI_INIT: 11299 e->command = "voicemail reload"; 11300 e->usage = 11301 "Usage: voicemail reload\n" 11302 " Reload voicemail configuration\n"; 11303 return NULL; 11304 case CLI_GENERATE: 11305 return NULL; 11306 } 11307 11308 if (a->argc != 2) 11309 return CLI_SHOWUSAGE; 11310 11311 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11312 load_config(1); 11313 11314 return CLI_SUCCESS; 11315 }
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 11183 of file app_voicemail_imapstorage.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.
11184 { 11185 struct ast_vm_user *vmu; 11186 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11187 const char *context = NULL; 11188 int users_counter = 0; 11189 11190 switch (cmd) { 11191 case CLI_INIT: 11192 e->command = "voicemail show users"; 11193 e->usage = 11194 "Usage: voicemail show users [for <context>]\n" 11195 " Lists all mailboxes currently set up\n"; 11196 return NULL; 11197 case CLI_GENERATE: 11198 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11199 } 11200 11201 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11202 return CLI_SHOWUSAGE; 11203 if (a->argc == 5) { 11204 if (strcmp(a->argv[3],"for")) 11205 return CLI_SHOWUSAGE; 11206 context = a->argv[4]; 11207 } 11208 11209 if (ast_check_realtime("voicemail")) { 11210 if (!context) { 11211 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11212 return CLI_SHOWUSAGE; 11213 } 11214 return show_users_realtime(a->fd, context); 11215 } 11216 11217 AST_LIST_LOCK(&users); 11218 if (AST_LIST_EMPTY(&users)) { 11219 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11220 AST_LIST_UNLOCK(&users); 11221 return CLI_FAILURE; 11222 } 11223 if (!context) { 11224 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11225 } else { 11226 int count = 0; 11227 AST_LIST_TRAVERSE(&users, vmu, list) { 11228 if (!strcmp(context, vmu->context)) { 11229 count++; 11230 break; 11231 } 11232 } 11233 if (count) { 11234 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11235 } else { 11236 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11237 AST_LIST_UNLOCK(&users); 11238 return CLI_FAILURE; 11239 } 11240 } 11241 AST_LIST_TRAVERSE(&users, vmu, list) { 11242 int newmsgs = 0, oldmsgs = 0; 11243 char count[12], tmp[256] = ""; 11244 11245 if (!context || !strcmp(context, vmu->context)) { 11246 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11247 inboxcount(tmp, &newmsgs, &oldmsgs); 11248 snprintf(count, sizeof(count), "%d", newmsgs); 11249 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11250 users_counter++; 11251 } 11252 } 11253 AST_LIST_UNLOCK(&users); 11254 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11255 return CLI_SUCCESS; 11256 }
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 11259 of file app_voicemail_imapstorage.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.
11260 { 11261 struct vm_zone *zone; 11262 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11263 char *res = CLI_SUCCESS; 11264 11265 switch (cmd) { 11266 case CLI_INIT: 11267 e->command = "voicemail show zones"; 11268 e->usage = 11269 "Usage: voicemail show zones\n" 11270 " Lists zone message formats\n"; 11271 return NULL; 11272 case CLI_GENERATE: 11273 return NULL; 11274 } 11275 11276 if (a->argc != 3) 11277 return CLI_SHOWUSAGE; 11278 11279 AST_LIST_LOCK(&zones); 11280 if (!AST_LIST_EMPTY(&zones)) { 11281 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11282 AST_LIST_TRAVERSE(&zones, zone, list) { 11283 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11284 } 11285 } else { 11286 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11287 res = CLI_FAILURE; 11288 } 11289 AST_LIST_UNLOCK(&zones); 11290 11291 return res; 11292 }
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 5442 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by load_module(), and vm_execmain().
05443 { 05444 char tmp[256], *tmp2 = tmp, *box, *context; 05445 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05446 if (ast_strlen_zero(folder)) { 05447 folder = "INBOX"; 05448 } 05449 while ((box = strsep(&tmp2, ",&"))) { 05450 if ((context = strchr(box, '@'))) 05451 *context++ = '\0'; 05452 else 05453 context = "default"; 05454 if (__has_voicemail(context, box, folder, 1)) 05455 return 1; 05456 /* If we are checking INBOX, we should check Urgent as well */ 05457 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05458 return 1; 05459 } 05460 } 05461 return 0; 05462 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5524 of file app_voicemail_imapstorage.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05525 { 05526 int urgentmsgs = 0; 05527 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05528 if (newmsgs) { 05529 *newmsgs += urgentmsgs; 05530 } 05531 return res; 05532 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5465 of file app_voicemail_imapstorage.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().
05466 { 05467 char tmp[256]; 05468 char *context; 05469 05470 /* If no mailbox, return immediately */ 05471 if (ast_strlen_zero(mailbox)) 05472 return 0; 05473 05474 if (newmsgs) 05475 *newmsgs = 0; 05476 if (oldmsgs) 05477 *oldmsgs = 0; 05478 if (urgentmsgs) 05479 *urgentmsgs = 0; 05480 05481 if (strchr(mailbox, ',')) { 05482 int tmpnew, tmpold, tmpurgent; 05483 char *mb, *cur; 05484 05485 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05486 mb = tmp; 05487 while ((cur = strsep(&mb, ", "))) { 05488 if (!ast_strlen_zero(cur)) { 05489 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05490 return -1; 05491 else { 05492 if (newmsgs) 05493 *newmsgs += tmpnew; 05494 if (oldmsgs) 05495 *oldmsgs += tmpold; 05496 if (urgentmsgs) 05497 *urgentmsgs += tmpurgent; 05498 } 05499 } 05500 } 05501 return 0; 05502 } 05503 05504 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05505 05506 if ((context = strchr(tmp, '@'))) 05507 *context++ = '\0'; 05508 else 05509 context = "default"; 05510 05511 if (newmsgs) 05512 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05513 if (oldmsgs) 05514 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05515 if (urgentmsgs) 05516 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05517 05518 return 0; 05519 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4224 of file app_voicemail_imapstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by inchar().
04225 { 04226 int l; 04227 04228 if (bio->ateof) 04229 return 0; 04230 04231 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04232 if (ferror(fi)) 04233 return -1; 04234 04235 bio->ateof = 1; 04236 return 0; 04237 } 04238 04239 bio->iolen = l; 04240 bio->iocp = 0; 04241 04242 return 1; 04243 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4248 of file app_voicemail_imapstorage.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 942 of file app_voicemail_imapstorage.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 951 of file app_voicemail_imapstorage.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, LOG_WARNING, and inprocess::mailbox.
Referenced by copy_message(), forward_message(), and leave_voicemail().
00952 { 00953 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00954 arg->context = arg->mailbox + strlen(mailbox) + 1; 00955 strcpy(arg->mailbox, mailbox); /* SAFE */ 00956 strcpy(arg->context, context); /* SAFE */ 00957 ao2_lock(inprocess_container); 00958 if ((i = ao2_find(inprocess_container, arg, 0))) { 00959 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00960 ao2_unlock(inprocess_container); 00961 ao2_ref(i, -1); 00962 return ret; 00963 } 00964 if (delta < 0) { 00965 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00966 } 00967 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00968 ao2_unlock(inprocess_container); 00969 return 0; 00970 } 00971 i->context = i->mailbox + strlen(mailbox) + 1; 00972 strcpy(i->mailbox, mailbox); /* SAFE */ 00973 strcpy(i->context, context); /* SAFE */ 00974 i->count = delta; 00975 ao2_link(inprocess_container, i); 00976 ao2_unlock(inprocess_container); 00977 ao2_ref(i, -1); 00978 return 0; 00979 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 936 of file app_voicemail_imapstorage.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 5064 of file app_voicemail_imapstorage.c.
References ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, and RETRIEVE.
Referenced by leave_voicemail().
05065 { 05066 int res; 05067 char fn[PATH_MAX]; 05068 char dest[PATH_MAX]; 05069 05070 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05071 05072 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05073 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05074 return -1; 05075 } 05076 05077 RETRIEVE(fn, -1, ext, context); 05078 if (ast_fileexists(fn, NULL, NULL) > 0) { 05079 res = ast_stream_and_wait(chan, fn, ecodes); 05080 if (res) { 05081 DISPOSE(fn, -1); 05082 return res; 05083 } 05084 } else { 05085 /* Dispose just in case */ 05086 DISPOSE(fn, -1); 05087 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05088 if (res) 05089 return res; 05090 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05091 if (res) 05092 return res; 05093 } 05094 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05095 return res; 05096 }
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 1378 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01379 { 01380 int i; 01381 char *local_key = ast_strdupa(key); 01382 01383 for (i = 0; i < strlen(key); ++i) { 01384 if (!strchr(VALID_DTMF, *local_key)) { 01385 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01386 return 0; 01387 } 01388 local_key++; 01389 } 01390 return 1; 01391 }
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 4043 of file app_voicemail_imapstorage.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().
04044 { 04045 int x; 04046 unsigned char map[MAXMSGLIMIT] = ""; 04047 DIR *msgdir; 04048 struct dirent *msgdirent; 04049 int msgdirint; 04050 char extension[4]; 04051 int stopcount = 0; 04052 04053 /* Reading the entire directory into a file map scales better than 04054 * doing a stat repeatedly on a predicted sequence. I suspect this 04055 * is partially due to stat(2) internally doing a readdir(2) itself to 04056 * find each file. */ 04057 if (!(msgdir = opendir(dir))) { 04058 return -1; 04059 } 04060 04061 while ((msgdirent = readdir(msgdir))) { 04062 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04063 map[msgdirint] = 1; 04064 stopcount++; 04065 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04066 } 04067 } 04068 closedir(msgdir); 04069 04070 for (x = 0; x < vmu->maxmsg; x++) { 04071 if (map[x] == 1) { 04072 stopcount--; 04073 } else if (map[x] == 0 && !stopcount) { 04074 break; 04075 } 04076 } 04077 04078 return x - 1; 04079 }
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 5597 of file app_voicemail_imapstorage.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, 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, VOICEMAIL_DIR_MODE, and VOICEMAIL_FILE_MODE.
Referenced by advanced_options(), forward_message(), and vm_exec().
05598 { 05599 #ifdef IMAP_STORAGE 05600 int newmsgs, oldmsgs; 05601 #else 05602 char urgdir[PATH_MAX]; 05603 #endif 05604 char txtfile[PATH_MAX]; 05605 char tmptxtfile[PATH_MAX]; 05606 struct vm_state *vms = NULL; 05607 char callerid[256]; 05608 FILE *txt; 05609 char date[256]; 05610 int txtdes; 05611 int res = 0; 05612 int msgnum; 05613 int duration = 0; 05614 int sound_duration = 0; 05615 int ausemacro = 0; 05616 int ousemacro = 0; 05617 int ouseexten = 0; 05618 char tmpdur[16]; 05619 char priority[16]; 05620 char origtime[16]; 05621 char dir[PATH_MAX]; 05622 char tmpdir[PATH_MAX]; 05623 char fn[PATH_MAX]; 05624 char prefile[PATH_MAX] = ""; 05625 char tempfile[PATH_MAX] = ""; 05626 char ext_context[256] = ""; 05627 char fmt[80]; 05628 char *context; 05629 char ecodes[17] = "#"; 05630 struct ast_str *tmp = ast_str_create(16); 05631 char *tmpptr; 05632 struct ast_vm_user *vmu; 05633 struct ast_vm_user svm; 05634 const char *category = NULL; 05635 const char *code; 05636 const char *alldtmf = "0123456789ABCD*#"; 05637 char flag[80]; 05638 05639 if (!tmp) { 05640 return -1; 05641 } 05642 05643 ast_str_set(&tmp, 0, "%s", ext); 05644 ext = ast_str_buffer(tmp); 05645 if ((context = strchr(ext, '@'))) { 05646 *context++ = '\0'; 05647 tmpptr = strchr(context, '&'); 05648 } else { 05649 tmpptr = strchr(ext, '&'); 05650 } 05651 05652 if (tmpptr) 05653 *tmpptr++ = '\0'; 05654 05655 ast_channel_lock(chan); 05656 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05657 category = ast_strdupa(category); 05658 } 05659 ast_channel_unlock(chan); 05660 05661 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05662 ast_copy_string(flag, "Urgent", sizeof(flag)); 05663 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05664 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05665 } else { 05666 flag[0] = '\0'; 05667 } 05668 05669 ast_debug(3, "Before find_user\n"); 05670 if (!(vmu = find_user(&svm, context, ext))) { 05671 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05672 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05673 ast_free(tmp); 05674 return res; 05675 } 05676 /* Setup pre-file if appropriate */ 05677 if (strcmp(vmu->context, "default")) 05678 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05679 else 05680 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05681 05682 /* Set the path to the prefile. Will be one of 05683 VM_SPOOL_DIRcontext/ext/busy 05684 VM_SPOOL_DIRcontext/ext/unavail 05685 Depending on the flag set in options. 05686 */ 05687 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05688 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05689 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05690 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05691 } 05692 /* Set the path to the tmpfile as 05693 VM_SPOOL_DIR/context/ext/temp 05694 and attempt to create the folder structure. 05695 */ 05696 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05697 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05698 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05699 ast_free(tmp); 05700 return -1; 05701 } 05702 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05703 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05704 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05705 05706 DISPOSE(tempfile, -1); 05707 /* It's easier just to try to make it than to check for its existence */ 05708 #ifndef IMAP_STORAGE 05709 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05710 #else 05711 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05712 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05713 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05714 } 05715 #endif 05716 05717 /* Check current or macro-calling context for special extensions */ 05718 if (ast_test_flag(vmu, VM_OPERATOR)) { 05719 if (!ast_strlen_zero(vmu->exit)) { 05720 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05721 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05722 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05723 ouseexten = 1; 05724 } 05725 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05726 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05727 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05728 ouseexten = 1; 05729 } else if (!ast_strlen_zero(chan->macrocontext) 05730 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05731 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05732 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05733 ousemacro = 1; 05734 } 05735 } 05736 05737 if (!ast_strlen_zero(vmu->exit)) { 05738 if (ast_exists_extension(chan, vmu->exit, "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 } 05742 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05743 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05744 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05745 } else if (!ast_strlen_zero(chan->macrocontext) 05746 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05747 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05748 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05749 ausemacro = 1; 05750 } 05751 05752 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05753 for (code = alldtmf; *code; code++) { 05754 char e[2] = ""; 05755 e[0] = *code; 05756 if (strchr(ecodes, e[0]) == NULL 05757 && ast_canmatch_extension(chan, 05758 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05759 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05760 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05761 } 05762 } 05763 } 05764 05765 /* Play the beginning intro if desired */ 05766 if (!ast_strlen_zero(prefile)) { 05767 #ifdef ODBC_STORAGE 05768 int success = 05769 #endif 05770 RETRIEVE(prefile, -1, ext, context); 05771 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05772 if (ast_streamfile(chan, prefile, chan->language) > -1) 05773 res = ast_waitstream(chan, ecodes); 05774 #ifdef ODBC_STORAGE 05775 if (success == -1) { 05776 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05777 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05778 store_file(prefile, vmu->mailbox, vmu->context, -1); 05779 } 05780 #endif 05781 } else { 05782 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05783 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05784 } 05785 DISPOSE(prefile, -1); 05786 if (res < 0) { 05787 ast_debug(1, "Hang up during prefile playback\n"); 05788 free_user(vmu); 05789 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05790 ast_free(tmp); 05791 return -1; 05792 } 05793 } 05794 if (res == '#') { 05795 /* On a '#' we skip the instructions */ 05796 ast_set_flag(options, OPT_SILENT); 05797 res = 0; 05798 } 05799 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05800 if (vmu->maxmsg == 0) { 05801 if (option_debug > 2) 05802 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05803 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05804 goto leave_vm_out; 05805 } 05806 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05807 res = ast_stream_and_wait(chan, INTRO, ecodes); 05808 if (res == '#') { 05809 ast_set_flag(options, OPT_SILENT); 05810 res = 0; 05811 } 05812 } 05813 if (res > 0) 05814 ast_stopstream(chan); 05815 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05816 other than the operator -- an automated attendant or mailbox login for example */ 05817 if (res == '*') { 05818 chan->exten[0] = 'a'; 05819 chan->exten[1] = '\0'; 05820 if (!ast_strlen_zero(vmu->exit)) { 05821 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05822 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05823 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05824 } 05825 chan->priority = 0; 05826 free_user(vmu); 05827 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05828 ast_free(tmp); 05829 return 0; 05830 } 05831 05832 /* Check for a '0' here */ 05833 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05834 transfer: 05835 if (ouseexten || ousemacro) { 05836 chan->exten[0] = 'o'; 05837 chan->exten[1] = '\0'; 05838 if (!ast_strlen_zero(vmu->exit)) { 05839 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05840 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05841 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05842 } 05843 ast_play_and_wait(chan, "transfer"); 05844 chan->priority = 0; 05845 free_user(vmu); 05846 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05847 } 05848 ast_free(tmp); 05849 return OPERATOR_EXIT; 05850 } 05851 05852 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05853 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05854 if (!ast_strlen_zero(options->exitcontext)) { 05855 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05856 } 05857 free_user(vmu); 05858 ast_free(tmp); 05859 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05860 return res; 05861 } 05862 05863 if (res < 0) { 05864 free_user(vmu); 05865 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05866 ast_free(tmp); 05867 return -1; 05868 } 05869 /* The meat of recording the message... All the announcements and beeps have been played*/ 05870 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05871 if (!ast_strlen_zero(fmt)) { 05872 msgnum = 0; 05873 05874 #ifdef IMAP_STORAGE 05875 /* Is ext a mailbox? */ 05876 /* must open stream for this user to get info! */ 05877 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05878 if (res < 0) { 05879 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05880 ast_free(tmp); 05881 return -1; 05882 } 05883 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05884 /* It is possible under certain circumstances that inboxcount did not 05885 * create a vm_state when it was needed. This is a catchall which will 05886 * rarely be used. 05887 */ 05888 if (!(vms = create_vm_state_from_user(vmu))) { 05889 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05890 ast_free(tmp); 05891 return -1; 05892 } 05893 } 05894 vms->newmessages++; 05895 05896 /* here is a big difference! We add one to it later */ 05897 msgnum = newmsgs + oldmsgs; 05898 ast_debug(3, "Messagecount set to %d\n", msgnum); 05899 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05900 /* set variable for compatibility */ 05901 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05902 05903 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05904 goto leave_vm_out; 05905 } 05906 #else 05907 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05908 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05909 if (!res) 05910 res = ast_waitstream(chan, ""); 05911 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05912 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05913 inprocess_count(vmu->mailbox, vmu->context, -1); 05914 goto leave_vm_out; 05915 } 05916 05917 #endif 05918 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05919 txtdes = mkstemp(tmptxtfile); 05920 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05921 if (txtdes < 0) { 05922 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05923 if (!res) 05924 res = ast_waitstream(chan, ""); 05925 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05926 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05927 inprocess_count(vmu->mailbox, vmu->context, -1); 05928 goto leave_vm_out; 05929 } 05930 05931 /* Now play the beep once we have the message number for our next message. */ 05932 if (res >= 0) { 05933 /* Unless we're *really* silent, try to send the beep */ 05934 res = ast_stream_and_wait(chan, "beep", ""); 05935 } 05936 05937 /* Store information in real-time storage */ 05938 if (ast_check_realtime("voicemail_data")) { 05939 snprintf(priority, sizeof(priority), "%d", chan->priority); 05940 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05941 get_date(date, sizeof(date)); 05942 ast_callerid_merge(callerid, sizeof(callerid), 05943 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05944 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05945 "Unknown"); 05946 ast_store_realtime("voicemail_data", 05947 "origmailbox", ext, 05948 "context", chan->context, 05949 "macrocontext", chan->macrocontext, 05950 "exten", chan->exten, 05951 "priority", priority, 05952 "callerchan", chan->name, 05953 "callerid", callerid, 05954 "origdate", date, 05955 "origtime", origtime, 05956 "category", S_OR(category, ""), 05957 "filename", tmptxtfile, 05958 SENTINEL); 05959 } 05960 05961 /* Store information */ 05962 txt = fdopen(txtdes, "w+"); 05963 if (txt) { 05964 get_date(date, sizeof(date)); 05965 ast_callerid_merge(callerid, sizeof(callerid), 05966 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05967 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05968 "Unknown"); 05969 fprintf(txt, 05970 ";\n" 05971 "; Message Information file\n" 05972 ";\n" 05973 "[message]\n" 05974 "origmailbox=%s\n" 05975 "context=%s\n" 05976 "macrocontext=%s\n" 05977 "exten=%s\n" 05978 "rdnis=%s\n" 05979 "priority=%d\n" 05980 "callerchan=%s\n" 05981 "callerid=%s\n" 05982 "origdate=%s\n" 05983 "origtime=%ld\n" 05984 "category=%s\n", 05985 ext, 05986 chan->context, 05987 chan->macrocontext, 05988 chan->exten, 05989 S_COR(chan->redirecting.from.number.valid, 05990 chan->redirecting.from.number.str, "unknown"), 05991 chan->priority, 05992 chan->name, 05993 callerid, 05994 date, (long) time(NULL), 05995 category ? category : ""); 05996 } else { 05997 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05998 inprocess_count(vmu->mailbox, vmu->context, -1); 05999 if (ast_check_realtime("voicemail_data")) { 06000 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06001 } 06002 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 06003 goto leave_vm_out; 06004 } 06005 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 06006 06007 if (txt) { 06008 fprintf(txt, "flag=%s\n", flag); 06009 if (sound_duration < vmu->minsecs) { 06010 fclose(txt); 06011 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06012 ast_filedelete(tmptxtfile, NULL); 06013 unlink(tmptxtfile); 06014 if (ast_check_realtime("voicemail_data")) { 06015 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06016 } 06017 inprocess_count(vmu->mailbox, vmu->context, -1); 06018 } else { 06019 fprintf(txt, "duration=%d\n", duration); 06020 fclose(txt); 06021 if (vm_lock_path(dir)) { 06022 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06023 /* Delete files */ 06024 ast_filedelete(tmptxtfile, NULL); 06025 unlink(tmptxtfile); 06026 inprocess_count(vmu->mailbox, vmu->context, -1); 06027 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06028 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06029 unlink(tmptxtfile); 06030 ast_unlock_path(dir); 06031 inprocess_count(vmu->mailbox, vmu->context, -1); 06032 if (ast_check_realtime("voicemail_data")) { 06033 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06034 } 06035 } else { 06036 #ifndef IMAP_STORAGE 06037 msgnum = last_message_index(vmu, dir) + 1; 06038 #endif 06039 make_file(fn, sizeof(fn), dir, msgnum); 06040 06041 /* assign a variable with the name of the voicemail file */ 06042 #ifndef IMAP_STORAGE 06043 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06044 #else 06045 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06046 #endif 06047 06048 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06049 ast_filerename(tmptxtfile, fn, NULL); 06050 rename(tmptxtfile, txtfile); 06051 inprocess_count(vmu->mailbox, vmu->context, -1); 06052 06053 /* Properly set permissions on voicemail text descriptor file. 06054 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06055 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06056 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06057 06058 ast_unlock_path(dir); 06059 if (ast_check_realtime("voicemail_data")) { 06060 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06061 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06062 } 06063 /* We must store the file first, before copying the message, because 06064 * ODBC storage does the entire copy with SQL. 06065 */ 06066 if (ast_fileexists(fn, NULL, NULL) > 0) { 06067 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06068 } 06069 06070 /* Are there to be more recipients of this message? */ 06071 while (tmpptr) { 06072 struct ast_vm_user recipu, *recip; 06073 char *exten, *cntx; 06074 06075 exten = strsep(&tmpptr, "&"); 06076 cntx = strchr(exten, '@'); 06077 if (cntx) { 06078 *cntx = '\0'; 06079 cntx++; 06080 } 06081 if ((recip = find_user(&recipu, cntx, exten))) { 06082 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06083 free_user(recip); 06084 } 06085 } 06086 #ifndef IMAP_STORAGE 06087 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06088 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06089 char sfn[PATH_MAX]; 06090 char dfn[PATH_MAX]; 06091 int x; 06092 /* It's easier just to try to make it than to check for its existence */ 06093 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06094 x = last_message_index(vmu, urgdir) + 1; 06095 make_file(sfn, sizeof(sfn), dir, msgnum); 06096 make_file(dfn, sizeof(dfn), urgdir, x); 06097 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06098 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06099 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06100 ast_copy_string(fn, dfn, sizeof(fn)); 06101 msgnum = x; 06102 } 06103 #endif 06104 /* Notification needs to happen after the copy, though. */ 06105 if (ast_fileexists(fn, NULL, NULL)) { 06106 #ifdef IMAP_STORAGE 06107 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06108 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06109 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06110 flag); 06111 #else 06112 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06113 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06114 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06115 flag); 06116 #endif 06117 } 06118 06119 /* Disposal needs to happen after the optional move and copy */ 06120 if (ast_fileexists(fn, NULL, NULL)) { 06121 DISPOSE(dir, msgnum); 06122 } 06123 } 06124 } 06125 } else { 06126 inprocess_count(vmu->mailbox, vmu->context, -1); 06127 } 06128 if (res == '0') { 06129 goto transfer; 06130 } else if (res > 0 && res != 't') 06131 res = 0; 06132 06133 if (sound_duration < vmu->minsecs) 06134 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06135 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06136 else 06137 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06138 } else 06139 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06140 leave_vm_out: 06141 free_user(vmu); 06142 06143 #ifdef IMAP_STORAGE 06144 /* expunge message - use UID Expunge if supported on IMAP server*/ 06145 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06146 if (expungeonhangup == 1) { 06147 ast_mutex_lock(&vms->lock); 06148 #ifdef HAVE_IMAP_TK2006 06149 if (LEVELUIDPLUS (vms->mailstream)) { 06150 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06151 } else 06152 #endif 06153 mail_expunge(vms->mailstream); 06154 ast_mutex_unlock(&vms->lock); 06155 } 06156 #endif 06157 06158 ast_free(tmp); 06159 return res; 06160 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11838 of file app_voicemail_imapstorage.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().
11839 { 11840 struct ast_config *cfg, *ucfg; 11841 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11842 int res; 11843 11844 ast_unload_realtime("voicemail"); 11845 ast_unload_realtime("voicemail_data"); 11846 11847 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11848 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11849 return 0; 11850 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11851 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11852 ucfg = NULL; 11853 } 11854 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11855 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11856 ast_config_destroy(ucfg); 11857 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11858 return 0; 11859 } 11860 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11861 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11862 return 0; 11863 } else { 11864 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11865 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11866 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11867 ucfg = NULL; 11868 } 11869 } 11870 11871 res = actual_load_config(reload, cfg, ucfg); 11872 11873 ast_config_destroy(cfg); 11874 ast_config_destroy(ucfg); 11875 11876 return res; 11877 }
static int load_module | ( | void | ) | [static] |
Definition at line 13138 of file app_voicemail_imapstorage.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), AST_LOG_WARNING, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_hash_fn(), load_config(), manager_list_voicemail_users(), messagecount(), RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_exec(), vm_execmain(), vmauthenticate(), and vmsayname_exec().
13139 { 13140 int res; 13141 my_umask = umask(0); 13142 umask(my_umask); 13143 13144 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13145 return AST_MODULE_LOAD_DECLINE; 13146 } 13147 13148 /* compute the location of the voicemail spool directory */ 13149 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13150 13151 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13152 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13153 } 13154 13155 if ((res = load_config(0))) 13156 return res; 13157 13158 res = ast_register_application_xml(app, vm_exec); 13159 res |= ast_register_application_xml(app2, vm_execmain); 13160 res |= ast_register_application_xml(app3, vm_box_exists); 13161 res |= ast_register_application_xml(app4, vmauthenticate); 13162 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13163 res |= ast_custom_function_register(&mailbox_exists_acf); 13164 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13165 #ifdef TEST_FRAMEWORK 13166 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13167 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13168 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13169 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13170 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13171 #endif 13172 13173 if (res) 13174 return res; 13175 13176 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13177 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13178 13179 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13180 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13181 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13182 13183 return res; 13184 }
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 1646 of file app_voicemail_imapstorage.c.
Referenced by copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01647 { 01648 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01649 }
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 4541 of file app_voicemail_imapstorage.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(), check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ENDL, ast_vm_user::fullname, 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().
04542 { 04543 char date[256]; 04544 char host[MAXHOSTNAMELEN] = ""; 04545 char who[256]; 04546 char bound[256]; 04547 char dur[256]; 04548 struct ast_tm tm; 04549 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04550 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04551 char *greeting_attachment; 04552 char filename[256]; 04553 04554 if (!str1 || !str2) { 04555 ast_free(str1); 04556 ast_free(str2); 04557 return; 04558 } 04559 04560 if (cidnum) { 04561 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04562 } 04563 if (cidname) { 04564 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04565 } 04566 gethostname(host, sizeof(host) - 1); 04567 04568 if (strchr(srcemail, '@')) { 04569 ast_copy_string(who, srcemail, sizeof(who)); 04570 } else { 04571 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04572 } 04573 04574 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04575 if (greeting_attachment) { 04576 *greeting_attachment++ = '\0'; 04577 } 04578 04579 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04580 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04581 fprintf(p, "Date: %s" ENDL, date); 04582 04583 /* Set date format for voicemail mail */ 04584 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04585 04586 if (!ast_strlen_zero(fromstring)) { 04587 struct ast_channel *ast; 04588 if ((ast = ast_dummy_channel_alloc())) { 04589 char *ptr; 04590 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04591 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04592 04593 if (check_mime(ast_str_buffer(str1))) { 04594 int first_line = 1; 04595 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04596 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04597 *ptr = '\0'; 04598 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04599 first_line = 0; 04600 /* Substring is smaller, so this will never grow */ 04601 ast_str_set(&str2, 0, "%s", ptr + 1); 04602 } 04603 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04604 } else { 04605 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04606 } 04607 ast = ast_channel_unref(ast); 04608 } else { 04609 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04610 } 04611 } else { 04612 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04613 } 04614 04615 if (check_mime(vmu->fullname)) { 04616 int first_line = 1; 04617 char *ptr; 04618 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04619 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04620 *ptr = '\0'; 04621 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04622 first_line = 0; 04623 /* Substring is smaller, so this will never grow */ 04624 ast_str_set(&str2, 0, "%s", ptr + 1); 04625 } 04626 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04627 } else { 04628 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04629 } 04630 04631 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04632 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04633 struct ast_channel *ast; 04634 if ((ast = ast_dummy_channel_alloc())) { 04635 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04636 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04637 if (check_mime(ast_str_buffer(str1))) { 04638 int first_line = 1; 04639 char *ptr; 04640 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04641 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04642 *ptr = '\0'; 04643 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04644 first_line = 0; 04645 /* Substring is smaller, so this will never grow */ 04646 ast_str_set(&str2, 0, "%s", ptr + 1); 04647 } 04648 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04649 } else { 04650 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04651 } 04652 ast = ast_channel_unref(ast); 04653 } else { 04654 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04655 } 04656 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04657 if (ast_strlen_zero(flag)) { 04658 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04659 } else { 04660 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04661 } 04662 } else { 04663 if (ast_strlen_zero(flag)) { 04664 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04665 } else { 04666 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04667 } 04668 } 04669 04670 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04671 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04672 if (imap) { 04673 /* additional information needed for IMAP searching */ 04674 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04675 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04676 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04677 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04678 #ifdef IMAP_STORAGE 04679 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04680 #else 04681 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04682 #endif 04683 /* flag added for Urgent */ 04684 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04685 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04686 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04687 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04688 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04689 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04690 if (!ast_strlen_zero(category)) { 04691 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04692 } else { 04693 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04694 } 04695 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04696 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04697 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04698 } 04699 if (!ast_strlen_zero(cidnum)) { 04700 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04701 } 04702 if (!ast_strlen_zero(cidname)) { 04703 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04704 } 04705 fprintf(p, "MIME-Version: 1.0" ENDL); 04706 if (attach_user_voicemail) { 04707 /* Something unique. */ 04708 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04709 (int) getpid(), (unsigned int) ast_random()); 04710 04711 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04712 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04713 fprintf(p, "--%s" ENDL, bound); 04714 } 04715 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04716 if (emailbody || vmu->emailbody) { 04717 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04718 struct ast_channel *ast; 04719 if ((ast = ast_dummy_channel_alloc())) { 04720 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04721 ast_str_substitute_variables(&str1, 0, ast, e_body); 04722 #ifdef IMAP_STORAGE 04723 { 04724 /* Convert body to native line terminators for IMAP backend */ 04725 char *line = ast_str_buffer(str1), *next; 04726 do { 04727 /* Terminate line before outputting it to the file */ 04728 if ((next = strchr(line, '\n'))) { 04729 *next++ = '\0'; 04730 } 04731 fprintf(p, "%s" ENDL, line); 04732 line = next; 04733 } while (!ast_strlen_zero(line)); 04734 } 04735 #else 04736 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04737 #endif 04738 ast = ast_channel_unref(ast); 04739 } else { 04740 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04741 } 04742 } else if (msgnum > -1) { 04743 if (strcmp(vmu->mailbox, mailbox)) { 04744 /* Forwarded type */ 04745 struct ast_config *msg_cfg; 04746 const char *v; 04747 int inttime; 04748 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04749 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04750 /* Retrieve info from VM attribute file */ 04751 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04752 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04753 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04754 strcat(fromfile, ".txt"); 04755 } 04756 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04757 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04758 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04759 } 04760 04761 /* You might be tempted to do origdate, except that a) it's in the wrong 04762 * format, and b) it's missing for IMAP recordings. */ 04763 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04764 struct timeval tv = { inttime, }; 04765 struct ast_tm tm; 04766 ast_localtime(&tv, &tm, NULL); 04767 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04768 } 04769 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04770 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04771 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04772 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04773 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04774 date, origcallerid, origdate); 04775 ast_config_destroy(msg_cfg); 04776 } else { 04777 goto plain_message; 04778 } 04779 } else { 04780 plain_message: 04781 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04782 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04783 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04784 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04785 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04786 } 04787 } else { 04788 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04789 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04790 } 04791 04792 if (imap || attach_user_voicemail) { 04793 if (!ast_strlen_zero(attach2)) { 04794 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04795 ast_debug(5, "creating second attachment filename %s\n", filename); 04796 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04797 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04798 ast_debug(5, "creating attachment filename %s\n", filename); 04799 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04800 } else { 04801 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04802 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04803 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04804 } 04805 } 04806 ast_free(str1); 04807 ast_free(str2); 04808 }
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 1663 of file app_voicemail_imapstorage.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().
01664 { 01665 return snprintf(dest, len, "%s/msg%04d", dir, num); 01666 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11669 of file app_voicemail_imapstorage.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, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, ast_vm_user::saydurationm, ast_vm_user::serveremail, ast_vm_user::uniqueid, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_OPERATOR, VM_REVIEW, VM_SAYCID, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by load_module().
11670 { 11671 struct ast_vm_user *vmu = NULL; 11672 const char *id = astman_get_header(m, "ActionID"); 11673 char actionid[128] = ""; 11674 11675 if (!ast_strlen_zero(id)) 11676 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11677 11678 AST_LIST_LOCK(&users); 11679 11680 if (AST_LIST_EMPTY(&users)) { 11681 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11682 AST_LIST_UNLOCK(&users); 11683 return RESULT_SUCCESS; 11684 } 11685 11686 astman_send_ack(s, m, "Voicemail user list will follow"); 11687 11688 AST_LIST_TRAVERSE(&users, vmu, list) { 11689 char dirname[256]; 11690 11691 #ifdef IMAP_STORAGE 11692 int new, old; 11693 inboxcount(vmu->mailbox, &new, &old); 11694 #endif 11695 11696 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11697 astman_append(s, 11698 "%s" 11699 "Event: VoicemailUserEntry\r\n" 11700 "VMContext: %s\r\n" 11701 "VoiceMailbox: %s\r\n" 11702 "Fullname: %s\r\n" 11703 "Email: %s\r\n" 11704 "Pager: %s\r\n" 11705 "ServerEmail: %s\r\n" 11706 "MailCommand: %s\r\n" 11707 "Language: %s\r\n" 11708 "TimeZone: %s\r\n" 11709 "Callback: %s\r\n" 11710 "Dialout: %s\r\n" 11711 "UniqueID: %s\r\n" 11712 "ExitContext: %s\r\n" 11713 "SayDurationMinimum: %d\r\n" 11714 "SayEnvelope: %s\r\n" 11715 "SayCID: %s\r\n" 11716 "AttachMessage: %s\r\n" 11717 "AttachmentFormat: %s\r\n" 11718 "DeleteMessage: %s\r\n" 11719 "VolumeGain: %.2f\r\n" 11720 "CanReview: %s\r\n" 11721 "CallOperator: %s\r\n" 11722 "MaxMessageCount: %d\r\n" 11723 "MaxMessageLength: %d\r\n" 11724 "NewMessageCount: %d\r\n" 11725 #ifdef IMAP_STORAGE 11726 "OldMessageCount: %d\r\n" 11727 "IMAPUser: %s\r\n" 11728 #endif 11729 "\r\n", 11730 actionid, 11731 vmu->context, 11732 vmu->mailbox, 11733 vmu->fullname, 11734 vmu->email, 11735 vmu->pager, 11736 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11737 mailcmd, 11738 vmu->language, 11739 vmu->zonetag, 11740 vmu->callback, 11741 vmu->dialout, 11742 vmu->uniqueid, 11743 vmu->exit, 11744 vmu->saydurationm, 11745 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11746 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11747 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11748 vmu->attachfmt, 11749 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11750 vmu->volgain, 11751 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11752 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11753 vmu->maxmsg, 11754 vmu->maxsecs, 11755 #ifdef IMAP_STORAGE 11756 new, old, vmu->imapuser 11757 #else 11758 count_messages(vmu, dirname) 11759 #endif 11760 ); 11761 } 11762 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11763 11764 AST_LIST_UNLOCK(&users); 11765 11766 return RESULT_SUCCESS; 11767 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11490 of file app_voicemail_imapstorage.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), and poll_subscribed_mailboxes().
Referenced by start_poll_thread().
11491 { 11492 while (poll_thread_run) { 11493 struct timespec ts = { 0, }; 11494 struct timeval wait; 11495 11496 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11497 ts.tv_sec = wait.tv_sec; 11498 ts.tv_nsec = wait.tv_usec * 1000; 11499 11500 ast_mutex_lock(&poll_lock); 11501 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11502 ast_mutex_unlock(&poll_lock); 11503 11504 if (!poll_thread_run) 11505 break; 11506 11507 poll_subscribed_mailboxes(); 11508 } 11509 11510 return NULL; 11511 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1724 of file app_voicemail_imapstorage.c.
References ARRAY_LEN.
Referenced by acf_mailbox_exists(), adsi_load_vmail(), copy_message(), get_folder(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().
01725 { 01726 #ifdef IMAP_STORAGE 01727 if (vmu && id == 0) { 01728 return vmu->imapfolder; 01729 } 01730 #endif 01731 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01732 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5391 of file app_voicemail_imapstorage.c.
References __has_voicemail().
Referenced by load_module().
05392 { 05393 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05394 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11513 of file app_voicemail_imapstorage.c.
References ast_free.
Referenced by handle_unsubscribe().
11514 { 11515 ast_free(mwi_sub); 11516 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11601 of file app_voicemail_imapstorage.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, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11602 { 11603 struct mwi_sub_task *mwist; 11604 11605 if (ast_event_get_type(event) != AST_EVENT_SUB) 11606 return; 11607 11608 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11609 return; 11610 11611 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11612 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11613 return; 11614 } 11615 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11616 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11617 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11618 11619 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11620 ast_free(mwist); 11621 } 11622 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11575 of file app_voicemail_imapstorage.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, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
11576 { 11577 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11578 11579 if (!uniqueid) { 11580 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11581 return; 11582 } 11583 11584 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11585 ast_free(uniqueid); 11586 return; 11587 } 11588 11589 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11590 ast_free(uniqueid); 11591 return; 11592 } 11593 11594 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11595 *uniqueid = u; 11596 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11597 ast_free(uniqueid); 11598 } 11599 }
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 7074 of file app_voicemail_imapstorage.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, VM_ATTACH, vm_delete(), and VM_DELETE.
Referenced by copy_message(), and leave_voicemail().
07075 { 07076 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07077 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07078 const char *category; 07079 char *myserveremail = serveremail; 07080 07081 ast_channel_lock(chan); 07082 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07083 category = ast_strdupa(category); 07084 } 07085 ast_channel_unlock(chan); 07086 07087 #ifndef IMAP_STORAGE 07088 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07089 #else 07090 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07091 #endif 07092 make_file(fn, sizeof(fn), todir, msgnum); 07093 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07094 07095 if (!ast_strlen_zero(vmu->attachfmt)) { 07096 if (strstr(fmt, vmu->attachfmt)) 07097 fmt = vmu->attachfmt; 07098 else 07099 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); 07100 } 07101 07102 /* Attach only the first format */ 07103 fmt = ast_strdupa(fmt); 07104 stringp = fmt; 07105 strsep(&stringp, "|"); 07106 07107 if (!ast_strlen_zero(vmu->serveremail)) 07108 myserveremail = vmu->serveremail; 07109 07110 if (!ast_strlen_zero(vmu->email)) { 07111 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07112 07113 if (attach_user_voicemail) 07114 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07115 07116 /* XXX possible imap issue, should category be NULL XXX */ 07117 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07118 07119 if (attach_user_voicemail) 07120 DISPOSE(todir, msgnum); 07121 } 07122 07123 if (!ast_strlen_zero(vmu->pager)) { 07124 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07125 } 07126 07127 if (ast_test_flag(vmu, VM_DELETE)) 07128 DELETE(todir, msgnum, fn, vmu); 07129 07130 /* Leave voicemail for someone */ 07131 if (ast_app_has_voicemail(ext_context, NULL)) 07132 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07133 07134 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07135 07136 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); 07137 run_externnotify(vmu->context, vmu->mailbox, flag); 07138 07139 #ifdef IMAP_STORAGE 07140 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07141 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07142 vm_imap_delete(NULL, vms->curmsg, vmu); 07143 vms->newmessages--; /* Fix new message count */ 07144 } 07145 #endif 07146 07147 return 0; 07148 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4261 of file app_voicemail_imapstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04262 { 04263 if (bio->linelength >= BASELINELEN) { 04264 if (fputs(ENDL, so) == EOF) { 04265 return -1; 04266 } 04267 04268 bio->linelength = 0; 04269 } 04270 04271 if (putc(((unsigned char) c), so) == EOF) { 04272 return -1; 04273 } 04274 04275 bio->linelength++; 04276 04277 return 1; 04278 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7923 of file app_voicemail_imapstorage.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().
07924 { 07925 int count_msg, last_msg; 07926 07927 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07928 07929 /* Rename the member vmbox HERE so that we don't try to return before 07930 * we know what's going on. 07931 */ 07932 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07933 07934 /* Faster to make the directory than to check if it exists. */ 07935 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07936 07937 /* traverses directory using readdir (or select query for ODBC) */ 07938 count_msg = count_messages(vmu, vms->curdir); 07939 if (count_msg < 0) { 07940 return count_msg; 07941 } else { 07942 vms->lastmsg = count_msg - 1; 07943 } 07944 07945 if (vm_allocate_dh(vms, vmu, count_msg)) { 07946 return -1; 07947 } 07948 07949 /* 07950 The following test is needed in case sequencing gets messed up. 07951 There appears to be more than one way to mess up sequence, so 07952 we will not try to find all of the root causes--just fix it when 07953 detected. 07954 */ 07955 07956 if (vm_lock_path(vms->curdir)) { 07957 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07958 return ERROR_LOCK_PATH; 07959 } 07960 07961 /* for local storage, checks directory for messages up to maxmsg limit */ 07962 last_msg = last_message_index(vmu, vms->curdir); 07963 ast_unlock_path(vms->curdir); 07964 07965 if (last_msg < -1) { 07966 return last_msg; 07967 } else if (vms->lastmsg != last_msg) { 07968 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); 07969 resequence_mailbox(vmu, vms->curdir, count_msg); 07970 } 07971 07972 return 0; 07973 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7697 of file app_voicemail_imapstorage.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().
07698 { 07699 int res = 0; 07700 char filename[256], *cid; 07701 const char *origtime, *context, *category, *duration, *flag; 07702 struct ast_config *msg_cfg; 07703 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07704 07705 vms->starting = 0; 07706 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07707 adsi_message(chan, vms); 07708 if (!vms->curmsg) { 07709 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07710 } else if (vms->curmsg == vms->lastmsg) { 07711 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07712 } 07713 07714 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07715 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07716 msg_cfg = ast_config_load(filename, config_flags); 07717 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07718 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07719 return 0; 07720 } 07721 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07722 07723 /* Play the word urgent if we are listening to urgent messages */ 07724 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07725 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07726 } 07727 07728 if (!res) { 07729 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07730 /* POLISH syntax */ 07731 if (!strncasecmp(chan->language, "pl", 2)) { 07732 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07733 int ten, one; 07734 char nextmsg[256]; 07735 ten = (vms->curmsg + 1) / 10; 07736 one = (vms->curmsg + 1) % 10; 07737 07738 if (vms->curmsg < 20) { 07739 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07740 res = wait_file2(chan, vms, nextmsg); 07741 } else { 07742 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07743 res = wait_file2(chan, vms, nextmsg); 07744 if (one > 0) { 07745 if (!res) { 07746 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07747 res = wait_file2(chan, vms, nextmsg); 07748 } 07749 } 07750 } 07751 } 07752 if (!res) 07753 res = wait_file2(chan, vms, "vm-message"); 07754 /* HEBREW syntax */ 07755 } else if (!strncasecmp(chan->language, "he", 2)) { 07756 if (!vms->curmsg) { 07757 res = wait_file2(chan, vms, "vm-message"); 07758 res = wait_file2(chan, vms, "vm-first"); 07759 } else if (vms->curmsg == vms->lastmsg) { 07760 res = wait_file2(chan, vms, "vm-message"); 07761 res = wait_file2(chan, vms, "vm-last"); 07762 } else { 07763 res = wait_file2(chan, vms, "vm-message"); 07764 res = wait_file2(chan, vms, "vm-number"); 07765 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07766 } 07767 /* VIETNAMESE syntax */ 07768 } else if (!strncasecmp(chan->language, "vi", 2)) { 07769 if (!vms->curmsg) { 07770 res = wait_file2(chan, vms, "vm-message"); 07771 res = wait_file2(chan, vms, "vm-first"); 07772 } else if (vms->curmsg == vms->lastmsg) { 07773 res = wait_file2(chan, vms, "vm-message"); 07774 res = wait_file2(chan, vms, "vm-last"); 07775 } else { 07776 res = wait_file2(chan, vms, "vm-message"); 07777 res = wait_file2(chan, vms, "vm-number"); 07778 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07779 } 07780 } else { 07781 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07782 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07783 } else { /* DEFAULT syntax */ 07784 res = wait_file2(chan, vms, "vm-message"); 07785 } 07786 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07787 if (!res) { 07788 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07789 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07790 } 07791 } 07792 } 07793 } 07794 07795 if (!msg_cfg) { 07796 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07797 return 0; 07798 } 07799 07800 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07801 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07802 DISPOSE(vms->curdir, vms->curmsg); 07803 ast_config_destroy(msg_cfg); 07804 return 0; 07805 } 07806 07807 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07808 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07809 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07810 07811 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07812 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07813 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07814 if (!res) { 07815 res = play_message_category(chan, category); 07816 } 07817 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07818 res = play_message_datetime(chan, vmu, origtime, filename); 07819 } 07820 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07821 res = play_message_callerid(chan, vms, cid, context, 0); 07822 } 07823 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07824 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07825 } 07826 /* Allow pressing '1' to skip envelope / callerid */ 07827 if (res == '1') { 07828 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07829 res = 0; 07830 } 07831 ast_config_destroy(msg_cfg); 07832 07833 if (!res) { 07834 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07835 #ifdef IMAP_STORAGE 07836 ast_mutex_lock(&vms->lock); 07837 #endif 07838 vms->heard[vms->curmsg] = 1; 07839 #ifdef IMAP_STORAGE 07840 ast_mutex_unlock(&vms->lock); 07841 /*IMAP storage stores any prepended message from a forward 07842 * as a separate file from the rest of the message 07843 */ 07844 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07845 wait_file(chan, vms, vms->introfn); 07846 } 07847 #endif 07848 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07849 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07850 res = 0; 07851 } 07852 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07853 } 07854 DISPOSE(vms->curdir, vms->curmsg); 07855 return res; 07856 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7583 of file app_voicemail_imapstorage.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, MAX_NUM_CID_CONTEXTS, and wait_file2().
Referenced by advanced_options(), and play_message().
07584 { 07585 int res = 0; 07586 int i; 07587 char *callerid, *name; 07588 char prefile[PATH_MAX] = ""; 07589 07590 07591 /* If voicemail cid is not enabled, or we didn't get cid or context from 07592 * the attribute file, leave now. 07593 * 07594 * TODO Still need to change this so that if this function is called by the 07595 * message envelope (and someone is explicitly requesting to hear the CID), 07596 * it does not check to see if CID is enabled in the config file. 07597 */ 07598 if ((cid == NULL)||(context == NULL)) 07599 return res; 07600 07601 /* Strip off caller ID number from name */ 07602 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07603 ast_callerid_parse(cid, &name, &callerid); 07604 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07605 /* Check for internal contexts and only */ 07606 /* say extension when the call didn't come from an internal context in the list */ 07607 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07608 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07609 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07610 break; 07611 } 07612 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07613 if (!res) { 07614 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07615 if (!ast_strlen_zero(prefile)) { 07616 /* See if we can find a recorded name for this person instead of their extension number */ 07617 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07618 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07619 if (!callback) 07620 res = wait_file2(chan, vms, "vm-from"); 07621 res = ast_stream_and_wait(chan, prefile, ""); 07622 } else { 07623 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07624 /* Say "from extension" as one saying to sound smoother */ 07625 if (!callback) 07626 res = wait_file2(chan, vms, "vm-from-extension"); 07627 res = ast_say_digit_str(chan, callerid, "", chan->language); 07628 } 07629 } 07630 } 07631 } else if (!res) { 07632 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07633 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07634 if (!callback) 07635 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07636 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07637 } 07638 } else { 07639 /* Number unknown */ 07640 ast_debug(1, "VM-CID: From an unknown number\n"); 07641 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07642 res = wait_file2(chan, vms, "vm-unknown-caller"); 07643 } 07644 return res; 07645 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7494 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07495 { 07496 int res = 0; 07497 07498 if (!ast_strlen_zero(category)) 07499 res = ast_play_and_wait(chan, category); 07500 07501 if (res) { 07502 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07503 res = 0; 07504 } 07505 07506 return res; 07507 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7509 of file app_voicemail_imapstorage.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().
07510 { 07511 int res = 0; 07512 struct vm_zone *the_zone = NULL; 07513 time_t t; 07514 07515 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07516 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07517 return 0; 07518 } 07519 07520 /* Does this user have a timezone specified? */ 07521 if (!ast_strlen_zero(vmu->zonetag)) { 07522 /* Find the zone in the list */ 07523 struct vm_zone *z; 07524 AST_LIST_LOCK(&zones); 07525 AST_LIST_TRAVERSE(&zones, z, list) { 07526 if (!strcmp(z->name, vmu->zonetag)) { 07527 the_zone = z; 07528 break; 07529 } 07530 } 07531 AST_LIST_UNLOCK(&zones); 07532 } 07533 07534 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07535 #if 0 07536 /* Set the DIFF_* variables */ 07537 ast_localtime(&t, &time_now, NULL); 07538 tv_now = ast_tvnow(); 07539 ast_localtime(&tv_now, &time_then, NULL); 07540 07541 /* Day difference */ 07542 if (time_now.tm_year == time_then.tm_year) 07543 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07544 else 07545 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07546 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07547 07548 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07549 #endif 07550 if (the_zone) { 07551 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07552 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN 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, "gr", 2)) { /* GREEK syntax */ 07555 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07556 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07557 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); 07558 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07559 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07560 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07561 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07562 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07563 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07564 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07565 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); 07566 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07567 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07568 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07569 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07570 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07571 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); 07572 } else { 07573 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07574 } 07575 #if 0 07576 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07577 #endif 07578 return res; 07579 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7647 of file app_voicemail_imapstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), say_and_wait(), and wait_file2().
Referenced by play_message().
07648 { 07649 int res = 0; 07650 int durationm; 07651 int durations; 07652 /* Verify that we have a duration for the message */ 07653 if (duration == NULL) 07654 return res; 07655 07656 /* Convert from seconds to minutes */ 07657 durations = atoi(duration); 07658 durationm = (durations / 60); 07659 07660 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07661 07662 if ((!res) && (durationm >= minduration)) { 07663 res = wait_file2(chan, vms, "vm-duration"); 07664 07665 /* POLISH syntax */ 07666 if (!strncasecmp(chan->language, "pl", 2)) { 07667 div_t num = div(durationm, 10); 07668 07669 if (durationm == 1) { 07670 res = ast_play_and_wait(chan, "digits/1z"); 07671 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07672 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07673 if (num.rem == 2) { 07674 if (!num.quot) { 07675 res = ast_play_and_wait(chan, "digits/2-ie"); 07676 } else { 07677 res = say_and_wait(chan, durationm - 2 , chan->language); 07678 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07679 } 07680 } else { 07681 res = say_and_wait(chan, durationm, chan->language); 07682 } 07683 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07684 } else { 07685 res = say_and_wait(chan, durationm, chan->language); 07686 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07687 } 07688 /* DEFAULT syntax */ 07689 } else { 07690 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07691 res = wait_file2(chan, vms, "vm-minutes"); 07692 } 07693 } 07694 return res; 07695 }
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 13451 of file app_voicemail_imapstorage.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, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
Referenced by leave_voicemail(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
13454 { 13455 /* Record message & let caller review or re-record it, or set options if applicable */ 13456 int res = 0; 13457 int cmd = 0; 13458 int max_attempts = 3; 13459 int attempts = 0; 13460 int recorded = 0; 13461 int msg_exists = 0; 13462 signed char zero_gain = 0; 13463 char tempfile[PATH_MAX]; 13464 char *acceptdtmf = "#"; 13465 char *canceldtmf = ""; 13466 int canceleddtmf = 0; 13467 13468 /* Note that urgent and private are for flagging messages as such in the future */ 13469 13470 /* barf if no pointer passed to store duration in */ 13471 if (duration == NULL) { 13472 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13473 return -1; 13474 } 13475 13476 if (!outsidecaller) 13477 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13478 else 13479 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13480 13481 cmd = '3'; /* Want to start by recording */ 13482 13483 while ((cmd >= 0) && (cmd != 't')) { 13484 switch (cmd) { 13485 case '1': 13486 if (!msg_exists) { 13487 /* In this case, 1 is to record a message */ 13488 cmd = '3'; 13489 break; 13490 } else { 13491 /* Otherwise 1 is to save the existing message */ 13492 ast_verb(3, "Saving message as is\n"); 13493 if (!outsidecaller) 13494 ast_filerename(tempfile, recordfile, NULL); 13495 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13496 if (!outsidecaller) { 13497 /* Saves to IMAP server only if imapgreeting=yes */ 13498 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13499 DISPOSE(recordfile, -1); 13500 } 13501 cmd = 't'; 13502 return res; 13503 } 13504 case '2': 13505 /* Review */ 13506 ast_verb(3, "Reviewing the message\n"); 13507 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13508 break; 13509 case '3': 13510 msg_exists = 0; 13511 /* Record */ 13512 if (recorded == 1) 13513 ast_verb(3, "Re-recording the message\n"); 13514 else 13515 ast_verb(3, "Recording the message\n"); 13516 13517 if (recorded && outsidecaller) { 13518 cmd = ast_play_and_wait(chan, INTRO); 13519 cmd = ast_play_and_wait(chan, "beep"); 13520 } 13521 recorded = 1; 13522 /* 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 */ 13523 if (record_gain) 13524 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13525 if (ast_test_flag(vmu, VM_OPERATOR)) 13526 canceldtmf = "0"; 13527 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13528 if (strchr(canceldtmf, cmd)) { 13529 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13530 canceleddtmf = 1; 13531 } 13532 if (record_gain) 13533 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13534 if (cmd == -1) { 13535 /* User has hung up, no options to give */ 13536 if (!outsidecaller) { 13537 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13538 ast_filedelete(tempfile, NULL); 13539 } 13540 return cmd; 13541 } 13542 if (cmd == '0') { 13543 break; 13544 } else if (cmd == '*') { 13545 break; 13546 #if 0 13547 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13548 /* Message is too short */ 13549 ast_verb(3, "Message too short\n"); 13550 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13551 cmd = ast_filedelete(tempfile, NULL); 13552 break; 13553 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13554 /* Message is all silence */ 13555 ast_verb(3, "Nothing recorded\n"); 13556 cmd = ast_filedelete(tempfile, NULL); 13557 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13558 if (!cmd) 13559 cmd = ast_play_and_wait(chan, "vm-speakup"); 13560 break; 13561 #endif 13562 } else { 13563 /* If all is well, a message exists */ 13564 msg_exists = 1; 13565 cmd = 0; 13566 } 13567 break; 13568 case '4': 13569 if (outsidecaller) { /* only mark vm messages */ 13570 /* Mark Urgent */ 13571 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13572 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13573 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13574 strcpy(flag, "Urgent"); 13575 } else if (flag) { 13576 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13577 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13578 strcpy(flag, ""); 13579 } else { 13580 ast_play_and_wait(chan, "vm-sorry"); 13581 } 13582 cmd = 0; 13583 } else { 13584 cmd = ast_play_and_wait(chan, "vm-sorry"); 13585 } 13586 break; 13587 case '5': 13588 case '6': 13589 case '7': 13590 case '8': 13591 case '9': 13592 case '*': 13593 case '#': 13594 cmd = ast_play_and_wait(chan, "vm-sorry"); 13595 break; 13596 #if 0 13597 /* XXX Commented out for the moment because of the dangers of deleting 13598 a message while recording (can put the message numbers out of sync) */ 13599 case '*': 13600 /* Cancel recording, delete message, offer to take another message*/ 13601 cmd = ast_play_and_wait(chan, "vm-deleted"); 13602 cmd = ast_filedelete(tempfile, NULL); 13603 if (outsidecaller) { 13604 res = vm_exec(chan, NULL); 13605 return res; 13606 } 13607 else 13608 return 1; 13609 #endif 13610 case '0': 13611 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13612 cmd = ast_play_and_wait(chan, "vm-sorry"); 13613 break; 13614 } 13615 if (msg_exists || recorded) { 13616 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13617 if (!cmd) 13618 cmd = ast_waitfordigit(chan, 3000); 13619 if (cmd == '1') { 13620 ast_filerename(tempfile, recordfile, NULL); 13621 ast_play_and_wait(chan, "vm-msgsaved"); 13622 cmd = '0'; 13623 } else if (cmd == '4') { 13624 if (flag) { 13625 ast_play_and_wait(chan, "vm-marked-urgent"); 13626 strcpy(flag, "Urgent"); 13627 } 13628 ast_play_and_wait(chan, "vm-msgsaved"); 13629 cmd = '0'; 13630 } else { 13631 ast_play_and_wait(chan, "vm-deleted"); 13632 DELETE(tempfile, -1, tempfile, vmu); 13633 cmd = '0'; 13634 } 13635 } 13636 return cmd; 13637 default: 13638 /* If the caller is an ouside caller, and the review option is enabled, 13639 allow them to review the message, but let the owner of the box review 13640 their OGM's */ 13641 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13642 return cmd; 13643 if (msg_exists) { 13644 cmd = ast_play_and_wait(chan, "vm-review"); 13645 if (!cmd && outsidecaller) { 13646 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13647 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13648 } else if (flag) { 13649 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13650 } 13651 } 13652 } else { 13653 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13654 if (!cmd) 13655 cmd = ast_waitfordigit(chan, 600); 13656 } 13657 13658 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13659 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13660 if (!cmd) 13661 cmd = ast_waitfordigit(chan, 600); 13662 } 13663 #if 0 13664 if (!cmd) 13665 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13666 #endif 13667 if (!cmd) 13668 cmd = ast_waitfordigit(chan, 6000); 13669 if (!cmd) { 13670 attempts++; 13671 } 13672 if (attempts > max_attempts) { 13673 cmd = 't'; 13674 } 13675 } 13676 } 13677 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13678 /* Hang up or timeout, so delete the recording. */ 13679 ast_filedelete(tempfile, NULL); 13680 } 13681 13682 if (cmd != 't' && outsidecaller) 13683 ast_play_and_wait(chan, "vm-goodbye"); 13684 13685 return cmd; 13686 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11462 of file app_voicemail_imapstorage.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11463 { 11464 int new = 0, old = 0, urgent = 0; 11465 11466 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11467 11468 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11469 mwi_sub->old_urgent = urgent; 11470 mwi_sub->old_new = new; 11471 mwi_sub->old_old = old; 11472 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11473 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11474 } 11475 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11477 of file app_voicemail_imapstorage.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
11478 { 11479 struct mwi_sub *mwi_sub; 11480 11481 AST_RWLIST_RDLOCK(&mwi_subs); 11482 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11483 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11484 poll_subscribed_mailbox(mwi_sub); 11485 } 11486 } 11487 AST_RWLIST_UNLOCK(&mwi_subs); 11488 }
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 1021 of file app_voicemail_imapstorage.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_free, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by actual_load_config(), append_mailbox(), AST_TEST_DEFINE(), and find_user_realtime().
01022 { 01023 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01024 vmu->passwordlocation = passwordlocation; 01025 if (saydurationminfo) { 01026 vmu->saydurationm = saydurationminfo; 01027 } 01028 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01029 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01030 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01031 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01032 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01033 if (vmminsecs) { 01034 vmu->minsecs = vmminsecs; 01035 } 01036 if (vmmaxsecs) { 01037 vmu->maxsecs = vmmaxsecs; 01038 } 01039 if (maxmsg) { 01040 vmu->maxmsg = maxmsg; 01041 } 01042 if (maxdeletedmsg) { 01043 vmu->maxdeletedmsg = maxdeletedmsg; 01044 } 01045 vmu->volgain = volgain; 01046 ast_free(vmu->emailsubject); 01047 vmu->emailsubject = NULL; 01048 ast_free(vmu->emailbody); 01049 vmu->emailbody = NULL; 01050 #ifdef IMAP_STORAGE 01051 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01052 #endif 01053 }
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 4349 of file app_voicemail_imapstorage.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, 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().
04350 { 04351 char callerid[256]; 04352 char num[12]; 04353 char fromdir[256], fromfile[256]; 04354 struct ast_config *msg_cfg; 04355 const char *origcallerid, *origtime; 04356 char origcidname[80], origcidnum[80], origdate[80]; 04357 int inttime; 04358 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04359 04360 /* Prepare variables for substitution in email body and subject */ 04361 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04362 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04363 snprintf(num, sizeof(num), "%d", msgnum); 04364 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04365 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04366 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04367 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04368 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04369 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04370 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04371 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04372 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04373 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04374 04375 /* Retrieve info from VM attribute file */ 04376 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04377 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04378 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04379 strcat(fromfile, ".txt"); 04380 } 04381 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04382 if (option_debug > 0) { 04383 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04384 } 04385 return; 04386 } 04387 04388 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04389 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04390 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04391 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04392 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04393 } 04394 04395 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04396 struct timeval tv = { inttime, }; 04397 struct ast_tm tm; 04398 ast_localtime(&tv, &tm, NULL); 04399 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04400 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04401 } 04402 ast_config_destroy(msg_cfg); 04403 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7037 of file app_voicemail_imapstorage.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().
07038 { 07039 struct ast_event *event; 07040 char *mailbox, *context; 07041 07042 /* Strip off @default */ 07043 context = mailbox = ast_strdupa(box); 07044 strsep(&context, "@"); 07045 if (ast_strlen_zero(context)) 07046 context = "default"; 07047 07048 if (!(event = ast_event_new(AST_EVENT_MWI, 07049 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07050 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07051 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07052 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07053 AST_EVENT_IE_END))) { 07054 return; 07055 } 07056 07057 ast_event_queue_and_cache(event); 07058 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12568 of file app_voicemail_imapstorage.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().
12568 { 12569 struct ast_config *pwconf; 12570 struct ast_flags config_flags = { 0 }; 12571 12572 pwconf = ast_config_load(secretfn, config_flags); 12573 if (pwconf) { 12574 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12575 if (val) { 12576 ast_copy_string(password, val, passwordlen); 12577 ast_config_destroy(pwconf); 12578 return; 12579 } 12580 ast_config_destroy(pwconf); 12581 } 12582 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12583 }
static int reload | ( | void | ) | [static] |
Definition at line 13098 of file app_voicemail_imapstorage.c.
References load_config().
13099 { 13100 return load_config(1); 13101 }
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 4019 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04020 { 04021 char stxt[PATH_MAX]; 04022 char dtxt[PATH_MAX]; 04023 ast_filerename(sfn, dfn, NULL); 04024 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04025 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04026 if (ast_check_realtime("voicemail_data")) { 04027 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04028 } 04029 rename(stxt, dtxt); 04030 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6163 of file app_voicemail_imapstorage.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().
06164 { 06165 /* we know the actual number of messages, so stop process when number is hit */ 06166 06167 int x, dest; 06168 char sfn[PATH_MAX]; 06169 char dfn[PATH_MAX]; 06170 06171 if (vm_lock_path(dir)) { 06172 return ERROR_LOCK_PATH; 06173 } 06174 06175 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06176 make_file(sfn, sizeof(sfn), dir, x); 06177 if (EXISTS(dir, x, sfn, NULL)) { 06178 06179 if (x != dest) { 06180 make_file(dfn, sizeof(dfn), dir, dest); 06181 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06182 } 06183 06184 dest++; 06185 } 06186 } 06187 ast_unlock_path(dir); 06188 06189 return dest; 06190 }
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 1491 of file app_voicemail_imapstorage.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().
01492 { 01493 /* This function could be made to generate one from a database, too */ 01494 struct ast_vm_user *cur; 01495 int res = -1; 01496 AST_LIST_LOCK(&users); 01497 AST_LIST_TRAVERSE(&users, cur, list) { 01498 if ((!context || !strcasecmp(context, cur->context)) && 01499 (!strcasecmp(mailbox, cur->mailbox))) 01500 break; 01501 } 01502 if (cur) { 01503 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01504 res = 0; 01505 } 01506 AST_LIST_UNLOCK(&users); 01507 return res; 01508 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5534 of file app_voicemail_imapstorage.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait_station(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, ast_smdi_mwi_message::fwd_st, inboxcount2(), and SMDI_MWI_WAIT_TIMEOUT.
Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
05535 { 05536 char arguments[255]; 05537 char ext_context[256] = ""; 05538 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05539 struct ast_smdi_mwi_message *mwi_msg; 05540 05541 if (!ast_strlen_zero(context)) 05542 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05543 else 05544 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05545 05546 if (smdi_iface) { 05547 if (ast_app_has_voicemail(ext_context, NULL)) 05548 ast_smdi_mwi_set(smdi_iface, extension); 05549 else 05550 ast_smdi_mwi_unset(smdi_iface, extension); 05551 05552 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05553 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05554 if (!strncmp(mwi_msg->cause, "INV", 3)) 05555 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05556 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05557 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05558 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05559 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05560 } else { 05561 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05562 } 05563 } 05564 05565 if (!ast_strlen_zero(externnotify)) { 05566 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05567 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05568 } else { 05569 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05570 ast_debug(1, "Executing %s\n", arguments); 05571 ast_safe_system(arguments); 05572 } 05573 } 05574 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6200 of file app_voicemail_imapstorage.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().
06201 { 06202 #ifdef IMAP_STORAGE 06203 /* we must use mbox(x) folder names, and copy the message there */ 06204 /* simple. huh? */ 06205 char sequence[10]; 06206 char mailbox[256]; 06207 int res; 06208 06209 /* get the real IMAP message number for this message */ 06210 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06211 06212 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06213 ast_mutex_lock(&vms->lock); 06214 /* if save to Old folder, put in INBOX as read */ 06215 if (box == OLD_FOLDER) { 06216 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06217 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06218 } else if (box == NEW_FOLDER) { 06219 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06220 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06221 } 06222 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06223 ast_mutex_unlock(&vms->lock); 06224 return 0; 06225 } 06226 /* Create the folder if it don't exist */ 06227 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06228 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06229 if (mail_create(vms->mailstream, mailbox) == NIL) 06230 ast_debug(5, "Folder exists.\n"); 06231 else 06232 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06233 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06234 ast_mutex_unlock(&vms->lock); 06235 return res; 06236 #else 06237 char *dir = vms->curdir; 06238 char *username = vms->username; 06239 char *context = vmu->context; 06240 char sfn[PATH_MAX]; 06241 char dfn[PATH_MAX]; 06242 char ddir[PATH_MAX]; 06243 const char *dbox = mbox(vmu, box); 06244 int x, i; 06245 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06246 06247 if (vm_lock_path(ddir)) 06248 return ERROR_LOCK_PATH; 06249 06250 x = last_message_index(vmu, ddir) + 1; 06251 06252 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06253 x--; 06254 for (i = 1; i <= x; i++) { 06255 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06256 make_file(sfn, sizeof(sfn), ddir, i); 06257 make_file(dfn, sizeof(dfn), ddir, i - 1); 06258 if (EXISTS(ddir, i, sfn, NULL)) { 06259 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06260 } else 06261 break; 06262 } 06263 } else { 06264 if (x >= vmu->maxmsg) { 06265 ast_unlock_path(ddir); 06266 return -1; 06267 } 06268 } 06269 make_file(sfn, sizeof(sfn), dir, msg); 06270 make_file(dfn, sizeof(dfn), ddir, x); 06271 if (strcmp(sfn, dfn)) { 06272 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06273 } 06274 ast_unlock_path(ddir); 06275 #endif 06276 return 0; 06277 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6193 of file app_voicemail_imapstorage.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().
06194 { 06195 int d; 06196 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06197 return d; 06198 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12554 of file app_voicemail_imapstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.
Referenced by load_module(), and vmsayname_exec().
12555 { 12556 int res = -1; 12557 char dir[PATH_MAX]; 12558 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12559 ast_debug(2, "About to try retrieving name file %s\n", dir); 12560 RETRIEVE(dir, -1, mailbox, context); 12561 if (ast_fileexists(dir, NULL, NULL)) { 12562 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12563 } 12564 DISPOSE(dir, -1); 12565 return res; 12566 }
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 4864 of file app_voicemail_imapstorage.c.
References ast_debug, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, ast_vm_user::mailbox, make_email_file(), VM_ATTACH, and vm_mkftemp().
Referenced by forward_message(), and notify_new_message().
04865 { 04866 FILE *p = NULL; 04867 char tmp[80] = "/tmp/astmail-XXXXXX"; 04868 char tmp2[256]; 04869 char *stringp; 04870 04871 if (vmu && ast_strlen_zero(vmu->email)) { 04872 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04873 return(0); 04874 } 04875 04876 /* Mail only the first format */ 04877 format = ast_strdupa(format); 04878 stringp = format; 04879 strsep(&stringp, "|"); 04880 04881 if (!strcmp(format, "wav49")) 04882 format = "WAV"; 04883 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)); 04884 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04885 command hangs */ 04886 if ((p = vm_mkftemp(tmp)) == NULL) { 04887 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04888 return -1; 04889 } else { 04890 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04891 fclose(p); 04892 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04893 ast_safe_system(tmp2); 04894 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04895 } 04896 return 0; 04897 }
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 4899 of file app_voicemail_imapstorage.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, MAXHOSTNAMELEN, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
Referenced by notify_new_message().
04900 { 04901 char enc_cidnum[256], enc_cidname[256]; 04902 char date[256]; 04903 char host[MAXHOSTNAMELEN] = ""; 04904 char who[256]; 04905 char dur[PATH_MAX]; 04906 char tmp[80] = "/tmp/astmail-XXXXXX"; 04907 char tmp2[PATH_MAX]; 04908 struct ast_tm tm; 04909 FILE *p; 04910 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04911 04912 if (!str1 || !str2) { 04913 ast_free(str1); 04914 ast_free(str2); 04915 return -1; 04916 } 04917 04918 if (cidnum) { 04919 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04920 } 04921 if (cidname) { 04922 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04923 } 04924 04925 if ((p = vm_mkftemp(tmp)) == NULL) { 04926 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04927 ast_free(str1); 04928 ast_free(str2); 04929 return -1; 04930 } 04931 gethostname(host, sizeof(host)-1); 04932 if (strchr(srcemail, '@')) { 04933 ast_copy_string(who, srcemail, sizeof(who)); 04934 } else { 04935 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04936 } 04937 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04938 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04939 fprintf(p, "Date: %s\n", date); 04940 04941 /* Reformat for custom pager format */ 04942 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04943 04944 if (!ast_strlen_zero(pagerfromstring)) { 04945 struct ast_channel *ast; 04946 if ((ast = ast_dummy_channel_alloc())) { 04947 char *ptr; 04948 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04949 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04950 04951 if (check_mime(ast_str_buffer(str1))) { 04952 int first_line = 1; 04953 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04954 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04955 *ptr = '\0'; 04956 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04957 first_line = 0; 04958 /* Substring is smaller, so this will never grow */ 04959 ast_str_set(&str2, 0, "%s", ptr + 1); 04960 } 04961 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04962 } else { 04963 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04964 } 04965 ast = ast_channel_unref(ast); 04966 } else { 04967 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04968 } 04969 } else { 04970 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04971 } 04972 04973 if (check_mime(vmu->fullname)) { 04974 int first_line = 1; 04975 char *ptr; 04976 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04977 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04978 *ptr = '\0'; 04979 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04980 first_line = 0; 04981 /* Substring is smaller, so this will never grow */ 04982 ast_str_set(&str2, 0, "%s", ptr + 1); 04983 } 04984 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04985 } else { 04986 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04987 } 04988 04989 if (!ast_strlen_zero(pagersubject)) { 04990 struct ast_channel *ast; 04991 if ((ast = ast_dummy_channel_alloc())) { 04992 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04993 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04994 if (check_mime(ast_str_buffer(str1))) { 04995 int first_line = 1; 04996 char *ptr; 04997 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04998 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04999 *ptr = '\0'; 05000 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05001 first_line = 0; 05002 /* Substring is smaller, so this will never grow */ 05003 ast_str_set(&str2, 0, "%s", ptr + 1); 05004 } 05005 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05006 } else { 05007 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 05008 } 05009 ast = ast_channel_unref(ast); 05010 } else { 05011 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05012 } 05013 } else { 05014 if (ast_strlen_zero(flag)) { 05015 fprintf(p, "Subject: New VM\n\n"); 05016 } else { 05017 fprintf(p, "Subject: New %s VM\n\n", flag); 05018 } 05019 } 05020 05021 if (pagerbody) { 05022 struct ast_channel *ast; 05023 if ((ast = ast_dummy_channel_alloc())) { 05024 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05025 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05026 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05027 ast = ast_channel_unref(ast); 05028 } else { 05029 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05030 } 05031 } else { 05032 fprintf(p, "New %s long %s msg in box %s\n" 05033 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05034 } 05035 05036 fclose(p); 05037 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05038 ast_safe_system(tmp2); 05039 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05040 ast_free(str1); 05041 ast_free(str2); 05042 return 0; 05043 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11119 of file app_voicemail_imapstorage.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().
11120 { 11121 struct ast_config *cfg; 11122 const char *cat = NULL; 11123 11124 if (!(cfg = ast_load_realtime_multientry("voicemail", 11125 "context", context, SENTINEL))) { 11126 return CLI_FAILURE; 11127 } 11128 11129 ast_cli(fd, 11130 "\n" 11131 "=============================================================\n" 11132 "=== Configured Voicemail Users ==============================\n" 11133 "=============================================================\n" 11134 "===\n"); 11135 11136 while ((cat = ast_category_browse(cfg, cat))) { 11137 struct ast_variable *var = NULL; 11138 ast_cli(fd, 11139 "=== Mailbox ...\n" 11140 "===\n"); 11141 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11142 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11143 ast_cli(fd, 11144 "===\n" 11145 "=== ---------------------------------------------------------\n" 11146 "===\n"); 11147 } 11148 11149 ast_cli(fd, 11150 "=============================================================\n" 11151 "\n"); 11152 11153 ast_config_destroy(cfg); 11154 11155 return CLI_SUCCESS; 11156 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11624 of file app_voicemail_imapstorage.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(), and mwi_unsub_event_cb().
Referenced by actual_load_config().
11625 { 11626 int errcode; 11627 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11628 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11629 AST_EVENT_IE_END); 11630 11631 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11632 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11633 AST_EVENT_IE_END); 11634 11635 if (mwi_sub_sub) 11636 ast_event_report_subs(mwi_sub_sub); 11637 11638 poll_thread_run = 1; 11639 11640 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11641 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11642 } 11643 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11645 of file app_voicemail_imapstorage.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, and AST_PTHREADT_NULL.
Referenced by actual_load_config(), and unload_module().
11646 { 11647 poll_thread_run = 0; 11648 11649 if (mwi_sub_sub) { 11650 ast_event_unsubscribe(mwi_sub_sub); 11651 mwi_sub_sub = NULL; 11652 } 11653 11654 if (mwi_unsub_sub) { 11655 ast_event_unsubscribe(mwi_unsub_sub); 11656 mwi_unsub_sub = NULL; 11657 } 11658 11659 ast_mutex_lock(&poll_lock); 11660 ast_cond_signal(&poll_cond); 11661 ast_mutex_unlock(&poll_lock); 11662 11663 pthread_join(poll_thread, NULL); 11664 11665 poll_thread = AST_PTHREADT_NULL; 11666 }
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 991 of file app_voicemail_imapstorage.c.
Referenced by make_email_file(), and sendpage().
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11791 of file app_voicemail_imapstorage.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().
11792 { 11793 char *current; 11794 11795 /* Add 16 for fudge factor */ 11796 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11797 11798 ast_str_reset(str); 11799 11800 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11801 for (current = (char *) value; *current; current++) { 11802 if (*current == '\\') { 11803 current++; 11804 if (!*current) { 11805 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11806 break; 11807 } 11808 switch (*current) { 11809 case '\\': 11810 ast_str_append(&str, 0, "\\"); 11811 break; 11812 case 'r': 11813 ast_str_append(&str, 0, "\r"); 11814 break; 11815 case 'n': 11816 #ifdef IMAP_STORAGE 11817 if (!str->used || str->str[str->used - 1] != '\r') { 11818 ast_str_append(&str, 0, "\r"); 11819 } 11820 #endif 11821 ast_str_append(&str, 0, "\n"); 11822 break; 11823 case 't': 11824 ast_str_append(&str, 0, "\t"); 11825 break; 11826 default: 11827 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11828 break; 11829 } 11830 } else { 11831 ast_str_append(&str, 0, "%c", *current); 11832 } 11833 } 11834 11835 return ast_str_buffer(str); 11836 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13103 of file app_voicemail_imapstorage.c.
References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), free_vm_users(), free_vm_zones(), and stop_poll_thread().
13104 { 13105 int res; 13106 13107 res = ast_unregister_application(app); 13108 res |= ast_unregister_application(app2); 13109 res |= ast_unregister_application(app3); 13110 res |= ast_unregister_application(app4); 13111 res |= ast_unregister_application(sayname_app); 13112 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13113 res |= ast_manager_unregister("VoicemailUsersList"); 13114 res |= ast_data_unregister(NULL); 13115 #ifdef TEST_FRAMEWORK 13116 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13117 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13118 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13119 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13120 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13121 #endif 13122 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13123 ast_uninstall_vm_functions(); 13124 ao2_ref(inprocess_container, -1); 13125 13126 if (poll_thread != AST_PTHREADT_NULL) 13127 stop_poll_thread(); 13128 13129 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13130 ast_unload_realtime("voicemail"); 13131 ast_unload_realtime("voicemail_data"); 13132 13133 free_vm_users(); 13134 free_vm_zones(); 13135 return res; 13136 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1761 of file app_voicemail_imapstorage.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().
01761 { 01762 01763 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01764 01765 /* remove old allocation */ 01766 if (vms->deleted) { 01767 ast_free(vms->deleted); 01768 vms->deleted = NULL; 01769 } 01770 if (vms->heard) { 01771 ast_free(vms->heard); 01772 vms->heard = NULL; 01773 } 01774 vms->dh_arraysize = 0; 01775 01776 if (arraysize > 0) { 01777 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01778 return -1; 01779 } 01780 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01781 ast_free(vms->deleted); 01782 vms->deleted = NULL; 01783 return -1; 01784 } 01785 vms->dh_arraysize = arraysize; 01786 } 01787 01788 return 0; 01789 }
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 9795 of file app_voicemail_imapstorage.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, and ast_party_number::valid.
Referenced by vm_execmain(), and vmauthenticate().
09798 { 09799 int useadsi = 0, valid = 0, logretries = 0; 09800 char password[AST_MAX_EXTENSION]="", *passptr; 09801 struct ast_vm_user vmus, *vmu = NULL; 09802 09803 /* If ADSI is supported, setup login screen */ 09804 adsi_begin(chan, &useadsi); 09805 if (!skipuser && useadsi) 09806 adsi_login(chan); 09807 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09808 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09809 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09810 return -1; 09811 } 09812 09813 /* Authenticate them and get their mailbox/password */ 09814 09815 while (!valid && (logretries < max_logins)) { 09816 /* Prompt for, and read in the username */ 09817 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09818 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09819 return -1; 09820 } 09821 if (ast_strlen_zero(mailbox)) { 09822 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09823 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09824 } else { 09825 ast_verb(3, "Username not entered\n"); 09826 return -1; 09827 } 09828 } else if (mailbox[0] == '*') { 09829 /* user entered '*' */ 09830 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09831 if (ast_exists_extension(chan, chan->context, "a", 1, 09832 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09833 return -1; 09834 } 09835 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09836 mailbox[0] = '\0'; 09837 } 09838 09839 if (useadsi) 09840 adsi_password(chan); 09841 09842 if (!ast_strlen_zero(prefix)) { 09843 char fullusername[80] = ""; 09844 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09845 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09846 ast_copy_string(mailbox, fullusername, mailbox_size); 09847 } 09848 09849 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09850 vmu = find_user(&vmus, context, mailbox); 09851 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09852 /* saved password is blank, so don't bother asking */ 09853 password[0] = '\0'; 09854 } else { 09855 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09856 if (ast_streamfile(chan, vm_password, chan->language)) { 09857 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09858 return -1; 09859 } 09860 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09861 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09862 return -1; 09863 } else if (password[0] == '*') { 09864 /* user entered '*' */ 09865 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09866 if (ast_exists_extension(chan, chan->context, "a", 1, 09867 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09868 mailbox[0] = '*'; 09869 return -1; 09870 } 09871 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09872 mailbox[0] = '\0'; 09873 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09874 vmu = NULL; 09875 } 09876 } 09877 09878 if (vmu) { 09879 passptr = vmu->password; 09880 if (passptr[0] == '-') passptr++; 09881 } 09882 if (vmu && !strcmp(passptr, password)) 09883 valid++; 09884 else { 09885 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09886 if (!ast_strlen_zero(prefix)) 09887 mailbox[0] = '\0'; 09888 } 09889 logretries++; 09890 if (!valid) { 09891 if (skipuser || logretries >= max_logins) { 09892 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09893 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09894 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09895 return -1; 09896 } 09897 } else { 09898 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09899 if (useadsi) 09900 adsi_login(chan); 09901 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09902 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09903 return -1; 09904 } 09905 } 09906 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09907 return -1; 09908 } 09909 } 09910 if (!valid && (logretries >= max_logins)) { 09911 ast_stopstream(chan); 09912 ast_play_and_wait(chan, "vm-goodbye"); 09913 return -1; 09914 } 09915 if (vmu && !skipuser) { 09916 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09917 } 09918 return 0; 09919 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11014 of file app_voicemail_imapstorage.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().
11015 { 11016 struct ast_vm_user svm; 11017 char *context, *box; 11018 AST_DECLARE_APP_ARGS(args, 11019 AST_APP_ARG(mbox); 11020 AST_APP_ARG(options); 11021 ); 11022 static int dep_warning = 0; 11023 11024 if (ast_strlen_zero(data)) { 11025 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11026 return -1; 11027 } 11028 11029 if (!dep_warning) { 11030 dep_warning = 1; 11031 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11032 } 11033 11034 box = ast_strdupa(data); 11035 11036 AST_STANDARD_APP_ARGS(args, box); 11037 11038 if (args.options) { 11039 } 11040 11041 if ((context = strchr(args.mbox, '@'))) { 11042 *context = '\0'; 11043 context++; 11044 } 11045 11046 if (find_user(&svm, context, args.mbox)) { 11047 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11048 } else 11049 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11050 11051 return 0; 11052 }
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 9774 of file app_voicemail_imapstorage.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().
09775 { 09776 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09777 return vm_browse_messages_es(chan, vms, vmu); 09778 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09779 return vm_browse_messages_gr(chan, vms, vmu); 09780 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09781 return vm_browse_messages_he(chan, vms, vmu); 09782 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09783 return vm_browse_messages_it(chan, vms, vmu); 09784 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09785 return vm_browse_messages_pt(chan, vms, vmu); 09786 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09787 return vm_browse_messages_vi(chan, vms, vmu); 09788 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09789 return vm_browse_messages_zh(chan, vms, vmu); 09790 } else { /* Default to English syntax */ 09791 return vm_browse_messages_en(chan, vms, vmu); 09792 } 09793 }
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 9613 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09614 { 09615 int cmd = 0; 09616 09617 if (vms->lastmsg > -1) { 09618 cmd = play_message(chan, vmu, vms); 09619 } else { 09620 cmd = ast_play_and_wait(chan, "vm-youhave"); 09621 if (!cmd) 09622 cmd = ast_play_and_wait(chan, "vm-no"); 09623 if (!cmd) { 09624 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09625 cmd = ast_play_and_wait(chan, vms->fn); 09626 } 09627 if (!cmd) 09628 cmd = ast_play_and_wait(chan, "vm-messages"); 09629 } 09630 return cmd; 09631 }
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 9667 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09668 { 09669 int cmd; 09670 09671 if (vms->lastmsg > -1) { 09672 cmd = play_message(chan, vmu, vms); 09673 } else { 09674 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09675 if (!cmd) 09676 cmd = ast_play_and_wait(chan, "vm-messages"); 09677 if (!cmd) { 09678 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09679 cmd = ast_play_and_wait(chan, vms->fn); 09680 } 09681 } 09682 return cmd; 09683 }
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 9561 of file app_voicemail_imapstorage.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().
09562 { 09563 int cmd = 0; 09564 09565 if (vms->lastmsg > -1) { 09566 cmd = play_message(chan, vmu, vms); 09567 } else { 09568 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09569 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09570 if (!cmd) { 09571 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09572 cmd = ast_play_and_wait(chan, vms->fn); 09573 } 09574 if (!cmd) 09575 cmd = ast_play_and_wait(chan, "vm-messages"); 09576 } else { 09577 if (!cmd) 09578 cmd = ast_play_and_wait(chan, "vm-messages"); 09579 if (!cmd) { 09580 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09581 cmd = ast_play_and_wait(chan, vms->fn); 09582 } 09583 } 09584 } 09585 return cmd; 09586 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9589 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09590 { 09591 int cmd = 0; 09592 09593 if (vms->lastmsg > -1) { 09594 cmd = play_message(chan, vmu, vms); 09595 } else { 09596 if (!strcasecmp(vms->fn, "INBOX")) { 09597 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09598 } else { 09599 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09600 } 09601 } 09602 return cmd; 09603 }
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 9641 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09642 { 09643 int cmd; 09644 09645 if (vms->lastmsg > -1) { 09646 cmd = play_message(chan, vmu, vms); 09647 } else { 09648 cmd = ast_play_and_wait(chan, "vm-no"); 09649 if (!cmd) 09650 cmd = ast_play_and_wait(chan, "vm-message"); 09651 if (!cmd) { 09652 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09653 cmd = ast_play_and_wait(chan, vms->fn); 09654 } 09655 } 09656 return cmd; 09657 }
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 9693 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09694 { 09695 int cmd; 09696 09697 if (vms->lastmsg > -1) { 09698 cmd = play_message(chan, vmu, vms); 09699 } else { 09700 cmd = ast_play_and_wait(chan, "vm-no"); 09701 if (!cmd) { 09702 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09703 cmd = ast_play_and_wait(chan, vms->fn); 09704 } 09705 if (!cmd) 09706 cmd = ast_play_and_wait(chan, "vm-messages"); 09707 } 09708 return cmd; 09709 }
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 9747 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09748 { 09749 int cmd = 0; 09750 09751 if (vms->lastmsg > -1) { 09752 cmd = play_message(chan, vmu, vms); 09753 } else { 09754 cmd = ast_play_and_wait(chan, "vm-no"); 09755 if (!cmd) { 09756 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09757 cmd = ast_play_and_wait(chan, vms->fn); 09758 } 09759 } 09760 return cmd; 09761 }
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 9719 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09720 { 09721 int cmd; 09722 09723 if (vms->lastmsg > -1) { 09724 cmd = play_message(chan, vmu, vms); 09725 } else { 09726 cmd = ast_play_and_wait(chan, "vm-you"); 09727 if (!cmd) 09728 cmd = ast_play_and_wait(chan, "vm-haveno"); 09729 if (!cmd) 09730 cmd = ast_play_and_wait(chan, "vm-messages"); 09731 if (!cmd) { 09732 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09733 cmd = ast_play_and_wait(chan, vms->fn); 09734 } 09735 } 09736 return cmd; 09737 }
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 1517 of file app_voicemail_imapstorage.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, VOICEMAIL_CONFIG, and write_password_to_file().
Referenced by vm_newuser(), and vm_options().
01518 { 01519 struct ast_config *cfg = NULL; 01520 struct ast_variable *var = NULL; 01521 struct ast_category *cat = NULL; 01522 char *category = NULL, *value = NULL, *new = NULL; 01523 const char *tmp = NULL; 01524 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01525 char secretfn[PATH_MAX] = ""; 01526 int found = 0; 01527 01528 if (!change_password_realtime(vmu, newpassword)) 01529 return; 01530 01531 /* check if we should store the secret in the spool directory next to the messages */ 01532 switch (vmu->passwordlocation) { 01533 case OPT_PWLOC_SPOOLDIR: 01534 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01535 if (write_password_to_file(secretfn, newpassword) == 0) { 01536 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01537 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01538 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01539 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01540 break; 01541 } else { 01542 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01543 } 01544 /* Fall-through */ 01545 case OPT_PWLOC_VOICEMAILCONF: 01546 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01547 while ((category = ast_category_browse(cfg, category))) { 01548 if (!strcasecmp(category, vmu->context)) { 01549 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01550 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01551 break; 01552 } 01553 value = strstr(tmp, ","); 01554 if (!value) { 01555 new = ast_alloca(strlen(newpassword)+1); 01556 sprintf(new, "%s", newpassword); 01557 } else { 01558 new = ast_alloca((strlen(value) + strlen(newpassword) + 1)); 01559 sprintf(new, "%s%s", newpassword, value); 01560 } 01561 if (!(cat = ast_category_get(cfg, category))) { 01562 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01563 break; 01564 } 01565 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01566 found = 1; 01567 } 01568 } 01569 /* save the results */ 01570 if (found) { 01571 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01572 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01573 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01574 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01575 break; 01576 } 01577 } 01578 /* Fall-through */ 01579 case OPT_PWLOC_USERSCONF: 01580 /* check users.conf and update the password stored for the mailbox */ 01581 /* if no vmsecret entry exists create one. */ 01582 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01583 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01584 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01585 ast_debug(4, "users.conf: %s\n", category); 01586 if (!strcasecmp(category, vmu->mailbox)) { 01587 if (!ast_variable_retrieve(cfg, category, "vmsecret")) { 01588 ast_debug(3, "looks like we need to make vmsecret!\n"); 01589 var = ast_variable_new("vmsecret", newpassword, ""); 01590 } else { 01591 var = NULL; 01592 } 01593 new = ast_alloca(strlen(newpassword) + 1); 01594 sprintf(new, "%s", newpassword); 01595 if (!(cat = ast_category_get(cfg, category))) { 01596 ast_debug(4, "failed to get category!\n"); 01597 ast_free(var); 01598 break; 01599 } 01600 if (!var) { 01601 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01602 } else { 01603 ast_variable_append(cat, var); 01604 } 01605 found = 1; 01606 break; 01607 } 01608 } 01609 /* save the results and clean things up */ 01610 if (found) { 01611 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01612 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01613 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01614 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01615 } 01616 } 01617 } 01618 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1620 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
Referenced by vm_newuser(), and vm_options().
01621 { 01622 char buf[255]; 01623 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01624 ast_debug(1, "External password: %s\n",buf); 01625 if (!ast_safe_system(buf)) { 01626 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01627 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01628 /* Reset the password in memory, too */ 01629 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01630 } 01631 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1188 of file app_voicemail_imapstorage.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().
01189 { 01190 int fds[2], pid = 0; 01191 01192 memset(buf, 0, len); 01193 01194 if (pipe(fds)) { 01195 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01196 } else { 01197 /* good to go*/ 01198 pid = ast_safe_fork(0); 01199 01200 if (pid < 0) { 01201 /* ok maybe not */ 01202 close(fds[0]); 01203 close(fds[1]); 01204 snprintf(buf, len, "FAILURE: Fork failed"); 01205 } else if (pid) { 01206 /* parent */ 01207 close(fds[1]); 01208 if (read(fds[0], buf, len) < 0) { 01209 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01210 } 01211 close(fds[0]); 01212 } else { 01213 /* child */ 01214 AST_DECLARE_APP_ARGS(arg, 01215 AST_APP_ARG(v)[20]; 01216 ); 01217 char *mycmd = ast_strdupa(command); 01218 01219 close(fds[0]); 01220 dup2(fds[1], STDOUT_FILENO); 01221 close(fds[1]); 01222 ast_close_fds_above_n(STDOUT_FILENO); 01223 01224 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01225 01226 execv(arg.v[0], arg.v); 01227 printf("FAILURE: %s", strerror(errno)); 01228 _exit(0); 01229 } 01230 } 01231 return buf; 01232 }
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 4203 of file app_voicemail_imapstorage.c.
References ast_alloca, ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
Referenced by copy_message(), and notify_new_message().
04204 { 04205 char *txt; 04206 int txtsize = 0; 04207 04208 txtsize = (strlen(file) + 5)*sizeof(char); 04209 txt = ast_alloca(txtsize); 04210 /* Sprintf here would safe because we alloca'd exactly the right length, 04211 * but trying to eliminate all sprintf's anyhow 04212 */ 04213 if (ast_check_realtime("voicemail_data")) { 04214 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04215 } 04216 snprintf(txt, txtsize, "%s.txt", file); 04217 unlink(txt); 04218 return ast_filedelete(file, NULL); 04219 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10673 of file app_voicemail_imapstorage.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().
10674 { 10675 int res = 0; 10676 char *tmp; 10677 struct leave_vm_options leave_options; 10678 struct ast_flags flags = { 0 }; 10679 char *opts[OPT_ARG_ARRAY_SIZE]; 10680 AST_DECLARE_APP_ARGS(args, 10681 AST_APP_ARG(argv0); 10682 AST_APP_ARG(argv1); 10683 ); 10684 10685 memset(&leave_options, 0, sizeof(leave_options)); 10686 10687 if (chan->_state != AST_STATE_UP) 10688 ast_answer(chan); 10689 10690 if (!ast_strlen_zero(data)) { 10691 tmp = ast_strdupa(data); 10692 AST_STANDARD_APP_ARGS(args, tmp); 10693 if (args.argc == 2) { 10694 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10695 return -1; 10696 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10697 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10698 int gain; 10699 10700 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10701 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10702 return -1; 10703 } else { 10704 leave_options.record_gain = (signed char) gain; 10705 } 10706 } 10707 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10708 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10709 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10710 } 10711 } 10712 } else { 10713 char temp[256]; 10714 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10715 if (res < 0) 10716 return res; 10717 if (ast_strlen_zero(temp)) 10718 return 0; 10719 args.argv0 = ast_strdupa(temp); 10720 } 10721 10722 res = leave_voicemail(chan, args.argv0, &leave_options); 10723 if (res == 't') { 10724 ast_play_and_wait(chan, "vm-goodbye"); 10725 res = 0; 10726 } 10727 10728 if (res == OPERATOR_EXIT) { 10729 res = 0; 10730 } 10731 10732 if (res == ERROR_LOCK_PATH) { 10733 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10734 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10735 res = 0; 10736 } 10737 10738 return res; 10739 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9921 of file app_voicemail_imapstorage.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(), has_voicemail(), vm_state::heard, language, ast_vm_user::language, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, mbox(), NEW_FOLDER, vm_state::newmessages, OLD_FOLDER, vm_state::oldmessages, open_mailbox(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, parse(), ast_vm_user::password, play_message(), queue_mwi_event(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::urgentmessages, vm_state::username, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), VM_MESSAGEWRAP, vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, and vm_state::vmbox.
Referenced by load_module().
09922 { 09923 /* XXX This is, admittedly, some pretty horrendous code. For some 09924 reason it just seemed a lot easier to do with GOTO's. I feel 09925 like I'm back in my GWBASIC days. XXX */ 09926 int res = -1; 09927 int cmd = 0; 09928 int valid = 0; 09929 char prefixstr[80] =""; 09930 char ext_context[256]=""; 09931 int box; 09932 int useadsi = 0; 09933 int skipuser = 0; 09934 struct vm_state vms; 09935 struct ast_vm_user *vmu = NULL, vmus; 09936 char *context = NULL; 09937 int silentexit = 0; 09938 struct ast_flags flags = { 0 }; 09939 signed char record_gain = 0; 09940 int play_auto = 0; 09941 int play_folder = 0; 09942 int in_urgent = 0; 09943 #ifdef IMAP_STORAGE 09944 int deleted = 0; 09945 #endif 09946 09947 /* Add the vm_state to the active list and keep it active */ 09948 memset(&vms, 0, sizeof(vms)); 09949 09950 vms.lastmsg = -1; 09951 09952 memset(&vmus, 0, sizeof(vmus)); 09953 09954 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09955 if (chan->_state != AST_STATE_UP) { 09956 ast_debug(1, "Before ast_answer\n"); 09957 ast_answer(chan); 09958 } 09959 09960 if (!ast_strlen_zero(data)) { 09961 char *opts[OPT_ARG_ARRAY_SIZE]; 09962 char *parse; 09963 AST_DECLARE_APP_ARGS(args, 09964 AST_APP_ARG(argv0); 09965 AST_APP_ARG(argv1); 09966 ); 09967 09968 parse = ast_strdupa(data); 09969 09970 AST_STANDARD_APP_ARGS(args, parse); 09971 09972 if (args.argc == 2) { 09973 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09974 return -1; 09975 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09976 int gain; 09977 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09978 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09979 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09980 return -1; 09981 } else { 09982 record_gain = (signed char) gain; 09983 } 09984 } else { 09985 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09986 } 09987 } 09988 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09989 play_auto = 1; 09990 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09991 /* See if it is a folder name first */ 09992 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09993 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09994 play_folder = -1; 09995 } 09996 } else { 09997 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09998 } 09999 } else { 10000 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 10001 } 10002 if (play_folder > 9 || play_folder < 0) { 10003 ast_log(AST_LOG_WARNING, 10004 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 10005 opts[OPT_ARG_PLAYFOLDER]); 10006 play_folder = 0; 10007 } 10008 } 10009 } else { 10010 /* old style options parsing */ 10011 while (*(args.argv0)) { 10012 if (*(args.argv0) == 's') 10013 ast_set_flag(&flags, OPT_SILENT); 10014 else if (*(args.argv0) == 'p') 10015 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10016 else 10017 break; 10018 (args.argv0)++; 10019 } 10020 10021 } 10022 10023 valid = ast_test_flag(&flags, OPT_SILENT); 10024 10025 if ((context = strchr(args.argv0, '@'))) 10026 *context++ = '\0'; 10027 10028 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10029 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10030 else 10031 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10032 10033 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10034 skipuser++; 10035 else 10036 valid = 0; 10037 } 10038 10039 if (!valid) 10040 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10041 10042 ast_debug(1, "After vm_authenticate\n"); 10043 10044 if (vms.username[0] == '*') { 10045 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10046 10047 /* user entered '*' */ 10048 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10049 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10050 res = 0; /* prevent hangup */ 10051 goto out; 10052 } 10053 } 10054 10055 if (!res) { 10056 valid = 1; 10057 if (!skipuser) 10058 vmu = &vmus; 10059 } else { 10060 res = 0; 10061 } 10062 10063 /* If ADSI is supported, setup login screen */ 10064 adsi_begin(chan, &useadsi); 10065 10066 ast_test_suite_assert(valid); 10067 if (!valid) { 10068 goto out; 10069 } 10070 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10071 10072 #ifdef IMAP_STORAGE 10073 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10074 pthread_setspecific(ts_vmstate.key, &vms); 10075 10076 vms.interactive = 1; 10077 vms.updated = 1; 10078 if (vmu) 10079 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10080 vmstate_insert(&vms); 10081 init_vm_state(&vms); 10082 #endif 10083 10084 /* Set language from config to override channel language */ 10085 if (!ast_strlen_zero(vmu->language)) 10086 ast_string_field_set(chan, language, vmu->language); 10087 10088 /* Retrieve urgent, old and new message counts */ 10089 ast_debug(1, "Before open_mailbox\n"); 10090 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10091 if (res < 0) 10092 goto out; 10093 vms.oldmessages = vms.lastmsg + 1; 10094 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10095 /* check INBOX */ 10096 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10097 if (res < 0) 10098 goto out; 10099 vms.newmessages = vms.lastmsg + 1; 10100 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10101 /* Start in Urgent */ 10102 in_urgent = 1; 10103 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10104 if (res < 0) 10105 goto out; 10106 vms.urgentmessages = vms.lastmsg + 1; 10107 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10108 10109 /* Select proper mailbox FIRST!! */ 10110 if (play_auto) { 10111 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10112 if (vms.urgentmessages) { 10113 in_urgent = 1; 10114 res = open_mailbox(&vms, vmu, 11); 10115 } else { 10116 in_urgent = 0; 10117 res = open_mailbox(&vms, vmu, play_folder); 10118 } 10119 if (res < 0) 10120 goto out; 10121 10122 /* If there are no new messages, inform the user and hangup */ 10123 if (vms.lastmsg == -1) { 10124 in_urgent = 0; 10125 cmd = vm_browse_messages(chan, &vms, vmu); 10126 res = 0; 10127 goto out; 10128 } 10129 } else { 10130 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10131 /* If we only have old messages start here */ 10132 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10133 in_urgent = 0; 10134 play_folder = 1; 10135 if (res < 0) 10136 goto out; 10137 } else if (!vms.urgentmessages && vms.newmessages) { 10138 /* If we have new messages but none are urgent */ 10139 in_urgent = 0; 10140 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10141 if (res < 0) 10142 goto out; 10143 } 10144 } 10145 10146 if (useadsi) 10147 adsi_status(chan, &vms); 10148 res = 0; 10149 10150 /* Check to see if this is a new user */ 10151 if (!strcasecmp(vmu->mailbox, vmu->password) && 10152 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10153 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10154 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10155 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10156 if ((cmd == 't') || (cmd == '#')) { 10157 /* Timeout */ 10158 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10159 res = 0; 10160 goto out; 10161 } else if (cmd < 0) { 10162 /* Hangup */ 10163 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10164 res = -1; 10165 goto out; 10166 } 10167 } 10168 #ifdef IMAP_STORAGE 10169 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10170 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10171 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10172 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10173 } 10174 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10175 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10176 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10177 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10178 } 10179 #endif 10180 10181 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10182 if (play_auto) { 10183 cmd = '1'; 10184 } else { 10185 cmd = vm_intro(chan, vmu, &vms); 10186 } 10187 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10188 10189 vms.repeats = 0; 10190 vms.starting = 1; 10191 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10192 /* Run main menu */ 10193 switch (cmd) { 10194 case '1': /* First message */ 10195 vms.curmsg = 0; 10196 /* Fall through */ 10197 case '5': /* Play current message */ 10198 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10199 cmd = vm_browse_messages(chan, &vms, vmu); 10200 break; 10201 case '2': /* Change folders */ 10202 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10203 if (useadsi) 10204 adsi_folders(chan, 0, "Change to folder..."); 10205 10206 cmd = get_folder2(chan, "vm-changeto", 0); 10207 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10208 if (cmd == '#') { 10209 cmd = 0; 10210 } else if (cmd > 0) { 10211 cmd = cmd - '0'; 10212 res = close_mailbox(&vms, vmu); 10213 if (res == ERROR_LOCK_PATH) 10214 goto out; 10215 /* If folder is not urgent, set in_urgent to zero! */ 10216 if (cmd != 11) in_urgent = 0; 10217 res = open_mailbox(&vms, vmu, cmd); 10218 if (res < 0) 10219 goto out; 10220 play_folder = cmd; 10221 cmd = 0; 10222 } 10223 if (useadsi) 10224 adsi_status2(chan, &vms); 10225 10226 if (!cmd) { 10227 cmd = vm_play_folder_name(chan, vms.vmbox); 10228 } 10229 10230 vms.starting = 1; 10231 vms.curmsg = 0; 10232 break; 10233 case '3': /* Advanced options */ 10234 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10235 cmd = 0; 10236 vms.repeats = 0; 10237 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10238 switch (cmd) { 10239 case '1': /* Reply */ 10240 if (vms.lastmsg > -1 && !vms.starting) { 10241 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10242 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10243 res = cmd; 10244 goto out; 10245 } 10246 } else { 10247 cmd = ast_play_and_wait(chan, "vm-sorry"); 10248 } 10249 cmd = 't'; 10250 break; 10251 case '2': /* Callback */ 10252 if (!vms.starting) 10253 ast_verb(3, "Callback Requested\n"); 10254 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10255 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10256 if (cmd == 9) { 10257 silentexit = 1; 10258 goto out; 10259 } else if (cmd == ERROR_LOCK_PATH) { 10260 res = cmd; 10261 goto out; 10262 } 10263 } else { 10264 cmd = ast_play_and_wait(chan, "vm-sorry"); 10265 } 10266 cmd = 't'; 10267 break; 10268 case '3': /* Envelope */ 10269 if (vms.lastmsg > -1 && !vms.starting) { 10270 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10271 if (cmd == ERROR_LOCK_PATH) { 10272 res = cmd; 10273 goto out; 10274 } 10275 } else { 10276 cmd = ast_play_and_wait(chan, "vm-sorry"); 10277 } 10278 cmd = 't'; 10279 break; 10280 case '4': /* Dialout */ 10281 if (!ast_strlen_zero(vmu->dialout)) { 10282 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10283 if (cmd == 9) { 10284 silentexit = 1; 10285 goto out; 10286 } 10287 } else { 10288 cmd = ast_play_and_wait(chan, "vm-sorry"); 10289 } 10290 cmd = 't'; 10291 break; 10292 10293 case '5': /* Leave VoiceMail */ 10294 if (ast_test_flag(vmu, VM_SVMAIL)) { 10295 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10296 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10297 res = cmd; 10298 goto out; 10299 } 10300 } else { 10301 cmd = ast_play_and_wait(chan, "vm-sorry"); 10302 } 10303 cmd = 't'; 10304 break; 10305 10306 case '*': /* Return to main menu */ 10307 cmd = 't'; 10308 break; 10309 10310 default: 10311 cmd = 0; 10312 if (!vms.starting) { 10313 cmd = ast_play_and_wait(chan, "vm-toreply"); 10314 } 10315 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10316 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10317 } 10318 if (!cmd && !vms.starting) { 10319 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10320 } 10321 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10322 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10323 } 10324 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10325 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10326 } 10327 if (!cmd) { 10328 cmd = ast_play_and_wait(chan, "vm-starmain"); 10329 } 10330 if (!cmd) { 10331 cmd = ast_waitfordigit(chan, 6000); 10332 } 10333 if (!cmd) { 10334 vms.repeats++; 10335 } 10336 if (vms.repeats > 3) { 10337 cmd = 't'; 10338 } 10339 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10340 } 10341 } 10342 if (cmd == 't') { 10343 cmd = 0; 10344 vms.repeats = 0; 10345 } 10346 break; 10347 case '4': /* Go to the previous message */ 10348 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10349 if (vms.curmsg > 0) { 10350 vms.curmsg--; 10351 cmd = play_message(chan, vmu, &vms); 10352 } else { 10353 /* Check if we were listening to new 10354 messages. If so, go to Urgent messages 10355 instead of saying "no more messages" 10356 */ 10357 if (in_urgent == 0 && vms.urgentmessages > 0) { 10358 /* Check for Urgent messages */ 10359 in_urgent = 1; 10360 res = close_mailbox(&vms, vmu); 10361 if (res == ERROR_LOCK_PATH) 10362 goto out; 10363 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10364 if (res < 0) 10365 goto out; 10366 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10367 vms.curmsg = vms.lastmsg; 10368 if (vms.lastmsg < 0) { 10369 cmd = ast_play_and_wait(chan, "vm-nomore"); 10370 } 10371 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10372 vms.curmsg = vms.lastmsg; 10373 cmd = play_message(chan, vmu, &vms); 10374 } else { 10375 cmd = ast_play_and_wait(chan, "vm-nomore"); 10376 } 10377 } 10378 break; 10379 case '6': /* Go to the next message */ 10380 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10381 if (vms.curmsg < vms.lastmsg) { 10382 vms.curmsg++; 10383 cmd = play_message(chan, vmu, &vms); 10384 } else { 10385 if (in_urgent && vms.newmessages > 0) { 10386 /* Check if we were listening to urgent 10387 * messages. If so, go to regular new messages 10388 * instead of saying "no more messages" 10389 */ 10390 in_urgent = 0; 10391 res = close_mailbox(&vms, vmu); 10392 if (res == ERROR_LOCK_PATH) 10393 goto out; 10394 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10395 if (res < 0) 10396 goto out; 10397 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10398 vms.curmsg = -1; 10399 if (vms.lastmsg < 0) { 10400 cmd = ast_play_and_wait(chan, "vm-nomore"); 10401 } 10402 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10403 vms.curmsg = 0; 10404 cmd = play_message(chan, vmu, &vms); 10405 } else { 10406 cmd = ast_play_and_wait(chan, "vm-nomore"); 10407 } 10408 } 10409 break; 10410 case '7': /* Delete the current message */ 10411 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10412 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10413 if (useadsi) 10414 adsi_delete(chan, &vms); 10415 if (vms.deleted[vms.curmsg]) { 10416 if (play_folder == 0) { 10417 if (in_urgent) { 10418 vms.urgentmessages--; 10419 } else { 10420 vms.newmessages--; 10421 } 10422 } 10423 else if (play_folder == 1) 10424 vms.oldmessages--; 10425 cmd = ast_play_and_wait(chan, "vm-deleted"); 10426 } else { 10427 if (play_folder == 0) { 10428 if (in_urgent) { 10429 vms.urgentmessages++; 10430 } else { 10431 vms.newmessages++; 10432 } 10433 } 10434 else if (play_folder == 1) 10435 vms.oldmessages++; 10436 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10437 } 10438 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10439 if (vms.curmsg < vms.lastmsg) { 10440 vms.curmsg++; 10441 cmd = play_message(chan, vmu, &vms); 10442 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10443 vms.curmsg = 0; 10444 cmd = play_message(chan, vmu, &vms); 10445 } else { 10446 /* Check if we were listening to urgent 10447 messages. If so, go to regular new messages 10448 instead of saying "no more messages" 10449 */ 10450 if (in_urgent == 1) { 10451 /* Check for new messages */ 10452 in_urgent = 0; 10453 res = close_mailbox(&vms, vmu); 10454 if (res == ERROR_LOCK_PATH) 10455 goto out; 10456 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10457 if (res < 0) 10458 goto out; 10459 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10460 vms.curmsg = -1; 10461 if (vms.lastmsg < 0) { 10462 cmd = ast_play_and_wait(chan, "vm-nomore"); 10463 } 10464 } else { 10465 cmd = ast_play_and_wait(chan, "vm-nomore"); 10466 } 10467 } 10468 } 10469 } else /* Delete not valid if we haven't selected a message */ 10470 cmd = 0; 10471 #ifdef IMAP_STORAGE 10472 deleted = 1; 10473 #endif 10474 break; 10475 10476 case '8': /* Forward the current message */ 10477 if (vms.lastmsg > -1) { 10478 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10479 if (cmd == ERROR_LOCK_PATH) { 10480 res = cmd; 10481 goto out; 10482 } 10483 } else { 10484 /* Check if we were listening to urgent 10485 messages. If so, go to regular new messages 10486 instead of saying "no more messages" 10487 */ 10488 if (in_urgent == 1 && vms.newmessages > 0) { 10489 /* Check for new messages */ 10490 in_urgent = 0; 10491 res = close_mailbox(&vms, vmu); 10492 if (res == ERROR_LOCK_PATH) 10493 goto out; 10494 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10495 if (res < 0) 10496 goto out; 10497 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10498 vms.curmsg = -1; 10499 if (vms.lastmsg < 0) { 10500 cmd = ast_play_and_wait(chan, "vm-nomore"); 10501 } 10502 } else { 10503 cmd = ast_play_and_wait(chan, "vm-nomore"); 10504 } 10505 } 10506 break; 10507 case '9': /* Save message to folder */ 10508 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10509 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10510 /* No message selected */ 10511 cmd = 0; 10512 break; 10513 } 10514 if (useadsi) 10515 adsi_folders(chan, 1, "Save to folder..."); 10516 cmd = get_folder2(chan, "vm-savefolder", 1); 10517 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10518 box = 0; /* Shut up compiler */ 10519 if (cmd == '#') { 10520 cmd = 0; 10521 break; 10522 } else if (cmd > 0) { 10523 box = cmd = cmd - '0'; 10524 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10525 if (cmd == ERROR_LOCK_PATH) { 10526 res = cmd; 10527 goto out; 10528 #ifndef IMAP_STORAGE 10529 } else if (!cmd) { 10530 vms.deleted[vms.curmsg] = 1; 10531 #endif 10532 } else { 10533 vms.deleted[vms.curmsg] = 0; 10534 vms.heard[vms.curmsg] = 0; 10535 } 10536 } 10537 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10538 if (useadsi) 10539 adsi_message(chan, &vms); 10540 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10541 if (!cmd) { 10542 cmd = ast_play_and_wait(chan, "vm-message"); 10543 if (!cmd) 10544 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10545 if (!cmd) 10546 cmd = ast_play_and_wait(chan, "vm-savedto"); 10547 if (!cmd) 10548 cmd = vm_play_folder_name(chan, vms.fn); 10549 } else { 10550 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10551 } 10552 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10553 if (vms.curmsg < vms.lastmsg) { 10554 vms.curmsg++; 10555 cmd = play_message(chan, vmu, &vms); 10556 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10557 vms.curmsg = 0; 10558 cmd = play_message(chan, vmu, &vms); 10559 } else { 10560 /* Check if we were listening to urgent 10561 messages. If so, go to regular new messages 10562 instead of saying "no more messages" 10563 */ 10564 if (in_urgent == 1 && vms.newmessages > 0) { 10565 /* Check for new messages */ 10566 in_urgent = 0; 10567 res = close_mailbox(&vms, vmu); 10568 if (res == ERROR_LOCK_PATH) 10569 goto out; 10570 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10571 if (res < 0) 10572 goto out; 10573 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10574 vms.curmsg = -1; 10575 if (vms.lastmsg < 0) { 10576 cmd = ast_play_and_wait(chan, "vm-nomore"); 10577 } 10578 } else { 10579 cmd = ast_play_and_wait(chan, "vm-nomore"); 10580 } 10581 } 10582 } 10583 break; 10584 case '*': /* Help */ 10585 if (!vms.starting) { 10586 cmd = ast_play_and_wait(chan, "vm-onefor"); 10587 if (!strncasecmp(chan->language, "he", 2)) { 10588 cmd = ast_play_and_wait(chan, "vm-for"); 10589 } 10590 if (!cmd) 10591 cmd = vm_play_folder_name(chan, vms.vmbox); 10592 if (!cmd) 10593 cmd = ast_play_and_wait(chan, "vm-opts"); 10594 if (!cmd) 10595 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10596 } else 10597 cmd = 0; 10598 break; 10599 case '0': /* Mailbox options */ 10600 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10601 if (useadsi) 10602 adsi_status(chan, &vms); 10603 break; 10604 default: /* Nothing */ 10605 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10606 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10607 break; 10608 } 10609 } 10610 if ((cmd == 't') || (cmd == '#')) { 10611 /* Timeout */ 10612 res = 0; 10613 } else { 10614 /* Hangup */ 10615 res = -1; 10616 } 10617 10618 out: 10619 if (res > -1) { 10620 ast_stopstream(chan); 10621 adsi_goodbye(chan); 10622 if (valid && res != OPERATOR_EXIT) { 10623 if (silentexit) 10624 res = ast_play_and_wait(chan, "vm-dialout"); 10625 else 10626 res = ast_play_and_wait(chan, "vm-goodbye"); 10627 } 10628 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10629 res = 0; 10630 } 10631 if (useadsi) 10632 ast_adsi_unload_session(chan); 10633 } 10634 if (vmu) 10635 close_mailbox(&vms, vmu); 10636 if (valid) { 10637 int new = 0, old = 0, urgent = 0; 10638 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10639 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10640 /* Urgent flag not passwd to externnotify here */ 10641 run_externnotify(vmu->context, vmu->mailbox, NULL); 10642 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10643 queue_mwi_event(ext_context, urgent, new, old); 10644 } 10645 #ifdef IMAP_STORAGE 10646 /* expunge message - use UID Expunge if supported on IMAP server*/ 10647 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10648 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10649 ast_mutex_lock(&vms.lock); 10650 #ifdef HAVE_IMAP_TK2006 10651 if (LEVELUIDPLUS (vms.mailstream)) { 10652 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10653 } else 10654 #endif 10655 mail_expunge(vms.mailstream); 10656 ast_mutex_unlock(&vms.lock); 10657 } 10658 /* before we delete the state, we should copy pertinent info 10659 * back to the persistent model */ 10660 if (vmu) { 10661 vmstate_delete(&vms); 10662 } 10663 #endif 10664 if (vmu) 10665 free_user(vmu); 10666 10667 #ifdef IMAP_STORAGE 10668 pthread_setspecific(ts_vmstate.key, NULL); 10669 #endif 10670 return res; 10671 }
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 6881 of file app_voicemail_imapstorage.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, and play_record_review().
Referenced by forward_message().
06883 { 06884 int cmd = 0; 06885 int retries = 0, prepend_duration = 0, already_recorded = 0; 06886 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06887 char textfile[PATH_MAX]; 06888 struct ast_config *msg_cfg; 06889 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06890 #ifndef IMAP_STORAGE 06891 signed char zero_gain = 0; 06892 #endif 06893 const char *duration_str; 06894 06895 /* Must always populate duration correctly */ 06896 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06897 strcpy(textfile, msgfile); 06898 strcpy(backup, msgfile); 06899 strcpy(backup_textfile, msgfile); 06900 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06901 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06902 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06903 06904 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06905 *duration = atoi(duration_str); 06906 } else { 06907 *duration = 0; 06908 } 06909 06910 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06911 if (cmd) 06912 retries = 0; 06913 switch (cmd) { 06914 case '1': 06915 06916 #ifdef IMAP_STORAGE 06917 /* Record new intro file */ 06918 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06919 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06920 ast_play_and_wait(chan, INTRO); 06921 ast_play_and_wait(chan, "beep"); 06922 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06923 if (cmd == -1) { 06924 break; 06925 } 06926 cmd = 't'; 06927 #else 06928 06929 /* prepend a message to the current message, update the metadata and return */ 06930 06931 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06932 strcpy(textfile, msgfile); 06933 strncat(textfile, ".txt", sizeof(textfile) - 1); 06934 *duration = 0; 06935 06936 /* if we can't read the message metadata, stop now */ 06937 if (!msg_cfg) { 06938 cmd = 0; 06939 break; 06940 } 06941 06942 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06943 #ifndef IMAP_STORAGE 06944 if (already_recorded) { 06945 ast_filecopy(backup, msgfile, NULL); 06946 copy(backup_textfile, textfile); 06947 } 06948 else { 06949 ast_filecopy(msgfile, backup, NULL); 06950 copy(textfile, backup_textfile); 06951 } 06952 #endif 06953 already_recorded = 1; 06954 06955 if (record_gain) 06956 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06957 06958 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06959 06960 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06961 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06962 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06963 ast_filerename(backup, msgfile, NULL); 06964 } 06965 06966 if (record_gain) 06967 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06968 06969 06970 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06971 *duration = atoi(duration_str); 06972 06973 if (prepend_duration) { 06974 struct ast_category *msg_cat; 06975 /* need enough space for a maximum-length message duration */ 06976 char duration_buf[12]; 06977 06978 *duration += prepend_duration; 06979 msg_cat = ast_category_get(msg_cfg, "message"); 06980 snprintf(duration_buf, 11, "%ld", *duration); 06981 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06982 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06983 } 06984 } 06985 06986 #endif 06987 break; 06988 case '2': 06989 /* NULL out introfile so we know there is no intro! */ 06990 #ifdef IMAP_STORAGE 06991 *vms->introfn = '\0'; 06992 #endif 06993 cmd = 't'; 06994 break; 06995 case '*': 06996 cmd = '*'; 06997 break; 06998 default: 06999 /* If time_out and return to menu, reset already_recorded */ 07000 already_recorded = 0; 07001 07002 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 07003 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 07004 if (!cmd) { 07005 cmd = ast_play_and_wait(chan, "vm-starmain"); 07006 /* "press star to return to the main menu" */ 07007 } 07008 if (!cmd) { 07009 cmd = ast_waitfordigit(chan, 6000); 07010 } 07011 if (!cmd) { 07012 retries++; 07013 } 07014 if (retries > 3) { 07015 cmd = '*'; /* Let's cancel this beast */ 07016 } 07017 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07018 } 07019 } 07020 07021 if (msg_cfg) 07022 ast_config_destroy(msg_cfg); 07023 if (prepend_duration) 07024 *duration = prepend_duration; 07025 07026 if (already_recorded && cmd == -1) { 07027 /* restore original message if prepention cancelled */ 07028 ast_filerename(backup, msgfile, NULL); 07029 rename(backup_textfile, textfile); 07030 } 07031 07032 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07033 cmd = 0; 07034 return cmd; 07035 }
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 9236 of file app_voicemail_imapstorage.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09237 { 09238 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09239 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09240 } else { /* Default to ENGLISH */ 09241 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09242 } 09243 }
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 9124 of file app_voicemail_imapstorage.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().
09125 { 09126 int res = 0; 09127 /* Play instructions and wait for new command */ 09128 while (!res) { 09129 if (vms->starting) { 09130 if (vms->lastmsg > -1) { 09131 if (skipadvanced) 09132 res = ast_play_and_wait(chan, "vm-onefor-full"); 09133 else 09134 res = ast_play_and_wait(chan, "vm-onefor"); 09135 if (!res) 09136 res = vm_play_folder_name(chan, vms->vmbox); 09137 } 09138 if (!res) { 09139 if (skipadvanced) 09140 res = ast_play_and_wait(chan, "vm-opts-full"); 09141 else 09142 res = ast_play_and_wait(chan, "vm-opts"); 09143 } 09144 } else { 09145 /* Added for additional help */ 09146 if (skipadvanced) { 09147 res = ast_play_and_wait(chan, "vm-onefor-full"); 09148 if (!res) 09149 res = vm_play_folder_name(chan, vms->vmbox); 09150 res = ast_play_and_wait(chan, "vm-opts-full"); 09151 } 09152 /* Logic: 09153 * If the current message is not the first OR 09154 * if we're listening to the first new message and there are 09155 * also urgent messages, then prompt for navigation to the 09156 * previous message 09157 */ 09158 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09159 res = ast_play_and_wait(chan, "vm-prev"); 09160 } 09161 if (!res && !skipadvanced) 09162 res = ast_play_and_wait(chan, "vm-advopts"); 09163 if (!res) 09164 res = ast_play_and_wait(chan, "vm-repeat"); 09165 /* Logic: 09166 * If we're not listening to the last message OR 09167 * we're listening to the last urgent message and there are 09168 * also new non-urgent messages, then prompt for navigation 09169 * to the next message 09170 */ 09171 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09172 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09173 res = ast_play_and_wait(chan, "vm-next"); 09174 } 09175 if (!res) { 09176 int curmsg_deleted; 09177 #ifdef IMAP_STORAGE 09178 ast_mutex_lock(&vms->lock); 09179 #endif 09180 curmsg_deleted = vms->deleted[vms->curmsg]; 09181 #ifdef IMAP_STORAGE 09182 ast_mutex_unlock(&vms->lock); 09183 #endif 09184 if (!curmsg_deleted) { 09185 res = ast_play_and_wait(chan, "vm-delete"); 09186 } else { 09187 res = ast_play_and_wait(chan, "vm-undelete"); 09188 } 09189 if (!res) { 09190 res = ast_play_and_wait(chan, "vm-toforward"); 09191 } 09192 if (!res) { 09193 res = ast_play_and_wait(chan, "vm-savemessage"); 09194 } 09195 } 09196 } 09197 if (!res) { 09198 res = ast_play_and_wait(chan, "vm-helpexit"); 09199 } 09200 if (!res) 09201 res = ast_waitfordigit(chan, 6000); 09202 if (!res) { 09203 vms->repeats++; 09204 if (vms->repeats > 2) { 09205 res = 't'; 09206 } 09207 } 09208 } 09209 return res; 09210 }
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 9212 of file app_voicemail_imapstorage.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().
09213 { 09214 int res = 0; 09215 /* Play instructions and wait for new command */ 09216 while (!res) { 09217 if (vms->lastmsg > -1) { 09218 res = ast_play_and_wait(chan, "vm-listen"); 09219 if (!res) 09220 res = vm_play_folder_name(chan, vms->vmbox); 09221 if (!res) 09222 res = ast_play_and_wait(chan, "press"); 09223 if (!res) 09224 res = ast_play_and_wait(chan, "digits/1"); 09225 } 09226 if (!res) 09227 res = ast_play_and_wait(chan, "vm-opts"); 09228 if (!res) { 09229 vms->starting = 0; 09230 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09231 } 09232 } 09233 return res; 09234 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9062 of file app_voicemail_imapstorage.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(), and VM_TEMPGREETWARN.
Referenced by vm_execmain().
09063 { 09064 char prefile[256]; 09065 09066 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09067 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09068 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09069 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09070 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09071 ast_play_and_wait(chan, "vm-tempgreetactive"); 09072 } 09073 DISPOSE(prefile, -1); 09074 } 09075 09076 /* Play voicemail intro - syntax is different for different languages */ 09077 if (0) { 09078 return 0; 09079 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09080 return vm_intro_cs(chan, vms); 09081 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09082 static int deprecation_warning = 0; 09083 if (deprecation_warning++ % 10 == 0) { 09084 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09085 } 09086 return vm_intro_cs(chan, vms); 09087 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09088 return vm_intro_de(chan, vms); 09089 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09090 return vm_intro_es(chan, vms); 09091 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09092 return vm_intro_fr(chan, vms); 09093 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09094 return vm_intro_gr(chan, vms); 09095 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09096 return vm_intro_he(chan, vms); 09097 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09098 return vm_intro_it(chan, vms); 09099 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09100 return vm_intro_nl(chan, vms); 09101 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09102 return vm_intro_no(chan, vms); 09103 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09104 return vm_intro_pl(chan, vms); 09105 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09106 return vm_intro_pt_BR(chan, vms); 09107 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09108 return vm_intro_pt(chan, vms); 09109 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09110 return vm_intro_multilang(chan, vms, "n"); 09111 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09112 return vm_intro_se(chan, vms); 09113 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09114 return vm_intro_multilang(chan, vms, "n"); 09115 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09116 return vm_intro_vi(chan, vms); 09117 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09118 return vm_intro_zh(chan, vms); 09119 } else { /* Default to ENGLISH */ 09120 return vm_intro_en(chan, vms); 09121 } 09122 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8932 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08933 { 08934 int res; 08935 res = ast_play_and_wait(chan, "vm-youhave"); 08936 if (!res) { 08937 if (vms->newmessages) { 08938 if (vms->newmessages == 1) { 08939 res = ast_play_and_wait(chan, "digits/jednu"); 08940 } else { 08941 res = say_and_wait(chan, vms->newmessages, chan->language); 08942 } 08943 if (!res) { 08944 if ((vms->newmessages == 1)) 08945 res = ast_play_and_wait(chan, "vm-novou"); 08946 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08947 res = ast_play_and_wait(chan, "vm-nove"); 08948 if (vms->newmessages > 4) 08949 res = ast_play_and_wait(chan, "vm-novych"); 08950 } 08951 if (vms->oldmessages && !res) 08952 res = ast_play_and_wait(chan, "vm-and"); 08953 else if (!res) { 08954 if ((vms->newmessages == 1)) 08955 res = ast_play_and_wait(chan, "vm-zpravu"); 08956 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08957 res = ast_play_and_wait(chan, "vm-zpravy"); 08958 if (vms->newmessages > 4) 08959 res = ast_play_and_wait(chan, "vm-zprav"); 08960 } 08961 } 08962 if (!res && vms->oldmessages) { 08963 res = say_and_wait(chan, vms->oldmessages, chan->language); 08964 if (!res) { 08965 if ((vms->oldmessages == 1)) 08966 res = ast_play_and_wait(chan, "vm-starou"); 08967 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08968 res = ast_play_and_wait(chan, "vm-stare"); 08969 if (vms->oldmessages > 4) 08970 res = ast_play_and_wait(chan, "vm-starych"); 08971 } 08972 if (!res) { 08973 if ((vms->oldmessages == 1)) 08974 res = ast_play_and_wait(chan, "vm-zpravu"); 08975 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08976 res = ast_play_and_wait(chan, "vm-zpravy"); 08977 if (vms->oldmessages > 4) 08978 res = ast_play_and_wait(chan, "vm-zprav"); 08979 } 08980 } 08981 if (!res) { 08982 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08983 res = ast_play_and_wait(chan, "vm-no"); 08984 if (!res) 08985 res = ast_play_and_wait(chan, "vm-zpravy"); 08986 } 08987 } 08988 } 08989 return res; 08990 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8628 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08629 { 08630 /* Introduce messages they have */ 08631 int res; 08632 res = ast_play_and_wait(chan, "vm-youhave"); 08633 if (!res) { 08634 if (vms->newmessages) { 08635 if ((vms->newmessages == 1)) 08636 res = ast_play_and_wait(chan, "digits/1F"); 08637 else 08638 res = say_and_wait(chan, vms->newmessages, chan->language); 08639 if (!res) 08640 res = ast_play_and_wait(chan, "vm-INBOX"); 08641 if (vms->oldmessages && !res) 08642 res = ast_play_and_wait(chan, "vm-and"); 08643 else if (!res) { 08644 if ((vms->newmessages == 1)) 08645 res = ast_play_and_wait(chan, "vm-message"); 08646 else 08647 res = ast_play_and_wait(chan, "vm-messages"); 08648 } 08649 08650 } 08651 if (!res && vms->oldmessages) { 08652 if (vms->oldmessages == 1) 08653 res = ast_play_and_wait(chan, "digits/1F"); 08654 else 08655 res = say_and_wait(chan, vms->oldmessages, chan->language); 08656 if (!res) 08657 res = ast_play_and_wait(chan, "vm-Old"); 08658 if (!res) { 08659 if (vms->oldmessages == 1) 08660 res = ast_play_and_wait(chan, "vm-message"); 08661 else 08662 res = ast_play_and_wait(chan, "vm-messages"); 08663 } 08664 } 08665 if (!res) { 08666 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08667 res = ast_play_and_wait(chan, "vm-no"); 08668 if (!res) 08669 res = ast_play_and_wait(chan, "vm-messages"); 08670 } 08671 } 08672 } 08673 return res; 08674 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8377 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08378 { 08379 int res; 08380 08381 /* Introduce messages they have */ 08382 res = ast_play_and_wait(chan, "vm-youhave"); 08383 if (!res) { 08384 if (vms->urgentmessages) { 08385 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08386 if (!res) 08387 res = ast_play_and_wait(chan, "vm-Urgent"); 08388 if ((vms->oldmessages || vms->newmessages) && !res) { 08389 res = ast_play_and_wait(chan, "vm-and"); 08390 } else if (!res) { 08391 if ((vms->urgentmessages == 1)) 08392 res = ast_play_and_wait(chan, "vm-message"); 08393 else 08394 res = ast_play_and_wait(chan, "vm-messages"); 08395 } 08396 } 08397 if (vms->newmessages) { 08398 res = say_and_wait(chan, vms->newmessages, chan->language); 08399 if (!res) 08400 res = ast_play_and_wait(chan, "vm-INBOX"); 08401 if (vms->oldmessages && !res) 08402 res = ast_play_and_wait(chan, "vm-and"); 08403 else if (!res) { 08404 if ((vms->newmessages == 1)) 08405 res = ast_play_and_wait(chan, "vm-message"); 08406 else 08407 res = ast_play_and_wait(chan, "vm-messages"); 08408 } 08409 08410 } 08411 if (!res && vms->oldmessages) { 08412 res = say_and_wait(chan, vms->oldmessages, chan->language); 08413 if (!res) 08414 res = ast_play_and_wait(chan, "vm-Old"); 08415 if (!res) { 08416 if (vms->oldmessages == 1) 08417 res = ast_play_and_wait(chan, "vm-message"); 08418 else 08419 res = ast_play_and_wait(chan, "vm-messages"); 08420 } 08421 } 08422 if (!res) { 08423 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08424 res = ast_play_and_wait(chan, "vm-no"); 08425 if (!res) 08426 res = ast_play_and_wait(chan, "vm-messages"); 08427 } 08428 } 08429 } 08430 return res; 08431 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8677 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08678 { 08679 /* Introduce messages they have */ 08680 int res; 08681 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08682 res = ast_play_and_wait(chan, "vm-youhaveno"); 08683 if (!res) 08684 res = ast_play_and_wait(chan, "vm-messages"); 08685 } else { 08686 res = ast_play_and_wait(chan, "vm-youhave"); 08687 } 08688 if (!res) { 08689 if (vms->newmessages) { 08690 if (!res) { 08691 if ((vms->newmessages == 1)) { 08692 res = ast_play_and_wait(chan, "digits/1M"); 08693 if (!res) 08694 res = ast_play_and_wait(chan, "vm-message"); 08695 if (!res) 08696 res = ast_play_and_wait(chan, "vm-INBOXs"); 08697 } else { 08698 res = say_and_wait(chan, vms->newmessages, chan->language); 08699 if (!res) 08700 res = ast_play_and_wait(chan, "vm-messages"); 08701 if (!res) 08702 res = ast_play_and_wait(chan, "vm-INBOX"); 08703 } 08704 } 08705 if (vms->oldmessages && !res) 08706 res = ast_play_and_wait(chan, "vm-and"); 08707 } 08708 if (vms->oldmessages) { 08709 if (!res) { 08710 if (vms->oldmessages == 1) { 08711 res = ast_play_and_wait(chan, "digits/1M"); 08712 if (!res) 08713 res = ast_play_and_wait(chan, "vm-message"); 08714 if (!res) 08715 res = ast_play_and_wait(chan, "vm-Olds"); 08716 } else { 08717 res = say_and_wait(chan, vms->oldmessages, chan->language); 08718 if (!res) 08719 res = ast_play_and_wait(chan, "vm-messages"); 08720 if (!res) 08721 res = ast_play_and_wait(chan, "vm-Old"); 08722 } 08723 } 08724 } 08725 } 08726 return res; 08727 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8775 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08776 { 08777 /* Introduce messages they have */ 08778 int res; 08779 res = ast_play_and_wait(chan, "vm-youhave"); 08780 if (!res) { 08781 if (vms->newmessages) { 08782 res = say_and_wait(chan, vms->newmessages, chan->language); 08783 if (!res) 08784 res = ast_play_and_wait(chan, "vm-INBOX"); 08785 if (vms->oldmessages && !res) 08786 res = ast_play_and_wait(chan, "vm-and"); 08787 else if (!res) { 08788 if ((vms->newmessages == 1)) 08789 res = ast_play_and_wait(chan, "vm-message"); 08790 else 08791 res = ast_play_and_wait(chan, "vm-messages"); 08792 } 08793 08794 } 08795 if (!res && vms->oldmessages) { 08796 res = say_and_wait(chan, vms->oldmessages, chan->language); 08797 if (!res) 08798 res = ast_play_and_wait(chan, "vm-Old"); 08799 if (!res) { 08800 if (vms->oldmessages == 1) 08801 res = ast_play_and_wait(chan, "vm-message"); 08802 else 08803 res = ast_play_and_wait(chan, "vm-messages"); 08804 } 08805 } 08806 if (!res) { 08807 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08808 res = ast_play_and_wait(chan, "vm-no"); 08809 if (!res) 08810 res = ast_play_and_wait(chan, "vm-messages"); 08811 } 08812 } 08813 } 08814 return res; 08815 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8176 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08177 { 08178 int res = 0; 08179 08180 if (vms->newmessages) { 08181 res = ast_play_and_wait(chan, "vm-youhave"); 08182 if (!res) 08183 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08184 if (!res) { 08185 if ((vms->newmessages == 1)) { 08186 res = ast_play_and_wait(chan, "vm-INBOX"); 08187 if (!res) 08188 res = ast_play_and_wait(chan, "vm-message"); 08189 } else { 08190 res = ast_play_and_wait(chan, "vm-INBOXs"); 08191 if (!res) 08192 res = ast_play_and_wait(chan, "vm-messages"); 08193 } 08194 } 08195 } else if (vms->oldmessages){ 08196 res = ast_play_and_wait(chan, "vm-youhave"); 08197 if (!res) 08198 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08199 if ((vms->oldmessages == 1)){ 08200 res = ast_play_and_wait(chan, "vm-Old"); 08201 if (!res) 08202 res = ast_play_and_wait(chan, "vm-message"); 08203 } else { 08204 res = ast_play_and_wait(chan, "vm-Olds"); 08205 if (!res) 08206 res = ast_play_and_wait(chan, "vm-messages"); 08207 } 08208 } else if (!vms->oldmessages && !vms->newmessages) 08209 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08210 return res; 08211 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8310 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08311 { 08312 int res = 0; 08313 08314 /* Introduce messages they have */ 08315 if (!res) { 08316 if ((vms->newmessages) || (vms->oldmessages)) { 08317 res = ast_play_and_wait(chan, "vm-youhave"); 08318 } 08319 /* 08320 * The word "shtei" refers to the number 2 in hebrew when performing a count 08321 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08322 * an element, this is one of them. 08323 */ 08324 if (vms->newmessages) { 08325 if (!res) { 08326 if (vms->newmessages == 1) { 08327 res = ast_play_and_wait(chan, "vm-INBOX1"); 08328 } else { 08329 if (vms->newmessages == 2) { 08330 res = ast_play_and_wait(chan, "vm-shtei"); 08331 } else { 08332 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08333 } 08334 res = ast_play_and_wait(chan, "vm-INBOX"); 08335 } 08336 } 08337 if (vms->oldmessages && !res) { 08338 res = ast_play_and_wait(chan, "vm-and"); 08339 if (vms->oldmessages == 1) { 08340 res = ast_play_and_wait(chan, "vm-Old1"); 08341 } else { 08342 if (vms->oldmessages == 2) { 08343 res = ast_play_and_wait(chan, "vm-shtei"); 08344 } else { 08345 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08346 } 08347 res = ast_play_and_wait(chan, "vm-Old"); 08348 } 08349 } 08350 } 08351 if (!res && vms->oldmessages && !vms->newmessages) { 08352 if (!res) { 08353 if (vms->oldmessages == 1) { 08354 res = ast_play_and_wait(chan, "vm-Old1"); 08355 } else { 08356 if (vms->oldmessages == 2) { 08357 res = ast_play_and_wait(chan, "vm-shtei"); 08358 } else { 08359 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08360 } 08361 res = ast_play_and_wait(chan, "vm-Old"); 08362 } 08363 } 08364 } 08365 if (!res) { 08366 if (!vms->oldmessages && !vms->newmessages) { 08367 if (!res) { 08368 res = ast_play_and_wait(chan, "vm-nomessages"); 08369 } 08370 } 08371 } 08372 } 08373 return res; 08374 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8434 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08435 { 08436 /* Introduce messages they have */ 08437 int res; 08438 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08439 res = ast_play_and_wait(chan, "vm-no") || 08440 ast_play_and_wait(chan, "vm-message"); 08441 else 08442 res = ast_play_and_wait(chan, "vm-youhave"); 08443 if (!res && vms->newmessages) { 08444 res = (vms->newmessages == 1) ? 08445 ast_play_and_wait(chan, "digits/un") || 08446 ast_play_and_wait(chan, "vm-nuovo") || 08447 ast_play_and_wait(chan, "vm-message") : 08448 /* 2 or more new messages */ 08449 say_and_wait(chan, vms->newmessages, chan->language) || 08450 ast_play_and_wait(chan, "vm-nuovi") || 08451 ast_play_and_wait(chan, "vm-messages"); 08452 if (!res && vms->oldmessages) 08453 res = ast_play_and_wait(chan, "vm-and"); 08454 } 08455 if (!res && vms->oldmessages) { 08456 res = (vms->oldmessages == 1) ? 08457 ast_play_and_wait(chan, "digits/un") || 08458 ast_play_and_wait(chan, "vm-vecchio") || 08459 ast_play_and_wait(chan, "vm-message") : 08460 /* 2 or more old messages */ 08461 say_and_wait(chan, vms->oldmessages, chan->language) || 08462 ast_play_and_wait(chan, "vm-vecchi") || 08463 ast_play_and_wait(chan, "vm-messages"); 08464 } 08465 return res; 08466 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8270 of file app_voicemail_imapstorage.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().
08271 { 08272 int res; 08273 int lastnum = 0; 08274 08275 res = ast_play_and_wait(chan, "vm-youhave"); 08276 08277 if (!res && vms->newmessages) { 08278 lastnum = vms->newmessages; 08279 08280 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08281 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08282 } 08283 08284 if (!res && vms->oldmessages) { 08285 res = ast_play_and_wait(chan, "vm-and"); 08286 } 08287 } 08288 08289 if (!res && vms->oldmessages) { 08290 lastnum = vms->oldmessages; 08291 08292 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08293 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08294 } 08295 } 08296 08297 if (!res) { 08298 if (lastnum == 0) { 08299 res = ast_play_and_wait(chan, "vm-no"); 08300 } 08301 if (!res) { 08302 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08303 } 08304 } 08305 08306 return res; 08307 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8818 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08819 { 08820 /* Introduce messages they have */ 08821 int res; 08822 res = ast_play_and_wait(chan, "vm-youhave"); 08823 if (!res) { 08824 if (vms->newmessages) { 08825 res = say_and_wait(chan, vms->newmessages, chan->language); 08826 if (!res) { 08827 if (vms->newmessages == 1) 08828 res = ast_play_and_wait(chan, "vm-INBOXs"); 08829 else 08830 res = ast_play_and_wait(chan, "vm-INBOX"); 08831 } 08832 if (vms->oldmessages && !res) 08833 res = ast_play_and_wait(chan, "vm-and"); 08834 else if (!res) { 08835 if ((vms->newmessages == 1)) 08836 res = ast_play_and_wait(chan, "vm-message"); 08837 else 08838 res = ast_play_and_wait(chan, "vm-messages"); 08839 } 08840 08841 } 08842 if (!res && vms->oldmessages) { 08843 res = say_and_wait(chan, vms->oldmessages, chan->language); 08844 if (!res) { 08845 if (vms->oldmessages == 1) 08846 res = ast_play_and_wait(chan, "vm-Olds"); 08847 else 08848 res = ast_play_and_wait(chan, "vm-Old"); 08849 } 08850 if (!res) { 08851 if (vms->oldmessages == 1) 08852 res = ast_play_and_wait(chan, "vm-message"); 08853 else 08854 res = ast_play_and_wait(chan, "vm-messages"); 08855 } 08856 } 08857 if (!res) { 08858 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08859 res = ast_play_and_wait(chan, "vm-no"); 08860 if (!res) 08861 res = ast_play_and_wait(chan, "vm-messages"); 08862 } 08863 } 08864 } 08865 return res; 08866 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8584 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08585 { 08586 /* Introduce messages they have */ 08587 int res; 08588 08589 res = ast_play_and_wait(chan, "vm-youhave"); 08590 if (res) 08591 return res; 08592 08593 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08594 res = ast_play_and_wait(chan, "vm-no"); 08595 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08596 return res; 08597 } 08598 08599 if (vms->newmessages) { 08600 if ((vms->newmessages == 1)) { 08601 res = ast_play_and_wait(chan, "digits/1"); 08602 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08603 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08604 } else { 08605 res = say_and_wait(chan, vms->newmessages, chan->language); 08606 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08607 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08608 } 08609 if (!res && vms->oldmessages) 08610 res = ast_play_and_wait(chan, "vm-and"); 08611 } 08612 if (!res && vms->oldmessages) { 08613 if (vms->oldmessages == 1) { 08614 res = ast_play_and_wait(chan, "digits/1"); 08615 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08616 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08617 } else { 08618 res = say_and_wait(chan, vms->oldmessages, chan->language); 08619 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08620 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08621 } 08622 } 08623 08624 return res; 08625 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8469 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08470 { 08471 /* Introduce messages they have */ 08472 int res; 08473 div_t num; 08474 08475 if (!vms->oldmessages && !vms->newmessages) { 08476 res = ast_play_and_wait(chan, "vm-no"); 08477 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08478 return res; 08479 } else { 08480 res = ast_play_and_wait(chan, "vm-youhave"); 08481 } 08482 08483 if (vms->newmessages) { 08484 num = div(vms->newmessages, 10); 08485 if (vms->newmessages == 1) { 08486 res = ast_play_and_wait(chan, "digits/1-a"); 08487 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08488 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08489 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08490 if (num.rem == 2) { 08491 if (!num.quot) { 08492 res = ast_play_and_wait(chan, "digits/2-ie"); 08493 } else { 08494 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08495 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08496 } 08497 } else { 08498 res = say_and_wait(chan, vms->newmessages, chan->language); 08499 } 08500 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08501 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08502 } else { 08503 res = say_and_wait(chan, vms->newmessages, chan->language); 08504 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08505 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08506 } 08507 if (!res && vms->oldmessages) 08508 res = ast_play_and_wait(chan, "vm-and"); 08509 } 08510 if (!res && vms->oldmessages) { 08511 num = div(vms->oldmessages, 10); 08512 if (vms->oldmessages == 1) { 08513 res = ast_play_and_wait(chan, "digits/1-a"); 08514 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08515 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08516 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08517 if (num.rem == 2) { 08518 if (!num.quot) { 08519 res = ast_play_and_wait(chan, "digits/2-ie"); 08520 } else { 08521 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08522 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08523 } 08524 } else { 08525 res = say_and_wait(chan, vms->oldmessages, chan->language); 08526 } 08527 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08528 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08529 } else { 08530 res = say_and_wait(chan, vms->oldmessages, chan->language); 08531 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08532 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08533 } 08534 } 08535 08536 return res; 08537 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8869 of file app_voicemail_imapstorage.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().
08870 { 08871 /* Introduce messages they have */ 08872 int res; 08873 res = ast_play_and_wait(chan, "vm-youhave"); 08874 if (!res) { 08875 if (vms->newmessages) { 08876 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08877 if (!res) { 08878 if ((vms->newmessages == 1)) { 08879 res = ast_play_and_wait(chan, "vm-message"); 08880 if (!res) 08881 res = ast_play_and_wait(chan, "vm-INBOXs"); 08882 } else { 08883 res = ast_play_and_wait(chan, "vm-messages"); 08884 if (!res) 08885 res = ast_play_and_wait(chan, "vm-INBOX"); 08886 } 08887 } 08888 if (vms->oldmessages && !res) 08889 res = ast_play_and_wait(chan, "vm-and"); 08890 } 08891 if (!res && vms->oldmessages) { 08892 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08893 if (!res) { 08894 if (vms->oldmessages == 1) { 08895 res = ast_play_and_wait(chan, "vm-message"); 08896 if (!res) 08897 res = ast_play_and_wait(chan, "vm-Olds"); 08898 } else { 08899 res = ast_play_and_wait(chan, "vm-messages"); 08900 if (!res) 08901 res = ast_play_and_wait(chan, "vm-Old"); 08902 } 08903 } 08904 } 08905 if (!res) { 08906 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08907 res = ast_play_and_wait(chan, "vm-no"); 08908 if (!res) 08909 res = ast_play_and_wait(chan, "vm-messages"); 08910 } 08911 } 08912 } 08913 return res; 08914 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8730 of file app_voicemail_imapstorage.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().
08730 { 08731 /* Introduce messages they have */ 08732 int res; 08733 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08734 res = ast_play_and_wait(chan, "vm-nomessages"); 08735 return res; 08736 } else { 08737 res = ast_play_and_wait(chan, "vm-youhave"); 08738 } 08739 if (vms->newmessages) { 08740 if (!res) 08741 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08742 if ((vms->newmessages == 1)) { 08743 if (!res) 08744 res = ast_play_and_wait(chan, "vm-message"); 08745 if (!res) 08746 res = ast_play_and_wait(chan, "vm-INBOXs"); 08747 } else { 08748 if (!res) 08749 res = ast_play_and_wait(chan, "vm-messages"); 08750 if (!res) 08751 res = ast_play_and_wait(chan, "vm-INBOX"); 08752 } 08753 if (vms->oldmessages && !res) 08754 res = ast_play_and_wait(chan, "vm-and"); 08755 } 08756 if (vms->oldmessages) { 08757 if (!res) 08758 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08759 if (vms->oldmessages == 1) { 08760 if (!res) 08761 res = ast_play_and_wait(chan, "vm-message"); 08762 if (!res) 08763 res = ast_play_and_wait(chan, "vm-Olds"); 08764 } else { 08765 if (!res) 08766 res = ast_play_and_wait(chan, "vm-messages"); 08767 if (!res) 08768 res = ast_play_and_wait(chan, "vm-Old"); 08769 } 08770 } 08771 return res; 08772 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8540 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08541 { 08542 /* Introduce messages they have */ 08543 int res; 08544 08545 res = ast_play_and_wait(chan, "vm-youhave"); 08546 if (res) 08547 return res; 08548 08549 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08550 res = ast_play_and_wait(chan, "vm-no"); 08551 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08552 return res; 08553 } 08554 08555 if (vms->newmessages) { 08556 if ((vms->newmessages == 1)) { 08557 res = ast_play_and_wait(chan, "digits/ett"); 08558 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08559 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08560 } else { 08561 res = say_and_wait(chan, vms->newmessages, chan->language); 08562 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08563 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08564 } 08565 if (!res && vms->oldmessages) 08566 res = ast_play_and_wait(chan, "vm-and"); 08567 } 08568 if (!res && vms->oldmessages) { 08569 if (vms->oldmessages == 1) { 08570 res = ast_play_and_wait(chan, "digits/ett"); 08571 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08572 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08573 } else { 08574 res = say_and_wait(chan, vms->oldmessages, chan->language); 08575 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08576 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08577 } 08578 } 08579 08580 return res; 08581 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9032 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09033 { 09034 int res; 09035 09036 /* Introduce messages they have */ 09037 res = ast_play_and_wait(chan, "vm-youhave"); 09038 if (!res) { 09039 if (vms->newmessages) { 09040 res = say_and_wait(chan, vms->newmessages, chan->language); 09041 if (!res) 09042 res = ast_play_and_wait(chan, "vm-INBOX"); 09043 if (vms->oldmessages && !res) 09044 res = ast_play_and_wait(chan, "vm-and"); 09045 } 09046 if (!res && vms->oldmessages) { 09047 res = say_and_wait(chan, vms->oldmessages, chan->language); 09048 if (!res) 09049 res = ast_play_and_wait(chan, "vm-Old"); 09050 } 09051 if (!res) { 09052 if (!vms->oldmessages && !vms->newmessages) { 09053 res = ast_play_and_wait(chan, "vm-no"); 09054 if (!res) 09055 res = ast_play_and_wait(chan, "vm-message"); 09056 } 09057 } 09058 } 09059 return res; 09060 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8993 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08994 { 08995 int res; 08996 /* Introduce messages they have */ 08997 res = ast_play_and_wait(chan, "vm-you"); 08998 08999 if (!res && vms->newmessages) { 09000 res = ast_play_and_wait(chan, "vm-have"); 09001 if (!res) 09002 res = say_and_wait(chan, vms->newmessages, chan->language); 09003 if (!res) 09004 res = ast_play_and_wait(chan, "vm-tong"); 09005 if (!res) 09006 res = ast_play_and_wait(chan, "vm-INBOX"); 09007 if (vms->oldmessages && !res) 09008 res = ast_play_and_wait(chan, "vm-and"); 09009 else if (!res) 09010 res = ast_play_and_wait(chan, "vm-messages"); 09011 } 09012 if (!res && vms->oldmessages) { 09013 res = ast_play_and_wait(chan, "vm-have"); 09014 if (!res) 09015 res = say_and_wait(chan, vms->oldmessages, chan->language); 09016 if (!res) 09017 res = ast_play_and_wait(chan, "vm-tong"); 09018 if (!res) 09019 res = ast_play_and_wait(chan, "vm-Old"); 09020 if (!res) 09021 res = ast_play_and_wait(chan, "vm-messages"); 09022 } 09023 if (!res && !vms->oldmessages && !vms->newmessages) { 09024 res = ast_play_and_wait(chan, "vm-haveno"); 09025 if (!res) 09026 res = ast_play_and_wait(chan, "vm-messages"); 09027 } 09028 return res; 09029 }
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 3278 of file app_voicemail_imapstorage.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().
03279 { 03280 switch (ast_lock_path(path)) { 03281 case AST_LOCK_TIMEOUT: 03282 return -1; 03283 default: 03284 return 0; 03285 } 03286 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1669 of file app_voicemail_imapstorage.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01670 { 01671 FILE *p = NULL; 01672 int pfd = mkstemp(template); 01673 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01674 if (pfd > -1) { 01675 p = fdopen(pfd, "w+"); 01676 if (!p) { 01677 close(pfd); 01678 pfd = -1; 01679 } 01680 } 01681 return p; 01682 }
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 9246 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, check_password(), ast_vm_user::context, play_record_review(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, and VM_FORCENAME.
Referenced by vm_execmain().
09247 { 09248 int cmd = 0; 09249 int duration = 0; 09250 int tries = 0; 09251 char newpassword[80] = ""; 09252 char newpassword2[80] = ""; 09253 char prefile[PATH_MAX] = ""; 09254 unsigned char buf[256]; 09255 int bytes = 0; 09256 09257 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09258 if (ast_adsi_available(chan)) { 09259 bytes += adsi_logo(buf + bytes); 09260 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09261 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09262 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09263 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09264 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09265 } 09266 09267 /* If forcename is set, have the user record their name */ 09268 if (ast_test_flag(vmu, VM_FORCENAME)) { 09269 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09270 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09271 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09272 if (cmd < 0 || cmd == 't' || cmd == '#') 09273 return cmd; 09274 } 09275 } 09276 09277 /* If forcegreetings is set, have the user record their greetings */ 09278 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09279 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09280 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09281 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09282 if (cmd < 0 || cmd == 't' || cmd == '#') 09283 return cmd; 09284 } 09285 09286 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09287 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09288 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09289 if (cmd < 0 || cmd == 't' || cmd == '#') 09290 return cmd; 09291 } 09292 } 09293 09294 /* 09295 * Change the password last since new users will be able to skip over any steps this one comes before 09296 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09297 */ 09298 for (;;) { 09299 newpassword[1] = '\0'; 09300 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09301 if (cmd == '#') 09302 newpassword[0] = '\0'; 09303 if (cmd < 0 || cmd == 't' || cmd == '#') 09304 return cmd; 09305 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09306 if (cmd < 0 || cmd == 't' || cmd == '#') 09307 return cmd; 09308 cmd = check_password(vmu, newpassword); /* perform password validation */ 09309 if (cmd != 0) { 09310 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09311 cmd = ast_play_and_wait(chan, vm_invalid_password); 09312 } else { 09313 newpassword2[1] = '\0'; 09314 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09315 if (cmd == '#') 09316 newpassword2[0] = '\0'; 09317 if (cmd < 0 || cmd == 't' || cmd == '#') 09318 return cmd; 09319 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09320 if (cmd < 0 || cmd == 't' || cmd == '#') 09321 return cmd; 09322 if (!strcmp(newpassword, newpassword2)) 09323 break; 09324 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09325 cmd = ast_play_and_wait(chan, vm_mismatch); 09326 } 09327 if (++tries == 3) 09328 return -1; 09329 if (cmd != 0) { 09330 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09331 } 09332 } 09333 if (pwdchange & PWDCHANGE_INTERNAL) 09334 vm_change_password(vmu, newpassword); 09335 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09336 vm_change_password_shell(vmu, newpassword); 09337 09338 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09339 cmd = ast_play_and_wait(chan, vm_passchanged); 09340 09341 return cmd; 09342 }
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 9344 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_waitfordigit(), check_password(), ast_vm_user::context, DISPOSE, ast_vm_user::mailbox, ast_vm_user::password, play_record_review(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), and vm_tempgreeting().
Referenced by vm_execmain().
09345 { 09346 int cmd = 0; 09347 int retries = 0; 09348 int duration = 0; 09349 char newpassword[80] = ""; 09350 char newpassword2[80] = ""; 09351 char prefile[PATH_MAX] = ""; 09352 unsigned char buf[256]; 09353 int bytes = 0; 09354 09355 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09356 if (ast_adsi_available(chan)) { 09357 bytes += adsi_logo(buf + bytes); 09358 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09359 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09360 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09361 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09362 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09363 } 09364 while ((cmd >= 0) && (cmd != 't')) { 09365 if (cmd) 09366 retries = 0; 09367 switch (cmd) { 09368 case '1': /* Record your unavailable message */ 09369 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09370 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09371 break; 09372 case '2': /* Record your busy message */ 09373 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09374 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09375 break; 09376 case '3': /* Record greeting */ 09377 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09378 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09379 break; 09380 case '4': /* manage the temporary greeting */ 09381 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09382 break; 09383 case '5': /* change password */ 09384 if (vmu->password[0] == '-') { 09385 cmd = ast_play_and_wait(chan, "vm-no"); 09386 break; 09387 } 09388 newpassword[1] = '\0'; 09389 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09390 if (cmd == '#') 09391 newpassword[0] = '\0'; 09392 else { 09393 if (cmd < 0) 09394 break; 09395 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09396 break; 09397 } 09398 } 09399 cmd = check_password(vmu, newpassword); /* perform password validation */ 09400 if (cmd != 0) { 09401 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09402 cmd = ast_play_and_wait(chan, vm_invalid_password); 09403 if (!cmd) { 09404 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09405 } 09406 break; 09407 } 09408 newpassword2[1] = '\0'; 09409 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09410 if (cmd == '#') 09411 newpassword2[0] = '\0'; 09412 else { 09413 if (cmd < 0) 09414 break; 09415 09416 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09417 break; 09418 } 09419 } 09420 if (strcmp(newpassword, newpassword2)) { 09421 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09422 cmd = ast_play_and_wait(chan, vm_mismatch); 09423 if (!cmd) { 09424 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09425 } 09426 break; 09427 } 09428 09429 if (pwdchange & PWDCHANGE_INTERNAL) { 09430 vm_change_password(vmu, newpassword); 09431 } 09432 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09433 vm_change_password_shell(vmu, newpassword); 09434 } 09435 09436 ast_debug(1, "User %s set password to %s of length %d\n", 09437 vms->username, newpassword, (int) strlen(newpassword)); 09438 cmd = ast_play_and_wait(chan, vm_passchanged); 09439 break; 09440 case '*': 09441 cmd = 't'; 09442 break; 09443 default: 09444 cmd = 0; 09445 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09446 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09447 if (ast_fileexists(prefile, NULL, NULL)) { 09448 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09449 } 09450 DISPOSE(prefile, -1); 09451 if (!cmd) { 09452 cmd = ast_play_and_wait(chan, "vm-options"); 09453 } 09454 if (!cmd) { 09455 cmd = ast_waitfordigit(chan, 6000); 09456 } 09457 if (!cmd) { 09458 retries++; 09459 } 09460 if (retries > 3) { 09461 cmd = 't'; 09462 } 09463 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09464 } 09465 } 09466 if (cmd == 't') 09467 cmd = 0; 09468 return cmd; 09469 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8139 of file app_voicemail_imapstorage.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().
08140 { 08141 int cmd; 08142 08143 if ( !strncasecmp(chan->language, "it", 2) || 08144 !strncasecmp(chan->language, "es", 2) || 08145 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08146 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08147 return cmd ? cmd : ast_play_and_wait(chan, box); 08148 } else if (!strncasecmp(chan->language, "gr", 2)) { 08149 return vm_play_folder_name_gr(chan, box); 08150 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08151 return ast_play_and_wait(chan, box); 08152 } else if (!strncasecmp(chan->language, "pl", 2)) { 08153 return vm_play_folder_name_pl(chan, box); 08154 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08155 return vm_play_folder_name_ua(chan, box); 08156 } else if (!strncasecmp(chan->language, "vi", 2)) { 08157 return ast_play_and_wait(chan, box); 08158 } else { /* Default English */ 08159 cmd = ast_play_and_wait(chan, box); 08160 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08161 } 08162 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8092 of file app_voicemail_imapstorage.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08093 { 08094 int cmd; 08095 char *buf; 08096 08097 buf = ast_alloca(strlen(box) + 2); 08098 strcpy(buf, box); 08099 strcat(buf, "s"); 08100 08101 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08102 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08103 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08104 } else { 08105 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08106 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08107 } 08108 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8110 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08111 { 08112 int cmd; 08113 08114 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08115 if (!strcasecmp(box, "vm-INBOX")) 08116 cmd = ast_play_and_wait(chan, "vm-new-e"); 08117 else 08118 cmd = ast_play_and_wait(chan, "vm-old-e"); 08119 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08120 } else { 08121 cmd = ast_play_and_wait(chan, "vm-messages"); 08122 return cmd ? cmd : ast_play_and_wait(chan, box); 08123 } 08124 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8126 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08127 { 08128 int cmd; 08129 08130 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08131 cmd = ast_play_and_wait(chan, "vm-messages"); 08132 return cmd ? cmd : ast_play_and_wait(chan, box); 08133 } else { 08134 cmd = ast_play_and_wait(chan, box); 08135 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08136 } 08137 }
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 9487 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_play_and_wait(), ast_test_suite_event_notify, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.
Referenced by vm_options().
09488 { 09489 int cmd = 0; 09490 int retries = 0; 09491 int duration = 0; 09492 char prefile[PATH_MAX] = ""; 09493 unsigned char buf[256]; 09494 int bytes = 0; 09495 09496 if (ast_adsi_available(chan)) { 09497 bytes += adsi_logo(buf + bytes); 09498 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09499 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09500 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09501 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09502 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09503 } 09504 09505 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09506 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09507 while ((cmd >= 0) && (cmd != 't')) { 09508 if (cmd) 09509 retries = 0; 09510 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09511 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09512 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09513 if (cmd == -1) { 09514 break; 09515 } 09516 cmd = 't'; 09517 } else { 09518 switch (cmd) { 09519 case '1': 09520 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09521 break; 09522 case '2': 09523 DELETE(prefile, -1, prefile, vmu); 09524 ast_play_and_wait(chan, "vm-tempremoved"); 09525 cmd = 't'; 09526 break; 09527 case '*': 09528 cmd = 't'; 09529 break; 09530 default: 09531 cmd = ast_play_and_wait(chan, 09532 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09533 "vm-tempgreeting2" : "vm-tempgreeting"); 09534 if (!cmd) { 09535 cmd = ast_waitfordigit(chan, 6000); 09536 } 09537 if (!cmd) { 09538 retries++; 09539 } 09540 if (retries > 3) { 09541 cmd = 't'; 09542 } 09543 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09544 } 09545 } 09546 DISPOSE(prefile, -1); 09547 } 09548 if (cmd == 't') 09549 cmd = 0; 09550 return cmd; 09551 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11439 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11441 { 11442 struct ast_vm_user *user; 11443 11444 AST_LIST_LOCK(&users); 11445 AST_LIST_TRAVERSE(&users, user, list) { 11446 vm_users_data_provider_get_helper(search, data_root, user); 11447 } 11448 AST_LIST_UNLOCK(&users); 11449 11450 return 0; 11451 }
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 11392 of file app_voicemail_imapstorage.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().
11394 { 11395 struct ast_data *data_user, *data_zone; 11396 struct ast_data *data_state; 11397 struct vm_zone *zone = NULL; 11398 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11399 char ext_context[256] = ""; 11400 11401 data_user = ast_data_add_node(data_root, "user"); 11402 if (!data_user) { 11403 return -1; 11404 } 11405 11406 ast_data_add_structure(ast_vm_user, data_user, user); 11407 11408 AST_LIST_LOCK(&zones); 11409 AST_LIST_TRAVERSE(&zones, zone, list) { 11410 if (!strcmp(zone->name, user->zonetag)) { 11411 break; 11412 } 11413 } 11414 AST_LIST_UNLOCK(&zones); 11415 11416 /* state */ 11417 data_state = ast_data_add_node(data_user, "state"); 11418 if (!data_state) { 11419 return -1; 11420 } 11421 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11422 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11423 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11424 ast_data_add_int(data_state, "newmsg", newmsg); 11425 ast_data_add_int(data_state, "oldmsg", oldmsg); 11426 11427 if (zone) { 11428 data_zone = ast_data_add_node(data_user, "zone"); 11429 ast_data_add_structure(vm_zone, data_zone, zone); 11430 } 11431 11432 if (!ast_data_search_match(search, data_user)) { 11433 ast_data_remove_node(data_root, data_user); 11434 } 11435 11436 return 0; 11437 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11078 of file app_voicemail_imapstorage.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().
11079 { 11080 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11081 struct ast_vm_user vmus; 11082 char *options = NULL; 11083 int silent = 0, skipuser = 0; 11084 int res = -1; 11085 11086 if (data) { 11087 s = ast_strdupa(data); 11088 user = strsep(&s, ","); 11089 options = strsep(&s, ","); 11090 if (user) { 11091 s = user; 11092 user = strsep(&s, "@"); 11093 context = strsep(&s, ""); 11094 if (!ast_strlen_zero(user)) 11095 skipuser++; 11096 ast_copy_string(mailbox, user, sizeof(mailbox)); 11097 } 11098 } 11099 11100 if (options) { 11101 silent = (strchr(options, 's')) != NULL; 11102 } 11103 11104 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11105 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11106 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11107 ast_play_and_wait(chan, "auth-thankyou"); 11108 res = 0; 11109 } else if (mailbox[0] == '*') { 11110 /* user entered '*' */ 11111 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11112 res = 0; /* prevent hangup */ 11113 } 11114 } 11115 11116 return res; 11117 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12618 of file app_voicemail_imapstorage.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().
12619 { 12620 char *context; 12621 char *args_copy; 12622 int res; 12623 12624 if (ast_strlen_zero(data)) { 12625 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12626 return -1; 12627 } 12628 12629 args_copy = ast_strdupa(data); 12630 if ((context = strchr(args_copy, '@'))) { 12631 *context++ = '\0'; 12632 } else { 12633 context = "default"; 12634 } 12635 12636 if ((res = sayname(chan, args_copy, context) < 0)) { 12637 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12638 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12639 if (!res) { 12640 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12641 } 12642 } 12643 12644 return res; 12645 }
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 4435 of file app_voicemail_imapstorage.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().
04436 { 04437 const struct vm_zone *z = NULL; 04438 struct timeval t = ast_tvnow(); 04439 04440 /* Does this user have a timezone specified? */ 04441 if (!ast_strlen_zero(vmu->zonetag)) { 04442 /* Find the zone in the list */ 04443 AST_LIST_LOCK(&zones); 04444 AST_LIST_TRAVERSE(&zones, z, list) { 04445 if (!strcmp(z->name, vmu->zonetag)) 04446 break; 04447 } 04448 AST_LIST_UNLOCK(&zones); 04449 } 04450 ast_localtime(&t, tm, z ? z->timezone : NULL); 04451 return tm; 04452 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7488 of file app_voicemail_imapstorage.c.
References ast_control_streamfile(), and ast_test_suite_event_notify.
Referenced by advanced_options(), and play_message().
07489 { 07490 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07491 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); 07492 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7480 of file app_voicemail_imapstorage.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().
07481 { 07482 int res; 07483 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07484 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07485 return res; 07486 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12585 of file app_voicemail_imapstorage.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().
12585 { 12586 struct ast_config *conf; 12587 struct ast_category *cat; 12588 struct ast_variable *var; 12589 int res = -1; 12590 12591 if (!(conf = ast_config_new())) { 12592 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12593 return res; 12594 } 12595 if (!(cat = ast_category_new("general", "", 1))) { 12596 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12597 ast_config_destroy(conf); 12598 return res; 12599 } 12600 if (!(var = ast_variable_new("password", password, ""))) { 12601 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12602 ast_config_destroy(conf); 12603 ast_category_destroy(cat); 12604 return res; 12605 } 12606 ast_category_append(conf, cat); 12607 ast_variable_append(cat, var); 12608 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12609 res = 0; 12610 } else { 12611 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12612 } 12613 12614 ast_config_destroy(conf); 12615 return res; 12616 }
char* addesc = "Comedian Mail" [static] |
Definition at line 776 of file app_voicemail_imapstorage.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 903 of file app_voicemail_imapstorage.c.
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 904 of file app_voicemail_imapstorage.c.
int adsiver = 1 [static] |
Definition at line 905 of file app_voicemail_imapstorage.c.
char* app = "VoiceMail" [static] |
Definition at line 779 of file app_voicemail_imapstorage.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 782 of file app_voicemail_imapstorage.c.
char* app3 = "MailboxExists" [static] |
Definition at line 784 of file app_voicemail_imapstorage.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 785 of file app_voicemail_imapstorage.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 889 of file app_voicemail_imapstorage.c.
char charset[32] = "ISO-8859-1" [static] |
Definition at line 901 of file app_voicemail_imapstorage.c.
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 892 of file app_voicemail_imapstorage.c.
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 11317 of file app_voicemail_imapstorage.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 888 of file app_voicemail_imapstorage.c.
char* emailbody = NULL [static] |
Definition at line 895 of file app_voicemail_imapstorage.c.
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 906 of file app_voicemail_imapstorage.c.
char* emailsubject = NULL [static] |
Definition at line 896 of file app_voicemail_imapstorage.c.
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 890 of file app_voicemail_imapstorage.c.
char ext_pass_check_cmd[128] [static] |
Definition at line 756 of file app_voicemail_imapstorage.c.
char ext_pass_cmd[128] [static] |
Definition at line 755 of file app_voicemail_imapstorage.c.
char externnotify[160] [static] |
Definition at line 799 of file app_voicemail_imapstorage.c.
char fromstring[100] [static] |
Definition at line 899 of file app_voicemail_imapstorage.c.
struct ast_flags globalflags = {0} [static] |
Definition at line 884 of file app_voicemail_imapstorage.c.
struct ao2_container* inprocess_container |
Definition at line 928 of file app_voicemail_imapstorage.c.
char listen_control_forward_key[12] [static] |
Definition at line 857 of file app_voicemail_imapstorage.c.
char listen_control_pause_key[12] [static] |
Definition at line 859 of file app_voicemail_imapstorage.c.
char listen_control_restart_key[12] [static] |
Definition at line 860 of file app_voicemail_imapstorage.c.
char listen_control_reverse_key[12] [static] |
Definition at line 858 of file app_voicemail_imapstorage.c.
char listen_control_stop_key[12] [static] |
Definition at line 861 of file app_voicemail_imapstorage.c.
char locale[20] [static] |
Definition at line 792 of file app_voicemail_imapstorage.c.
struct ast_custom_function mailbox_exists_acf [static] |
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11073 of file app_voicemail_imapstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1705 of file app_voicemail_imapstorage.c.
char mailcmd[160] [static] |
Definition at line 798 of file app_voicemail_imapstorage.c.
int maxdeletedmsg [static] |
Definition at line 795 of file app_voicemail_imapstorage.c.
int maxgreet [static] |
Definition at line 805 of file app_voicemail_imapstorage.c.
int maxlogins [static] |
Definition at line 807 of file app_voicemail_imapstorage.c.
int maxmsg [static] |
Definition at line 794 of file app_voicemail_imapstorage.c.
int maxsilence [static] |
Definition at line 793 of file app_voicemail_imapstorage.c.
int minpassword [static] |
Definition at line 808 of file app_voicemail_imapstorage.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 826 of file app_voicemail_imapstorage.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 852 of file app_voicemail_imapstorage.c.
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 828 of file app_voicemail_imapstorage.c.
int my_umask [static] |
Definition at line 758 of file app_voicemail_imapstorage.c.
char* pagerbody = NULL [static] |
Definition at line 897 of file app_voicemail_imapstorage.c.
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 907 of file app_voicemail_imapstorage.c.
char pagerfromstring[100] [static] |
Definition at line 900 of file app_voicemail_imapstorage.c.
char* pagersubject = NULL [static] |
Definition at line 898 of file app_voicemail_imapstorage.c.
int passwordlocation [static] |
Definition at line 809 of file app_voicemail_imapstorage.c.
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 821 of file app_voicemail_imapstorage.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 816 of file app_voicemail_imapstorage.c.
unsigned int poll_mailboxes [static] |
Poll mailboxes for changes since there is something external to app_voicemail that may change them.
Definition at line 813 of file app_voicemail_imapstorage.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 822 of file app_voicemail_imapstorage.c.
unsigned char poll_thread_run [static] |
Definition at line 823 of file app_voicemail_imapstorage.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 762 of file app_voicemail_imapstorage.c.
int saydurationminfo [static] |
Definition at line 886 of file app_voicemail_imapstorage.c.
char* sayname_app = "VMSayName" [static] |
Definition at line 787 of file app_voicemail_imapstorage.c.
char serveremail[80] [static] |
Definition at line 797 of file app_voicemail_imapstorage.c.
int silencethreshold = 128 [static] |
Definition at line 796 of file app_voicemail_imapstorage.c.
int skipms [static] |
Definition at line 806 of file app_voicemail_imapstorage.c.
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 800 of file app_voicemail_imapstorage.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 774 of file app_voicemail_imapstorage.c.
struct ast_data_entry vm_data_providers[] [static] |
{ }
Definition at line 11458 of file app_voicemail_imapstorage.c.
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 869 of file app_voicemail_imapstorage.c.
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 868 of file app_voicemail_imapstorage.c.
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 865 of file app_voicemail_imapstorage.c.
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 866 of file app_voicemail_imapstorage.c.
char vm_password[80] = "vm-password" [static] |
Definition at line 864 of file app_voicemail_imapstorage.c.
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 870 of file app_voicemail_imapstorage.c.
char vm_prepend_timeout[80] = "vm-then-pound" [static] |
Definition at line 882 of file app_voicemail_imapstorage.c.
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 867 of file app_voicemail_imapstorage.c.
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 753 of file app_voicemail_imapstorage.c.
struct ast_data_handler vm_users_data_provider [static] |
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11453 of file app_voicemail_imapstorage.c.
char vmfmts[80] [static] |
Definition at line 801 of file app_voicemail_imapstorage.c.
int vmmaxsecs [static] |
Definition at line 804 of file app_voicemail_imapstorage.c.
int vmminsecs [static] |
Definition at line 803 of file app_voicemail_imapstorage.c.
double volgain [static] |
Definition at line 802 of file app_voicemail_imapstorage.c.
char zonetag[80] [static] |
Definition at line 791 of file app_voicemail_imapstorage.c.