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