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_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_latin (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Common LATIN languages 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 11304 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 11331 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 11007 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().
11008 { 11009 struct ast_vm_user svm; 11010 AST_DECLARE_APP_ARGS(arg, 11011 AST_APP_ARG(mbox); 11012 AST_APP_ARG(context); 11013 ); 11014 11015 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11016 11017 if (ast_strlen_zero(arg.mbox)) { 11018 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11019 return -1; 11020 } 11021 11022 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11023 return 0; 11024 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11841 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().
11842 { 11843 struct ast_vm_user *current; 11844 char *cat; 11845 struct ast_variable *var; 11846 const char *val; 11847 char *q, *stringp, *tmp; 11848 int x; 11849 unsigned int tmpadsi[4]; 11850 char secretfn[PATH_MAX] = ""; 11851 11852 #ifdef IMAP_STORAGE 11853 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11854 #endif 11855 /* set audio control prompts */ 11856 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11857 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11858 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11859 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11860 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11861 11862 /* Free all the users structure */ 11863 free_vm_users(); 11864 11865 /* Free all the zones structure */ 11866 free_vm_zones(); 11867 11868 AST_LIST_LOCK(&users); 11869 11870 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11871 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11872 11873 if (cfg) { 11874 /* General settings */ 11875 11876 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11877 val = "default"; 11878 ast_copy_string(userscontext, val, sizeof(userscontext)); 11879 /* Attach voice message to mail message ? */ 11880 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11881 val = "yes"; 11882 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11883 11884 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11885 val = "no"; 11886 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11887 11888 volgain = 0.0; 11889 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11890 sscanf(val, "%30lf", &volgain); 11891 11892 #ifdef ODBC_STORAGE 11893 strcpy(odbc_database, "asterisk"); 11894 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11895 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11896 } 11897 strcpy(odbc_table, "voicemessages"); 11898 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11899 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11900 } 11901 #endif 11902 /* Mail command */ 11903 strcpy(mailcmd, SENDMAIL); 11904 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11905 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11906 11907 maxsilence = 0; 11908 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11909 maxsilence = atoi(val); 11910 if (maxsilence > 0) 11911 maxsilence *= 1000; 11912 } 11913 11914 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11915 maxmsg = MAXMSG; 11916 } else { 11917 maxmsg = atoi(val); 11918 if (maxmsg < 0) { 11919 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11920 maxmsg = MAXMSG; 11921 } else if (maxmsg > MAXMSGLIMIT) { 11922 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11923 maxmsg = MAXMSGLIMIT; 11924 } 11925 } 11926 11927 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11928 maxdeletedmsg = 0; 11929 } else { 11930 if (sscanf(val, "%30d", &x) == 1) 11931 maxdeletedmsg = x; 11932 else if (ast_true(val)) 11933 maxdeletedmsg = MAXMSG; 11934 else 11935 maxdeletedmsg = 0; 11936 11937 if (maxdeletedmsg < 0) { 11938 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11939 maxdeletedmsg = MAXMSG; 11940 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11941 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11942 maxdeletedmsg = MAXMSGLIMIT; 11943 } 11944 } 11945 11946 /* Load date format config for voicemail mail */ 11947 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11948 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11949 } 11950 11951 /* Load date format config for voicemail pager mail */ 11952 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11953 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11954 } 11955 11956 /* External password changing command */ 11957 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11958 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11959 pwdchange = PWDCHANGE_EXTERNAL; 11960 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11961 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11962 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11963 } 11964 11965 /* External password validation command */ 11966 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11967 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11968 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11969 } 11970 11971 #ifdef IMAP_STORAGE 11972 /* IMAP server address */ 11973 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11974 ast_copy_string(imapserver, val, sizeof(imapserver)); 11975 } else { 11976 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11977 } 11978 /* IMAP server port */ 11979 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11980 ast_copy_string(imapport, val, sizeof(imapport)); 11981 } else { 11982 ast_copy_string(imapport, "143", sizeof(imapport)); 11983 } 11984 /* IMAP server flags */ 11985 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11986 ast_copy_string(imapflags, val, sizeof(imapflags)); 11987 } 11988 /* IMAP server master username */ 11989 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11990 ast_copy_string(authuser, val, sizeof(authuser)); 11991 } 11992 /* IMAP server master password */ 11993 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11994 ast_copy_string(authpassword, val, sizeof(authpassword)); 11995 } 11996 /* Expunge on exit */ 11997 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11998 if (ast_false(val)) 11999 expungeonhangup = 0; 12000 else 12001 expungeonhangup = 1; 12002 } else { 12003 expungeonhangup = 1; 12004 } 12005 /* IMAP voicemail folder */ 12006 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12007 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12008 } else { 12009 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12010 } 12011 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12012 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12013 } 12014 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12015 imapgreetings = ast_true(val); 12016 } else { 12017 imapgreetings = 0; 12018 } 12019 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12020 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12021 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12022 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12023 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12024 } else { 12025 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12026 } 12027 12028 /* There is some very unorthodox casting done here. This is due 12029 * to the way c-client handles the argument passed in. It expects a 12030 * void pointer and casts the pointer directly to a long without 12031 * first dereferencing it. */ 12032 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12033 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12034 } else { 12035 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12036 } 12037 12038 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12039 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12040 } else { 12041 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12042 } 12043 12044 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12045 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12046 } else { 12047 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12048 } 12049 12050 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12051 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12052 } else { 12053 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12054 } 12055 12056 /* Increment configuration version */ 12057 imapversion++; 12058 #endif 12059 /* External voicemail notify application */ 12060 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12061 ast_copy_string(externnotify, val, sizeof(externnotify)); 12062 ast_debug(1, "found externnotify: %s\n", externnotify); 12063 } else { 12064 externnotify[0] = '\0'; 12065 } 12066 12067 /* SMDI voicemail notification */ 12068 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12069 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12070 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12071 smdi_iface = ast_smdi_interface_find(val); 12072 } else { 12073 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12074 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12075 } 12076 if (!smdi_iface) { 12077 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12078 } 12079 } 12080 12081 /* Silence treshold */ 12082 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12083 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12084 silencethreshold = atoi(val); 12085 12086 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12087 val = ASTERISK_USERNAME; 12088 ast_copy_string(serveremail, val, sizeof(serveremail)); 12089 12090 vmmaxsecs = 0; 12091 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12092 if (sscanf(val, "%30d", &x) == 1) { 12093 vmmaxsecs = x; 12094 } else { 12095 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12096 } 12097 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12098 static int maxmessage_deprecate = 0; 12099 if (maxmessage_deprecate == 0) { 12100 maxmessage_deprecate = 1; 12101 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12102 } 12103 if (sscanf(val, "%30d", &x) == 1) { 12104 vmmaxsecs = x; 12105 } else { 12106 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12107 } 12108 } 12109 12110 vmminsecs = 0; 12111 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12112 if (sscanf(val, "%30d", &x) == 1) { 12113 vmminsecs = x; 12114 if (maxsilence / 1000 >= vmminsecs) { 12115 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12116 } 12117 } else { 12118 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12119 } 12120 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12121 static int maxmessage_deprecate = 0; 12122 if (maxmessage_deprecate == 0) { 12123 maxmessage_deprecate = 1; 12124 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12125 } 12126 if (sscanf(val, "%30d", &x) == 1) { 12127 vmminsecs = x; 12128 if (maxsilence / 1000 >= vmminsecs) { 12129 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12130 } 12131 } else { 12132 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12133 } 12134 } 12135 12136 val = ast_variable_retrieve(cfg, "general", "format"); 12137 if (!val) { 12138 val = "wav"; 12139 } else { 12140 tmp = ast_strdupa(val); 12141 val = ast_format_str_reduce(tmp); 12142 if (!val) { 12143 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12144 val = "wav"; 12145 } 12146 } 12147 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12148 12149 skipms = 3000; 12150 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12151 if (sscanf(val, "%30d", &x) == 1) { 12152 maxgreet = x; 12153 } else { 12154 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12155 } 12156 } 12157 12158 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12159 if (sscanf(val, "%30d", &x) == 1) { 12160 skipms = x; 12161 } else { 12162 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12163 } 12164 } 12165 12166 maxlogins = 3; 12167 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12168 if (sscanf(val, "%30d", &x) == 1) { 12169 maxlogins = x; 12170 } else { 12171 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12172 } 12173 } 12174 12175 minpassword = MINPASSWORD; 12176 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12177 if (sscanf(val, "%30d", &x) == 1) { 12178 minpassword = x; 12179 } else { 12180 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12181 } 12182 } 12183 12184 /* Force new user to record name ? */ 12185 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12186 val = "no"; 12187 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12188 12189 /* Force new user to record greetings ? */ 12190 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12191 val = "no"; 12192 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12193 12194 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12195 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12196 stringp = ast_strdupa(val); 12197 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12198 if (!ast_strlen_zero(stringp)) { 12199 q = strsep(&stringp, ","); 12200 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12201 q++; 12202 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12203 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12204 } else { 12205 cidinternalcontexts[x][0] = '\0'; 12206 } 12207 } 12208 } 12209 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12210 ast_debug(1, "VM Review Option disabled globally\n"); 12211 val = "no"; 12212 } 12213 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12214 12215 /* Temporary greeting reminder */ 12216 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12217 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12218 val = "no"; 12219 } else { 12220 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12221 } 12222 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12223 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12224 ast_debug(1, "VM next message wrap disabled globally\n"); 12225 val = "no"; 12226 } 12227 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12228 12229 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12230 ast_debug(1, "VM Operator break disabled globally\n"); 12231 val = "no"; 12232 } 12233 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12234 12235 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12236 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12237 val = "no"; 12238 } 12239 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12240 12241 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12242 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12243 val = "no"; 12244 } 12245 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12246 12247 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12248 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12249 val = "yes"; 12250 } 12251 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12252 12253 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12254 ast_debug(1, "Move Heard enabled globally\n"); 12255 val = "yes"; 12256 } 12257 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12258 12259 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12260 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12261 val = "no"; 12262 } 12263 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12264 12265 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12266 ast_debug(1, "Duration info before msg enabled globally\n"); 12267 val = "yes"; 12268 } 12269 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12270 12271 saydurationminfo = 2; 12272 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12273 if (sscanf(val, "%30d", &x) == 1) { 12274 saydurationminfo = x; 12275 } else { 12276 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12277 } 12278 } 12279 12280 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12281 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12282 val = "no"; 12283 } 12284 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12285 12286 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12287 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12288 ast_debug(1, "found dialout context: %s\n", dialcontext); 12289 } else { 12290 dialcontext[0] = '\0'; 12291 } 12292 12293 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12294 ast_copy_string(callcontext, val, sizeof(callcontext)); 12295 ast_debug(1, "found callback context: %s\n", callcontext); 12296 } else { 12297 callcontext[0] = '\0'; 12298 } 12299 12300 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12301 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12302 ast_debug(1, "found operator context: %s\n", exitcontext); 12303 } else { 12304 exitcontext[0] = '\0'; 12305 } 12306 12307 /* load password sounds configuration */ 12308 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12309 ast_copy_string(vm_password, val, sizeof(vm_password)); 12310 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12311 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12312 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12313 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12314 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12315 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12316 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12317 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12318 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12319 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12320 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12321 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12322 } 12323 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12324 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12325 } 12326 /* load configurable audio prompts */ 12327 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12328 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12329 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12330 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12331 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12332 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12333 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12334 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12335 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12336 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12337 12338 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12339 val = "no"; 12340 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12341 12342 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12343 val = "voicemail.conf"; 12344 } 12345 if (!(strcmp(val, "spooldir"))) { 12346 passwordlocation = OPT_PWLOC_SPOOLDIR; 12347 } else { 12348 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12349 } 12350 12351 poll_freq = DEFAULT_POLL_FREQ; 12352 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12353 if (sscanf(val, "%30u", &poll_freq) != 1) { 12354 poll_freq = DEFAULT_POLL_FREQ; 12355 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12356 } 12357 } 12358 12359 poll_mailboxes = 0; 12360 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12361 poll_mailboxes = ast_true(val); 12362 12363 memset(fromstring, 0, sizeof(fromstring)); 12364 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12365 strcpy(charset, "ISO-8859-1"); 12366 if (emailbody) { 12367 ast_free(emailbody); 12368 emailbody = NULL; 12369 } 12370 if (emailsubject) { 12371 ast_free(emailsubject); 12372 emailsubject = NULL; 12373 } 12374 if (pagerbody) { 12375 ast_free(pagerbody); 12376 pagerbody = NULL; 12377 } 12378 if (pagersubject) { 12379 ast_free(pagersubject); 12380 pagersubject = NULL; 12381 } 12382 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12383 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12384 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12385 ast_copy_string(fromstring, val, sizeof(fromstring)); 12386 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12387 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12388 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12389 ast_copy_string(charset, val, sizeof(charset)); 12390 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12391 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12392 for (x = 0; x < 4; x++) { 12393 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12394 } 12395 } 12396 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12397 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12398 for (x = 0; x < 4; x++) { 12399 memcpy(&adsisec[x], &tmpadsi[x], 1); 12400 } 12401 } 12402 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12403 if (atoi(val)) { 12404 adsiver = atoi(val); 12405 } 12406 } 12407 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12408 ast_copy_string(zonetag, val, sizeof(zonetag)); 12409 } 12410 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12411 ast_copy_string(locale, val, sizeof(locale)); 12412 } 12413 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12414 emailsubject = ast_strdup(substitute_escapes(val)); 12415 } 12416 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12417 emailbody = ast_strdup(substitute_escapes(val)); 12418 } 12419 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12420 pagersubject = ast_strdup(substitute_escapes(val)); 12421 } 12422 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12423 pagerbody = ast_strdup(substitute_escapes(val)); 12424 } 12425 12426 /* load mailboxes from users.conf */ 12427 if (ucfg) { 12428 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12429 if (!strcasecmp(cat, "general")) { 12430 continue; 12431 } 12432 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12433 continue; 12434 if ((current = find_or_create(userscontext, cat))) { 12435 populate_defaults(current); 12436 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12437 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12438 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12439 current->passwordlocation = OPT_PWLOC_USERSCONF; 12440 } 12441 12442 switch (current->passwordlocation) { 12443 case OPT_PWLOC_SPOOLDIR: 12444 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12445 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12446 } 12447 } 12448 } 12449 } 12450 12451 /* load mailboxes from voicemail.conf */ 12452 cat = ast_category_browse(cfg, NULL); 12453 while (cat) { 12454 if (strcasecmp(cat, "general")) { 12455 var = ast_variable_browse(cfg, cat); 12456 if (strcasecmp(cat, "zonemessages")) { 12457 /* Process mailboxes in this context */ 12458 while (var) { 12459 append_mailbox(cat, var->name, var->value); 12460 var = var->next; 12461 } 12462 } else { 12463 /* Timezones in this context */ 12464 while (var) { 12465 struct vm_zone *z; 12466 if ((z = ast_malloc(sizeof(*z)))) { 12467 char *msg_format, *tzone; 12468 msg_format = ast_strdupa(var->value); 12469 tzone = strsep(&msg_format, "|,"); 12470 if (msg_format) { 12471 ast_copy_string(z->name, var->name, sizeof(z->name)); 12472 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12473 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12474 AST_LIST_LOCK(&zones); 12475 AST_LIST_INSERT_HEAD(&zones, z, list); 12476 AST_LIST_UNLOCK(&zones); 12477 } else { 12478 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12479 ast_free(z); 12480 } 12481 } else { 12482 AST_LIST_UNLOCK(&users); 12483 return -1; 12484 } 12485 var = var->next; 12486 } 12487 } 12488 } 12489 cat = ast_category_browse(cfg, cat); 12490 } 12491 12492 AST_LIST_UNLOCK(&users); 12493 12494 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12495 start_poll_thread(); 12496 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12497 stop_poll_thread();; 12498 12499 return 0; 12500 } else { 12501 AST_LIST_UNLOCK(&users); 12502 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12503 return 0; 12504 } 12505 }
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 13213 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().
13214 { 13215 int res = 0; 13216 char filename[PATH_MAX]; 13217 struct ast_config *msg_cfg = NULL; 13218 const char *origtime, *context; 13219 char *name, *num; 13220 int retries = 0; 13221 char *cid; 13222 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13223 13224 vms->starting = 0; 13225 13226 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13227 13228 /* Retrieve info from VM attribute file */ 13229 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13230 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13231 msg_cfg = ast_config_load(filename, config_flags); 13232 DISPOSE(vms->curdir, vms->curmsg); 13233 if (!valid_config(msg_cfg)) { 13234 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13235 return 0; 13236 } 13237 13238 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13239 ast_config_destroy(msg_cfg); 13240 return 0; 13241 } 13242 13243 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13244 13245 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13246 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13247 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13248 switch (option) { 13249 case 3: /* Play message envelope */ 13250 if (!res) 13251 res = play_message_datetime(chan, vmu, origtime, filename); 13252 if (!res) 13253 res = play_message_callerid(chan, vms, cid, context, 0); 13254 13255 res = 't'; 13256 break; 13257 13258 case 2: /* Call back */ 13259 13260 if (ast_strlen_zero(cid)) 13261 break; 13262 13263 ast_callerid_parse(cid, &name, &num); 13264 while ((res > -1) && (res != 't')) { 13265 switch (res) { 13266 case '1': 13267 if (num) { 13268 /* Dial the CID number */ 13269 res = dialout(chan, vmu, num, vmu->callback); 13270 if (res) { 13271 ast_config_destroy(msg_cfg); 13272 return 9; 13273 } 13274 } else { 13275 res = '2'; 13276 } 13277 break; 13278 13279 case '2': 13280 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13281 if (!ast_strlen_zero(vmu->dialout)) { 13282 res = dialout(chan, vmu, NULL, vmu->dialout); 13283 if (res) { 13284 ast_config_destroy(msg_cfg); 13285 return 9; 13286 } 13287 } else { 13288 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13289 res = ast_play_and_wait(chan, "vm-sorry"); 13290 } 13291 ast_config_destroy(msg_cfg); 13292 return res; 13293 case '*': 13294 res = 't'; 13295 break; 13296 case '3': 13297 case '4': 13298 case '5': 13299 case '6': 13300 case '7': 13301 case '8': 13302 case '9': 13303 case '0': 13304 13305 res = ast_play_and_wait(chan, "vm-sorry"); 13306 retries++; 13307 break; 13308 default: 13309 if (num) { 13310 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13311 res = ast_play_and_wait(chan, "vm-num-i-have"); 13312 if (!res) 13313 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13314 if (!res) 13315 res = ast_play_and_wait(chan, "vm-tocallnum"); 13316 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13317 if (!ast_strlen_zero(vmu->dialout)) { 13318 if (!res) 13319 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13320 } 13321 } else { 13322 res = ast_play_and_wait(chan, "vm-nonumber"); 13323 if (!ast_strlen_zero(vmu->dialout)) { 13324 if (!res) 13325 res = ast_play_and_wait(chan, "vm-toenternumber"); 13326 } 13327 } 13328 if (!res) { 13329 res = ast_play_and_wait(chan, "vm-star-cancel"); 13330 } 13331 if (!res) { 13332 res = ast_waitfordigit(chan, 6000); 13333 } 13334 if (!res) { 13335 retries++; 13336 if (retries > 3) { 13337 res = 't'; 13338 } 13339 } 13340 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13341 break; 13342 13343 } 13344 if (res == 't') 13345 res = 0; 13346 else if (res == '*') 13347 res = -1; 13348 } 13349 break; 13350 13351 case 1: /* Reply */ 13352 /* Send reply directly to sender */ 13353 if (ast_strlen_zero(cid)) 13354 break; 13355 13356 ast_callerid_parse(cid, &name, &num); 13357 if (!num) { 13358 ast_verb(3, "No CID number available, no reply sent\n"); 13359 if (!res) 13360 res = ast_play_and_wait(chan, "vm-nonumber"); 13361 ast_config_destroy(msg_cfg); 13362 return res; 13363 } else { 13364 struct ast_vm_user vmu2; 13365 if (find_user(&vmu2, vmu->context, num)) { 13366 struct leave_vm_options leave_options; 13367 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13368 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13369 13370 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13371 13372 memset(&leave_options, 0, sizeof(leave_options)); 13373 leave_options.record_gain = record_gain; 13374 res = leave_voicemail(chan, mailbox, &leave_options); 13375 if (!res) 13376 res = 't'; 13377 ast_config_destroy(msg_cfg); 13378 return res; 13379 } else { 13380 /* Sender has no mailbox, can't reply */ 13381 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13382 ast_play_and_wait(chan, "vm-nobox"); 13383 res = 't'; 13384 ast_config_destroy(msg_cfg); 13385 return res; 13386 } 13387 } 13388 res = 0; 13389 13390 break; 13391 } 13392 13393 ast_config_destroy(msg_cfg); 13394 13395 #ifndef IMAP_STORAGE 13396 if (!res) { 13397 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13398 vms->heard[msg] = 1; 13399 res = wait_file(chan, vms, vms->fn); 13400 } 13401 #endif 13402 return res; 13403 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10734 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().
10735 { 10736 /* Assumes lock is already held */ 10737 char *tmp; 10738 char *stringp; 10739 char *s; 10740 struct ast_vm_user *vmu; 10741 char *mailbox_full; 10742 int new = 0, old = 0, urgent = 0; 10743 char secretfn[PATH_MAX] = ""; 10744 10745 tmp = ast_strdupa(data); 10746 10747 if (!(vmu = find_or_create(context, box))) 10748 return -1; 10749 10750 populate_defaults(vmu); 10751 10752 stringp = tmp; 10753 if ((s = strsep(&stringp, ","))) { 10754 if (!ast_strlen_zero(s) && s[0] == '*') { 10755 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10756 "\n\tmust be reset in voicemail.conf.\n", box); 10757 } 10758 /* assign password regardless of validity to prevent NULL password from being assigned */ 10759 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10760 } 10761 if (stringp && (s = strsep(&stringp, ","))) { 10762 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10763 } 10764 if (stringp && (s = strsep(&stringp, ","))) { 10765 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10766 } 10767 if (stringp && (s = strsep(&stringp, ","))) { 10768 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10769 } 10770 if (stringp && (s = strsep(&stringp, ","))) { 10771 apply_options(vmu, s); 10772 } 10773 10774 switch (vmu->passwordlocation) { 10775 case OPT_PWLOC_SPOOLDIR: 10776 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10777 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10778 } 10779 10780 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10781 strcpy(mailbox_full, box); 10782 strcat(mailbox_full, "@"); 10783 strcat(mailbox_full, context); 10784 10785 inboxcount2(mailbox_full, &urgent, &new, &old); 10786 queue_mwi_event(mailbox_full, urgent, new, old); 10787 10788 return 0; 10789 }
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 10791 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.
10792 { 10793 int res = 0; 10794 struct ast_vm_user *vmu; 10795 /* language parameter seems to only be used for display in manager action */ 10796 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10797 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10798 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10799 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10800 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10801 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10802 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10803 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10804 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10805 #ifdef IMAP_STORAGE 10806 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10807 "imapfolder=INBOX|imapvmshareid=6000"; 10808 #endif 10809 10810 switch (cmd) { 10811 case TEST_INIT: 10812 info->name = "vmuser"; 10813 info->category = "/apps/app_voicemail/"; 10814 info->summary = "Vmuser unit test"; 10815 info->description = 10816 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10817 return AST_TEST_NOT_RUN; 10818 case TEST_EXECUTE: 10819 break; 10820 } 10821 10822 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10823 return AST_TEST_NOT_RUN; 10824 } 10825 populate_defaults(vmu); 10826 ast_set_flag(vmu, VM_ALLOCED); 10827 10828 apply_options(vmu, options_string); 10829 10830 if (!ast_test_flag(vmu, VM_ATTACH)) { 10831 ast_test_status_update(test, "Parse failure for attach option\n"); 10832 res = 1; 10833 } 10834 if (strcasecmp(vmu->attachfmt, "wav49")) { 10835 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10836 res = 1; 10837 } 10838 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10839 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10840 res = 1; 10841 } 10842 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10843 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10844 res = 1; 10845 } 10846 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10847 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10848 res = 1; 10849 } 10850 if (strcasecmp(vmu->zonetag, "central")) { 10851 ast_test_status_update(test, "Parse failure for tz option\n"); 10852 res = 1; 10853 } 10854 if (!ast_test_flag(vmu, VM_DELETE)) { 10855 ast_test_status_update(test, "Parse failure for delete option\n"); 10856 res = 1; 10857 } 10858 if (!ast_test_flag(vmu, VM_SAYCID)) { 10859 ast_test_status_update(test, "Parse failure for saycid option\n"); 10860 res = 1; 10861 } 10862 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10863 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10864 res = 1; 10865 } 10866 if (!ast_test_flag(vmu, VM_REVIEW)) { 10867 ast_test_status_update(test, "Parse failure for review option\n"); 10868 res = 1; 10869 } 10870 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10871 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10872 res = 1; 10873 } 10874 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10875 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10876 res = 1; 10877 } 10878 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10879 ast_test_status_update(test, "Parse failure for operator option\n"); 10880 res = 1; 10881 } 10882 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10883 ast_test_status_update(test, "Parse failure for envelope option\n"); 10884 res = 1; 10885 } 10886 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10887 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10888 res = 1; 10889 } 10890 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10891 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10892 res = 1; 10893 } 10894 if (vmu->saydurationm != 5) { 10895 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10896 res = 1; 10897 } 10898 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10899 ast_test_status_update(test, "Parse failure for forcename option\n"); 10900 res = 1; 10901 } 10902 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10903 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10904 res = 1; 10905 } 10906 if (strcasecmp(vmu->callback, "somecontext")) { 10907 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10908 res = 1; 10909 } 10910 if (strcasecmp(vmu->dialout, "somecontext2")) { 10911 ast_test_status_update(test, "Parse failure for dialout option\n"); 10912 res = 1; 10913 } 10914 if (strcasecmp(vmu->exit, "somecontext3")) { 10915 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10916 res = 1; 10917 } 10918 if (vmu->minsecs != 10) { 10919 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10920 res = 1; 10921 } 10922 if (vmu->maxsecs != 100) { 10923 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10924 res = 1; 10925 } 10926 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10927 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10928 res = 1; 10929 } 10930 if (vmu->maxdeletedmsg != 50) { 10931 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10932 res = 1; 10933 } 10934 if (vmu->volgain != 1.3) { 10935 ast_test_status_update(test, "Parse failure for volgain option\n"); 10936 res = 1; 10937 } 10938 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10939 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10940 res = 1; 10941 } 10942 #ifdef IMAP_STORAGE 10943 apply_options(vmu, option_string2); 10944 10945 if (strcasecmp(vmu->imapuser, "imapuser")) { 10946 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10947 res = 1; 10948 } 10949 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10950 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10951 res = 1; 10952 } 10953 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10954 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 10955 res = 1; 10956 } 10957 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10958 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10959 res = 1; 10960 } 10961 #endif 10962 10963 free_user(vmu); 10964 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10965 }
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 11111 of file app_voicemail_imapstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11112 { 11113 int which = 0; 11114 int wordlen; 11115 struct ast_vm_user *vmu; 11116 const char *context = ""; 11117 11118 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11119 if (pos > 4) 11120 return NULL; 11121 if (pos == 3) 11122 return (state == 0) ? ast_strdup("for") : NULL; 11123 wordlen = strlen(word); 11124 AST_LIST_TRAVERSE(&users, vmu, list) { 11125 if (!strncasecmp(word, vmu->context, wordlen)) { 11126 if (context && strcmp(context, vmu->context) && ++which > state) 11127 return ast_strdup(vmu->context); 11128 /* ignore repeated contexts ? */ 11129 context = vmu->context; 11130 } 11131 } 11132 return NULL; 11133 }
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 13140 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().
13141 { 13142 int cmd = 0; 13143 char destination[80] = ""; 13144 int retries = 0; 13145 13146 if (!num) { 13147 ast_verb(3, "Destination number will be entered manually\n"); 13148 while (retries < 3 && cmd != 't') { 13149 destination[1] = '\0'; 13150 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13151 if (!cmd) 13152 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13153 if (!cmd) 13154 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13155 if (!cmd) { 13156 cmd = ast_waitfordigit(chan, 6000); 13157 if (cmd) 13158 destination[0] = cmd; 13159 } 13160 if (!cmd) { 13161 retries++; 13162 } else { 13163 13164 if (cmd < 0) 13165 return 0; 13166 if (cmd == '*') { 13167 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13168 return 0; 13169 } 13170 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13171 retries++; 13172 else 13173 cmd = 't'; 13174 } 13175 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13176 } 13177 if (retries >= 3) { 13178 return 0; 13179 } 13180 13181 } else { 13182 if (option_verbose > 2) 13183 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13184 ast_copy_string(destination, num, sizeof(destination)); 13185 } 13186 13187 if (!ast_strlen_zero(destination)) { 13188 if (destination[strlen(destination) -1 ] == '*') 13189 return 0; 13190 if (option_verbose > 2) 13191 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13192 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13193 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13194 chan->priority = 0; 13195 return 9; 13196 } 13197 return 0; 13198 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10694 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().
10695 { 10696 struct ast_vm_user *vmu; 10697 10698 if (!ast_strlen_zero(box) && box[0] == '*') { 10699 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10700 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10701 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10702 "\n\tand will be ignored.\n", box, context); 10703 return NULL; 10704 } 10705 10706 AST_LIST_TRAVERSE(&users, vmu, list) { 10707 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10708 if (strcasecmp(vmu->context, context)) { 10709 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10710 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10711 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10712 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10713 } 10714 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10715 return NULL; 10716 } 10717 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10718 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10719 return NULL; 10720 } 10721 } 10722 10723 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10724 return NULL; 10725 10726 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10727 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10728 10729 AST_LIST_INSERT_TAIL(&users, vmu, list); 10730 10731 return vmu; 10732 }
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 11723 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().
11724 { 11725 struct ast_vm_user *current; 11726 AST_LIST_LOCK(&users); 11727 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11728 ast_set_flag(current, VM_ALLOCED); 11729 free_user(current); 11730 } 11731 AST_LIST_UNLOCK(&users); 11732 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11735 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().
11736 { 11737 struct vm_zone *zcur; 11738 AST_LIST_LOCK(&zones); 11739 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11740 free_zone(zcur); 11741 AST_LIST_UNLOCK(&zones); 11742 }
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 11493 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().
11494 { 11495 unsigned int len; 11496 struct mwi_sub *mwi_sub; 11497 struct mwi_sub_task *p = datap; 11498 11499 len = sizeof(*mwi_sub); 11500 if (!ast_strlen_zero(p->mailbox)) 11501 len += strlen(p->mailbox); 11502 11503 if (!ast_strlen_zero(p->context)) 11504 len += strlen(p->context) + 1; /* Allow for seperator */ 11505 11506 if (!(mwi_sub = ast_calloc(1, len))) 11507 return -1; 11508 11509 mwi_sub->uniqueid = p->uniqueid; 11510 if (!ast_strlen_zero(p->mailbox)) 11511 strcpy(mwi_sub->mailbox, p->mailbox); 11512 11513 if (!ast_strlen_zero(p->context)) { 11514 strcat(mwi_sub->mailbox, "@"); 11515 strcat(mwi_sub->mailbox, p->context); 11516 } 11517 11518 AST_RWLIST_WRLOCK(&mwi_subs); 11519 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11520 AST_RWLIST_UNLOCK(&mwi_subs); 11521 ast_free((void *) p->mailbox); 11522 ast_free((void *) p->context); 11523 ast_free(p); 11524 poll_subscribed_mailbox(mwi_sub); 11525 return 0; 11526 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11471 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().
11472 { 11473 struct mwi_sub *mwi_sub; 11474 uint32_t *uniqueid = datap; 11475 11476 AST_RWLIST_WRLOCK(&mwi_subs); 11477 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11478 if (mwi_sub->uniqueid == *uniqueid) { 11479 AST_LIST_REMOVE_CURRENT(entry); 11480 break; 11481 } 11482 } 11483 AST_RWLIST_TRAVERSE_SAFE_END 11484 AST_RWLIST_UNLOCK(&mwi_subs); 11485 11486 if (mwi_sub) 11487 mwi_sub_destroy(mwi_sub); 11488 11489 ast_free(uniqueid); 11490 return 0; 11491 }
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 11248 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.
11249 { 11250 switch (cmd) { 11251 case CLI_INIT: 11252 e->command = "voicemail reload"; 11253 e->usage = 11254 "Usage: voicemail reload\n" 11255 " Reload voicemail configuration\n"; 11256 return NULL; 11257 case CLI_GENERATE: 11258 return NULL; 11259 } 11260 11261 if (a->argc != 2) 11262 return CLI_SHOWUSAGE; 11263 11264 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11265 load_config(1); 11266 11267 return CLI_SUCCESS; 11268 }
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 11136 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.
11137 { 11138 struct ast_vm_user *vmu; 11139 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11140 const char *context = NULL; 11141 int users_counter = 0; 11142 11143 switch (cmd) { 11144 case CLI_INIT: 11145 e->command = "voicemail show users"; 11146 e->usage = 11147 "Usage: voicemail show users [for <context>]\n" 11148 " Lists all mailboxes currently set up\n"; 11149 return NULL; 11150 case CLI_GENERATE: 11151 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11152 } 11153 11154 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11155 return CLI_SHOWUSAGE; 11156 if (a->argc == 5) { 11157 if (strcmp(a->argv[3],"for")) 11158 return CLI_SHOWUSAGE; 11159 context = a->argv[4]; 11160 } 11161 11162 if (ast_check_realtime("voicemail")) { 11163 if (!context) { 11164 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11165 return CLI_SHOWUSAGE; 11166 } 11167 return show_users_realtime(a->fd, context); 11168 } 11169 11170 AST_LIST_LOCK(&users); 11171 if (AST_LIST_EMPTY(&users)) { 11172 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11173 AST_LIST_UNLOCK(&users); 11174 return CLI_FAILURE; 11175 } 11176 if (!context) { 11177 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11178 } else { 11179 int count = 0; 11180 AST_LIST_TRAVERSE(&users, vmu, list) { 11181 if (!strcmp(context, vmu->context)) { 11182 count++; 11183 break; 11184 } 11185 } 11186 if (count) { 11187 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11188 } else { 11189 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11190 AST_LIST_UNLOCK(&users); 11191 return CLI_FAILURE; 11192 } 11193 } 11194 AST_LIST_TRAVERSE(&users, vmu, list) { 11195 int newmsgs = 0, oldmsgs = 0; 11196 char count[12], tmp[256] = ""; 11197 11198 if (!context || !strcmp(context, vmu->context)) { 11199 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11200 inboxcount(tmp, &newmsgs, &oldmsgs); 11201 snprintf(count, sizeof(count), "%d", newmsgs); 11202 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11203 users_counter++; 11204 } 11205 } 11206 AST_LIST_UNLOCK(&users); 11207 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11208 return CLI_SUCCESS; 11209 }
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 11212 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.
11213 { 11214 struct vm_zone *zone; 11215 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11216 char *res = CLI_SUCCESS; 11217 11218 switch (cmd) { 11219 case CLI_INIT: 11220 e->command = "voicemail show zones"; 11221 e->usage = 11222 "Usage: voicemail show zones\n" 11223 " Lists zone message formats\n"; 11224 return NULL; 11225 case CLI_GENERATE: 11226 return NULL; 11227 } 11228 11229 if (a->argc != 3) 11230 return CLI_SHOWUSAGE; 11231 11232 AST_LIST_LOCK(&zones); 11233 if (!AST_LIST_EMPTY(&zones)) { 11234 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11235 AST_LIST_TRAVERSE(&zones, zone, list) { 11236 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11237 } 11238 } else { 11239 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11240 res = CLI_FAILURE; 11241 } 11242 AST_LIST_UNLOCK(&zones); 11243 11244 return res; 11245 }
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 11791 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().
11792 { 11793 struct ast_config *cfg, *ucfg; 11794 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11795 int res; 11796 11797 ast_unload_realtime("voicemail"); 11798 ast_unload_realtime("voicemail_data"); 11799 11800 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11801 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11802 return 0; 11803 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11804 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11805 ucfg = NULL; 11806 } 11807 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11808 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11809 ast_config_destroy(ucfg); 11810 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11811 return 0; 11812 } 11813 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11814 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11815 return 0; 11816 } else { 11817 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11818 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11819 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11820 ucfg = NULL; 11821 } 11822 } 11823 11824 res = actual_load_config(reload, cfg, ucfg); 11825 11826 ast_config_destroy(cfg); 11827 ast_config_destroy(ucfg); 11828 11829 return res; 11830 }
static int load_module | ( | void | ) | [static] |
Definition at line 13092 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().
13093 { 13094 int res; 13095 my_umask = umask(0); 13096 umask(my_umask); 13097 13098 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13099 return AST_MODULE_LOAD_DECLINE; 13100 } 13101 13102 /* compute the location of the voicemail spool directory */ 13103 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13104 13105 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13106 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13107 } 13108 13109 if ((res = load_config(0))) 13110 return res; 13111 13112 res = ast_register_application_xml(app, vm_exec); 13113 res |= ast_register_application_xml(app2, vm_execmain); 13114 res |= ast_register_application_xml(app3, vm_box_exists); 13115 res |= ast_register_application_xml(app4, vmauthenticate); 13116 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13117 res |= ast_custom_function_register(&mailbox_exists_acf); 13118 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13119 #ifdef TEST_FRAMEWORK 13120 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13121 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13122 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13123 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13124 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13125 #endif 13126 13127 if (res) 13128 return res; 13129 13130 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13131 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13132 13133 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13134 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13135 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13136 13137 return res; 13138 }
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 11622 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().
11623 { 11624 struct ast_vm_user *vmu = NULL; 11625 const char *id = astman_get_header(m, "ActionID"); 11626 char actionid[128] = ""; 11627 11628 if (!ast_strlen_zero(id)) 11629 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11630 11631 AST_LIST_LOCK(&users); 11632 11633 if (AST_LIST_EMPTY(&users)) { 11634 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11635 AST_LIST_UNLOCK(&users); 11636 return RESULT_SUCCESS; 11637 } 11638 11639 astman_send_ack(s, m, "Voicemail user list will follow"); 11640 11641 AST_LIST_TRAVERSE(&users, vmu, list) { 11642 char dirname[256]; 11643 11644 #ifdef IMAP_STORAGE 11645 int new, old; 11646 inboxcount(vmu->mailbox, &new, &old); 11647 #endif 11648 11649 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11650 astman_append(s, 11651 "%s" 11652 "Event: VoicemailUserEntry\r\n" 11653 "VMContext: %s\r\n" 11654 "VoiceMailbox: %s\r\n" 11655 "Fullname: %s\r\n" 11656 "Email: %s\r\n" 11657 "Pager: %s\r\n" 11658 "ServerEmail: %s\r\n" 11659 "MailCommand: %s\r\n" 11660 "Language: %s\r\n" 11661 "TimeZone: %s\r\n" 11662 "Callback: %s\r\n" 11663 "Dialout: %s\r\n" 11664 "UniqueID: %s\r\n" 11665 "ExitContext: %s\r\n" 11666 "SayDurationMinimum: %d\r\n" 11667 "SayEnvelope: %s\r\n" 11668 "SayCID: %s\r\n" 11669 "AttachMessage: %s\r\n" 11670 "AttachmentFormat: %s\r\n" 11671 "DeleteMessage: %s\r\n" 11672 "VolumeGain: %.2f\r\n" 11673 "CanReview: %s\r\n" 11674 "CallOperator: %s\r\n" 11675 "MaxMessageCount: %d\r\n" 11676 "MaxMessageLength: %d\r\n" 11677 "NewMessageCount: %d\r\n" 11678 #ifdef IMAP_STORAGE 11679 "OldMessageCount: %d\r\n" 11680 "IMAPUser: %s\r\n" 11681 #endif 11682 "\r\n", 11683 actionid, 11684 vmu->context, 11685 vmu->mailbox, 11686 vmu->fullname, 11687 vmu->email, 11688 vmu->pager, 11689 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11690 mailcmd, 11691 vmu->language, 11692 vmu->zonetag, 11693 vmu->callback, 11694 vmu->dialout, 11695 vmu->uniqueid, 11696 vmu->exit, 11697 vmu->saydurationm, 11698 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11699 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11700 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11701 vmu->attachfmt, 11702 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11703 vmu->volgain, 11704 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11705 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11706 vmu->maxmsg, 11707 vmu->maxsecs, 11708 #ifdef IMAP_STORAGE 11709 new, old, vmu->imapuser 11710 #else 11711 count_messages(vmu, dirname) 11712 #endif 11713 ); 11714 } 11715 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11716 11717 AST_LIST_UNLOCK(&users); 11718 11719 return RESULT_SUCCESS; 11720 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11443 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().
11444 { 11445 while (poll_thread_run) { 11446 struct timespec ts = { 0, }; 11447 struct timeval wait; 11448 11449 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11450 ts.tv_sec = wait.tv_sec; 11451 ts.tv_nsec = wait.tv_usec * 1000; 11452 11453 ast_mutex_lock(&poll_lock); 11454 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11455 ast_mutex_unlock(&poll_lock); 11456 11457 if (!poll_thread_run) 11458 break; 11459 11460 poll_subscribed_mailboxes(); 11461 } 11462 11463 return NULL; 11464 }
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 11466 of file app_voicemail_imapstorage.c.
References ast_free.
Referenced by handle_unsubscribe().
11467 { 11468 ast_free(mwi_sub); 11469 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11554 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().
11555 { 11556 struct mwi_sub_task *mwist; 11557 11558 if (ast_event_get_type(event) != AST_EVENT_SUB) 11559 return; 11560 11561 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11562 return; 11563 11564 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11565 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11566 return; 11567 } 11568 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11569 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11570 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11571 11572 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11573 ast_free(mwist); 11574 } 11575 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11528 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().
11529 { 11530 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11531 11532 if (!uniqueid) { 11533 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11534 return; 11535 } 11536 11537 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11538 ast_free(uniqueid); 11539 return; 11540 } 11541 11542 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11543 ast_free(uniqueid); 11544 return; 11545 } 11546 11547 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11548 *uniqueid = u; 11549 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11550 ast_free(uniqueid); 11551 } 11552 }
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_he(), vm_browse_messages_latin(), 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 13405 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().
13408 { 13409 /* Record message & let caller review or re-record it, or set options if applicable */ 13410 int res = 0; 13411 int cmd = 0; 13412 int max_attempts = 3; 13413 int attempts = 0; 13414 int recorded = 0; 13415 int msg_exists = 0; 13416 signed char zero_gain = 0; 13417 char tempfile[PATH_MAX]; 13418 char *acceptdtmf = "#"; 13419 char *canceldtmf = ""; 13420 int canceleddtmf = 0; 13421 13422 /* Note that urgent and private are for flagging messages as such in the future */ 13423 13424 /* barf if no pointer passed to store duration in */ 13425 if (duration == NULL) { 13426 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13427 return -1; 13428 } 13429 13430 if (!outsidecaller) 13431 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13432 else 13433 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13434 13435 cmd = '3'; /* Want to start by recording */ 13436 13437 while ((cmd >= 0) && (cmd != 't')) { 13438 switch (cmd) { 13439 case '1': 13440 if (!msg_exists) { 13441 /* In this case, 1 is to record a message */ 13442 cmd = '3'; 13443 break; 13444 } else { 13445 /* Otherwise 1 is to save the existing message */ 13446 ast_verb(3, "Saving message as is\n"); 13447 if (!outsidecaller) 13448 ast_filerename(tempfile, recordfile, NULL); 13449 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13450 if (!outsidecaller) { 13451 /* Saves to IMAP server only if imapgreeting=yes */ 13452 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13453 DISPOSE(recordfile, -1); 13454 } 13455 cmd = 't'; 13456 return res; 13457 } 13458 case '2': 13459 /* Review */ 13460 ast_verb(3, "Reviewing the message\n"); 13461 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13462 break; 13463 case '3': 13464 msg_exists = 0; 13465 /* Record */ 13466 if (recorded == 1) 13467 ast_verb(3, "Re-recording the message\n"); 13468 else 13469 ast_verb(3, "Recording the message\n"); 13470 13471 if (recorded && outsidecaller) { 13472 cmd = ast_play_and_wait(chan, INTRO); 13473 cmd = ast_play_and_wait(chan, "beep"); 13474 } 13475 recorded = 1; 13476 /* 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 */ 13477 if (record_gain) 13478 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13479 if (ast_test_flag(vmu, VM_OPERATOR)) 13480 canceldtmf = "0"; 13481 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13482 if (strchr(canceldtmf, cmd)) { 13483 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13484 canceleddtmf = 1; 13485 } 13486 if (record_gain) 13487 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13488 if (cmd == -1) { 13489 /* User has hung up, no options to give */ 13490 if (!outsidecaller) { 13491 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13492 ast_filedelete(tempfile, NULL); 13493 } 13494 return cmd; 13495 } 13496 if (cmd == '0') { 13497 break; 13498 } else if (cmd == '*') { 13499 break; 13500 #if 0 13501 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13502 /* Message is too short */ 13503 ast_verb(3, "Message too short\n"); 13504 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13505 cmd = ast_filedelete(tempfile, NULL); 13506 break; 13507 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13508 /* Message is all silence */ 13509 ast_verb(3, "Nothing recorded\n"); 13510 cmd = ast_filedelete(tempfile, NULL); 13511 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13512 if (!cmd) 13513 cmd = ast_play_and_wait(chan, "vm-speakup"); 13514 break; 13515 #endif 13516 } else { 13517 /* If all is well, a message exists */ 13518 msg_exists = 1; 13519 cmd = 0; 13520 } 13521 break; 13522 case '4': 13523 if (outsidecaller) { /* only mark vm messages */ 13524 /* Mark Urgent */ 13525 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13526 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13527 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13528 strcpy(flag, "Urgent"); 13529 } else if (flag) { 13530 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13531 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13532 strcpy(flag, ""); 13533 } else { 13534 ast_play_and_wait(chan, "vm-sorry"); 13535 } 13536 cmd = 0; 13537 } else { 13538 cmd = ast_play_and_wait(chan, "vm-sorry"); 13539 } 13540 break; 13541 case '5': 13542 case '6': 13543 case '7': 13544 case '8': 13545 case '9': 13546 case '*': 13547 case '#': 13548 cmd = ast_play_and_wait(chan, "vm-sorry"); 13549 break; 13550 #if 0 13551 /* XXX Commented out for the moment because of the dangers of deleting 13552 a message while recording (can put the message numbers out of sync) */ 13553 case '*': 13554 /* Cancel recording, delete message, offer to take another message*/ 13555 cmd = ast_play_and_wait(chan, "vm-deleted"); 13556 cmd = ast_filedelete(tempfile, NULL); 13557 if (outsidecaller) { 13558 res = vm_exec(chan, NULL); 13559 return res; 13560 } 13561 else 13562 return 1; 13563 #endif 13564 case '0': 13565 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13566 cmd = ast_play_and_wait(chan, "vm-sorry"); 13567 break; 13568 } 13569 if (msg_exists || recorded) { 13570 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13571 if (!cmd) 13572 cmd = ast_waitfordigit(chan, 3000); 13573 if (cmd == '1') { 13574 ast_filerename(tempfile, recordfile, NULL); 13575 ast_play_and_wait(chan, "vm-msgsaved"); 13576 cmd = '0'; 13577 } else if (cmd == '4') { 13578 if (flag) { 13579 ast_play_and_wait(chan, "vm-marked-urgent"); 13580 strcpy(flag, "Urgent"); 13581 } 13582 ast_play_and_wait(chan, "vm-msgsaved"); 13583 cmd = '0'; 13584 } else { 13585 ast_play_and_wait(chan, "vm-deleted"); 13586 DELETE(tempfile, -1, tempfile, vmu); 13587 cmd = '0'; 13588 } 13589 } 13590 return cmd; 13591 default: 13592 /* If the caller is an ouside caller, and the review option is enabled, 13593 allow them to review the message, but let the owner of the box review 13594 their OGM's */ 13595 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13596 return cmd; 13597 if (msg_exists) { 13598 cmd = ast_play_and_wait(chan, "vm-review"); 13599 if (!cmd && outsidecaller) { 13600 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13601 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13602 } else if (flag) { 13603 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13604 } 13605 } 13606 } else { 13607 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13608 if (!cmd) 13609 cmd = ast_waitfordigit(chan, 600); 13610 } 13611 13612 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13613 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13614 if (!cmd) 13615 cmd = ast_waitfordigit(chan, 600); 13616 } 13617 #if 0 13618 if (!cmd) 13619 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13620 #endif 13621 if (!cmd) 13622 cmd = ast_waitfordigit(chan, 6000); 13623 if (!cmd) { 13624 attempts++; 13625 } 13626 if (attempts > max_attempts) { 13627 cmd = 't'; 13628 } 13629 } 13630 } 13631 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13632 /* Hang up or timeout, so delete the recording. */ 13633 ast_filedelete(tempfile, NULL); 13634 } 13635 13636 if (cmd != 't' && outsidecaller) 13637 ast_play_and_wait(chan, "vm-goodbye"); 13638 13639 return cmd; 13640 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11415 of file app_voicemail_imapstorage.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11416 { 11417 int new = 0, old = 0, urgent = 0; 11418 11419 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11420 11421 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11422 mwi_sub->old_urgent = urgent; 11423 mwi_sub->old_new = new; 11424 mwi_sub->old_old = old; 11425 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11426 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11427 } 11428 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11430 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().
11431 { 11432 struct mwi_sub *mwi_sub; 11433 11434 AST_RWLIST_RDLOCK(&mwi_subs); 11435 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11436 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11437 poll_subscribed_mailbox(mwi_sub); 11438 } 11439 } 11440 AST_RWLIST_UNLOCK(&mwi_subs); 11441 }
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 12521 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().
12521 { 12522 struct ast_config *pwconf; 12523 struct ast_flags config_flags = { 0 }; 12524 12525 pwconf = ast_config_load(secretfn, config_flags); 12526 if (valid_config(pwconf)) { 12527 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12528 if (val) { 12529 ast_copy_string(password, val, passwordlen); 12530 ast_config_destroy(pwconf); 12531 return; 12532 } 12533 ast_config_destroy(pwconf); 12534 } 12535 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12536 }
static int reload | ( | void | ) | [static] |
Definition at line 13052 of file app_voicemail_imapstorage.c.
References load_config().
13053 { 13054 return load_config(1); 13055 }
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 12507 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().
12508 { 12509 int res = -1; 12510 char dir[PATH_MAX]; 12511 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12512 ast_debug(2, "About to try retrieving name file %s\n", dir); 12513 RETRIEVE(dir, -1, mailbox, context); 12514 if (ast_fileexists(dir, NULL, NULL)) { 12515 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12516 } 12517 DISPOSE(dir, -1); 12518 return res; 12519 }
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 11072 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().
11073 { 11074 struct ast_config *cfg; 11075 const char *cat = NULL; 11076 11077 if (!(cfg = ast_load_realtime_multientry("voicemail", 11078 "context", context, SENTINEL))) { 11079 return CLI_FAILURE; 11080 } 11081 11082 ast_cli(fd, 11083 "\n" 11084 "=============================================================\n" 11085 "=== Configured Voicemail Users ==============================\n" 11086 "=============================================================\n" 11087 "===\n"); 11088 11089 while ((cat = ast_category_browse(cfg, cat))) { 11090 struct ast_variable *var = NULL; 11091 ast_cli(fd, 11092 "=== Mailbox ...\n" 11093 "===\n"); 11094 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11095 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11096 ast_cli(fd, 11097 "===\n" 11098 "=== ---------------------------------------------------------\n" 11099 "===\n"); 11100 } 11101 11102 ast_cli(fd, 11103 "=============================================================\n" 11104 "\n"); 11105 11106 ast_config_destroy(cfg); 11107 11108 return CLI_SUCCESS; 11109 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11577 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().
11578 { 11579 int errcode; 11580 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11581 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11582 AST_EVENT_IE_END); 11583 11584 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11585 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11586 AST_EVENT_IE_END); 11587 11588 if (mwi_sub_sub) 11589 ast_event_report_subs(mwi_sub_sub); 11590 11591 poll_thread_run = 1; 11592 11593 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11594 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11595 } 11596 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11598 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().
11599 { 11600 poll_thread_run = 0; 11601 11602 if (mwi_sub_sub) { 11603 ast_event_unsubscribe(mwi_sub_sub); 11604 mwi_sub_sub = NULL; 11605 } 11606 11607 if (mwi_unsub_sub) { 11608 ast_event_unsubscribe(mwi_unsub_sub); 11609 mwi_unsub_sub = NULL; 11610 } 11611 11612 ast_mutex_lock(&poll_lock); 11613 ast_cond_signal(&poll_cond); 11614 ast_mutex_unlock(&poll_lock); 11615 11616 pthread_join(poll_thread, NULL); 11617 11618 poll_thread = AST_PTHREADT_NULL; 11619 }
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 11744 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().
11745 { 11746 char *current; 11747 11748 /* Add 16 for fudge factor */ 11749 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11750 11751 ast_str_reset(str); 11752 11753 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11754 for (current = (char *) value; *current; current++) { 11755 if (*current == '\\') { 11756 current++; 11757 if (!*current) { 11758 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11759 break; 11760 } 11761 switch (*current) { 11762 case '\\': 11763 ast_str_append(&str, 0, "\\"); 11764 break; 11765 case 'r': 11766 ast_str_append(&str, 0, "\r"); 11767 break; 11768 case 'n': 11769 #ifdef IMAP_STORAGE 11770 if (!str->used || str->str[str->used - 1] != '\r') { 11771 ast_str_append(&str, 0, "\r"); 11772 } 11773 #endif 11774 ast_str_append(&str, 0, "\n"); 11775 break; 11776 case 't': 11777 ast_str_append(&str, 0, "\t"); 11778 break; 11779 default: 11780 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11781 break; 11782 } 11783 } else { 11784 ast_str_append(&str, 0, "%c", *current); 11785 } 11786 } 11787 11788 return ast_str_buffer(str); 11789 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13057 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().
13058 { 13059 int res; 13060 13061 res = ast_unregister_application(app); 13062 res |= ast_unregister_application(app2); 13063 res |= ast_unregister_application(app3); 13064 res |= ast_unregister_application(app4); 13065 res |= ast_unregister_application(sayname_app); 13066 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13067 res |= ast_manager_unregister("VoicemailUsersList"); 13068 res |= ast_data_unregister(NULL); 13069 #ifdef TEST_FRAMEWORK 13070 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13071 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13072 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13073 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13074 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13075 #endif 13076 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13077 ast_uninstall_vm_functions(); 13078 ao2_ref(inprocess_container, -1); 13079 13080 if (poll_thread != AST_PTHREADT_NULL) 13081 stop_poll_thread(); 13082 13083 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13084 ast_unload_realtime("voicemail"); 13085 ast_unload_realtime("voicemail_data"); 13086 13087 free_vm_users(); 13088 free_vm_zones(); 13089 return res; 13090 }
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 9752 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().
09755 { 09756 int useadsi = 0, valid = 0, logretries = 0; 09757 char password[AST_MAX_EXTENSION]="", *passptr; 09758 struct ast_vm_user vmus, *vmu = NULL; 09759 09760 /* If ADSI is supported, setup login screen */ 09761 adsi_begin(chan, &useadsi); 09762 if (!skipuser && useadsi) 09763 adsi_login(chan); 09764 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09765 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09766 return -1; 09767 } 09768 09769 /* Authenticate them and get their mailbox/password */ 09770 09771 while (!valid && (logretries < max_logins)) { 09772 /* Prompt for, and read in the username */ 09773 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09774 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09775 return -1; 09776 } 09777 if (ast_strlen_zero(mailbox)) { 09778 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09779 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09780 } else { 09781 ast_verb(3, "Username not entered\n"); 09782 return -1; 09783 } 09784 } else if (mailbox[0] == '*') { 09785 /* user entered '*' */ 09786 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09787 if (ast_exists_extension(chan, chan->context, "a", 1, 09788 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09789 return -1; 09790 } 09791 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09792 mailbox[0] = '\0'; 09793 } 09794 09795 if (useadsi) 09796 adsi_password(chan); 09797 09798 if (!ast_strlen_zero(prefix)) { 09799 char fullusername[80] = ""; 09800 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09801 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09802 ast_copy_string(mailbox, fullusername, mailbox_size); 09803 } 09804 09805 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09806 vmu = find_user(&vmus, context, mailbox); 09807 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09808 /* saved password is blank, so don't bother asking */ 09809 password[0] = '\0'; 09810 } else { 09811 if (ast_streamfile(chan, vm_password, chan->language)) { 09812 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09813 return -1; 09814 } 09815 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09816 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09817 return -1; 09818 } else if (password[0] == '*') { 09819 /* user entered '*' */ 09820 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09821 if (ast_exists_extension(chan, chan->context, "a", 1, 09822 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09823 mailbox[0] = '*'; 09824 return -1; 09825 } 09826 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09827 mailbox[0] = '\0'; 09828 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09829 vmu = NULL; 09830 } 09831 } 09832 09833 if (vmu) { 09834 passptr = vmu->password; 09835 if (passptr[0] == '-') passptr++; 09836 } 09837 if (vmu && !strcmp(passptr, password)) 09838 valid++; 09839 else { 09840 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09841 if (!ast_strlen_zero(prefix)) 09842 mailbox[0] = '\0'; 09843 } 09844 logretries++; 09845 if (!valid) { 09846 if (skipuser || logretries >= max_logins) { 09847 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09848 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09849 return -1; 09850 } 09851 } else { 09852 if (useadsi) 09853 adsi_login(chan); 09854 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09855 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09856 return -1; 09857 } 09858 } 09859 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09860 return -1; 09861 } 09862 } 09863 if (!valid && (logretries >= max_logins)) { 09864 ast_stopstream(chan); 09865 ast_play_and_wait(chan, "vm-goodbye"); 09866 return -1; 09867 } 09868 if (vmu && !skipuser) { 09869 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09870 } 09871 return 0; 09872 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10967 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().
10968 { 10969 struct ast_vm_user svm; 10970 char *context, *box; 10971 AST_DECLARE_APP_ARGS(args, 10972 AST_APP_ARG(mbox); 10973 AST_APP_ARG(options); 10974 ); 10975 static int dep_warning = 0; 10976 10977 if (ast_strlen_zero(data)) { 10978 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10979 return -1; 10980 } 10981 10982 if (!dep_warning) { 10983 dep_warning = 1; 10984 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10985 } 10986 10987 box = ast_strdupa(data); 10988 10989 AST_STANDARD_APP_ARGS(args, box); 10990 10991 if (args.options) { 10992 } 10993 10994 if ((context = strchr(args.mbox, '@'))) { 10995 *context = '\0'; 10996 context++; 10997 } 10998 10999 if (find_user(&svm, context, args.mbox)) { 11000 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11001 } else 11002 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11003 11004 return 0; 11005 }
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 9734 of file app_voicemail_imapstorage.c.
References vm_browse_messages_en(), vm_browse_messages_he(), vm_browse_messages_latin(), vm_browse_messages_vi(), and vm_browse_messages_zh().
Referenced by vm_execmain().
09735 { 09736 if (!strncasecmp(chan->language, "es", 2) || 09737 !strncasecmp(chan->language, "it", 2) || 09738 !strncasecmp(chan->language, "pt", 2) || 09739 !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */ 09740 return vm_browse_messages_latin(chan, vms, vmu); 09741 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09742 return vm_browse_messages_he(chan, vms, vmu); 09743 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09744 return vm_browse_messages_vi(chan, vms, vmu); 09745 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09746 return vm_browse_messages_zh(chan, vms, vmu); 09747 } else { /* Default to English syntax */ 09748 return vm_browse_messages_en(chan, vms, vmu); 09749 } 09750 }
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 9615 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().
09616 { 09617 int cmd = 0; 09618 09619 if (vms->lastmsg > -1) { 09620 cmd = play_message(chan, vmu, vms); 09621 } else { 09622 cmd = ast_play_and_wait(chan, "vm-youhave"); 09623 if (!cmd) 09624 cmd = ast_play_and_wait(chan, "vm-no"); 09625 if (!cmd) { 09626 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09627 cmd = ast_play_and_wait(chan, vms->fn); 09628 } 09629 if (!cmd) 09630 cmd = ast_play_and_wait(chan, "vm-messages"); 09631 } 09632 return cmd; 09633 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9591 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().
09592 { 09593 int cmd = 0; 09594 09595 if (vms->lastmsg > -1) { 09596 cmd = play_message(chan, vmu, vms); 09597 } else { 09598 if (!strcasecmp(vms->fn, "INBOX")) { 09599 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09600 } else { 09601 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09602 } 09603 } 09604 return cmd; 09605 }
static int vm_browse_messages_latin | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Common LATIN languages syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9644 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().
09645 { 09646 int cmd; 09647 09648 if (vms->lastmsg > -1) { 09649 cmd = play_message(chan, vmu, vms); 09650 } else { 09651 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09652 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09653 if (!cmd) { 09654 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09655 cmd = ast_play_and_wait(chan, vms->fn); 09656 } 09657 if (!cmd) 09658 cmd = ast_play_and_wait(chan, "vm-messages"); 09659 } else { 09660 if (!cmd) 09661 cmd = ast_play_and_wait(chan, "vm-messages"); 09662 if (!cmd) { 09663 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09664 cmd = ast_play_and_wait(chan, vms->fn); 09665 } 09666 } 09667 } 09668 return cmd; 09669 }
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 9707 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().
09708 { 09709 int cmd = 0; 09710 09711 if (vms->lastmsg > -1) { 09712 cmd = play_message(chan, vmu, vms); 09713 } else { 09714 cmd = ast_play_and_wait(chan, "vm-no"); 09715 if (!cmd) { 09716 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09717 cmd = ast_play_and_wait(chan, vms->fn); 09718 } 09719 } 09720 return cmd; 09721 }
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 9679 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().
09680 { 09681 int cmd; 09682 09683 if (vms->lastmsg > -1) { 09684 cmd = play_message(chan, vmu, vms); 09685 } else { 09686 cmd = ast_play_and_wait(chan, "vm-you"); 09687 if (!cmd) 09688 cmd = ast_play_and_wait(chan, "vm-haveno"); 09689 if (!cmd) 09690 cmd = ast_play_and_wait(chan, "vm-messages"); 09691 if (!cmd) { 09692 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09693 cmd = ast_play_and_wait(chan, vms->fn); 09694 } 09695 } 09696 return cmd; 09697 }
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 10626 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().
10627 { 10628 int res = 0; 10629 char *tmp; 10630 struct leave_vm_options leave_options; 10631 struct ast_flags flags = { 0 }; 10632 char *opts[OPT_ARG_ARRAY_SIZE]; 10633 AST_DECLARE_APP_ARGS(args, 10634 AST_APP_ARG(argv0); 10635 AST_APP_ARG(argv1); 10636 ); 10637 10638 memset(&leave_options, 0, sizeof(leave_options)); 10639 10640 if (chan->_state != AST_STATE_UP) 10641 ast_answer(chan); 10642 10643 if (!ast_strlen_zero(data)) { 10644 tmp = ast_strdupa(data); 10645 AST_STANDARD_APP_ARGS(args, tmp); 10646 if (args.argc == 2) { 10647 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10648 return -1; 10649 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10650 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10651 int gain; 10652 10653 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10654 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10655 return -1; 10656 } else { 10657 leave_options.record_gain = (signed char) gain; 10658 } 10659 } 10660 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10661 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10662 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10663 } 10664 } 10665 } else { 10666 char temp[256]; 10667 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10668 if (res < 0) 10669 return res; 10670 if (ast_strlen_zero(temp)) 10671 return 0; 10672 args.argv0 = ast_strdupa(temp); 10673 } 10674 10675 res = leave_voicemail(chan, args.argv0, &leave_options); 10676 if (res == 't') { 10677 ast_play_and_wait(chan, "vm-goodbye"); 10678 res = 0; 10679 } 10680 10681 if (res == OPERATOR_EXIT) { 10682 res = 0; 10683 } 10684 10685 if (res == ERROR_LOCK_PATH) { 10686 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10687 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10688 res = 0; 10689 } 10690 10691 return res; 10692 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9874 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().
09875 { 09876 /* XXX This is, admittedly, some pretty horrendous code. For some 09877 reason it just seemed a lot easier to do with GOTO's. I feel 09878 like I'm back in my GWBASIC days. XXX */ 09879 int res = -1; 09880 int cmd = 0; 09881 int valid = 0; 09882 char prefixstr[80] =""; 09883 char ext_context[256]=""; 09884 int box; 09885 int useadsi = 0; 09886 int skipuser = 0; 09887 struct vm_state vms; 09888 struct ast_vm_user *vmu = NULL, vmus; 09889 char *context = NULL; 09890 int silentexit = 0; 09891 struct ast_flags flags = { 0 }; 09892 signed char record_gain = 0; 09893 int play_auto = 0; 09894 int play_folder = 0; 09895 int in_urgent = 0; 09896 #ifdef IMAP_STORAGE 09897 int deleted = 0; 09898 #endif 09899 09900 /* Add the vm_state to the active list and keep it active */ 09901 memset(&vms, 0, sizeof(vms)); 09902 09903 vms.lastmsg = -1; 09904 09905 memset(&vmus, 0, sizeof(vmus)); 09906 09907 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09908 if (chan->_state != AST_STATE_UP) { 09909 ast_debug(1, "Before ast_answer\n"); 09910 ast_answer(chan); 09911 } 09912 09913 if (!ast_strlen_zero(data)) { 09914 char *opts[OPT_ARG_ARRAY_SIZE]; 09915 char *parse; 09916 AST_DECLARE_APP_ARGS(args, 09917 AST_APP_ARG(argv0); 09918 AST_APP_ARG(argv1); 09919 ); 09920 09921 parse = ast_strdupa(data); 09922 09923 AST_STANDARD_APP_ARGS(args, parse); 09924 09925 if (args.argc == 2) { 09926 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09927 return -1; 09928 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09929 int gain; 09930 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09931 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09932 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09933 return -1; 09934 } else { 09935 record_gain = (signed char) gain; 09936 } 09937 } else { 09938 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09939 } 09940 } 09941 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09942 play_auto = 1; 09943 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09944 /* See if it is a folder name first */ 09945 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09946 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09947 play_folder = -1; 09948 } 09949 } else { 09950 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09951 } 09952 } else { 09953 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09954 } 09955 if (play_folder > 9 || play_folder < 0) { 09956 ast_log(AST_LOG_WARNING, 09957 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09958 opts[OPT_ARG_PLAYFOLDER]); 09959 play_folder = 0; 09960 } 09961 } 09962 } else { 09963 /* old style options parsing */ 09964 while (*(args.argv0)) { 09965 if (*(args.argv0) == 's') 09966 ast_set_flag(&flags, OPT_SILENT); 09967 else if (*(args.argv0) == 'p') 09968 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09969 else 09970 break; 09971 (args.argv0)++; 09972 } 09973 09974 } 09975 09976 valid = ast_test_flag(&flags, OPT_SILENT); 09977 09978 if ((context = strchr(args.argv0, '@'))) 09979 *context++ = '\0'; 09980 09981 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09982 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09983 else 09984 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09985 09986 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09987 skipuser++; 09988 else 09989 valid = 0; 09990 } 09991 09992 if (!valid) 09993 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09994 09995 ast_debug(1, "After vm_authenticate\n"); 09996 09997 if (vms.username[0] == '*') { 09998 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09999 10000 /* user entered '*' */ 10001 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10002 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10003 res = 0; /* prevent hangup */ 10004 goto out; 10005 } 10006 } 10007 10008 if (!res) { 10009 valid = 1; 10010 if (!skipuser) 10011 vmu = &vmus; 10012 } else { 10013 res = 0; 10014 } 10015 10016 /* If ADSI is supported, setup login screen */ 10017 adsi_begin(chan, &useadsi); 10018 10019 ast_test_suite_assert(valid); 10020 if (!valid) { 10021 goto out; 10022 } 10023 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10024 10025 #ifdef IMAP_STORAGE 10026 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10027 pthread_setspecific(ts_vmstate.key, &vms); 10028 10029 vms.interactive = 1; 10030 vms.updated = 1; 10031 if (vmu) 10032 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10033 vmstate_insert(&vms); 10034 init_vm_state(&vms); 10035 #endif 10036 10037 /* Set language from config to override channel language */ 10038 if (!ast_strlen_zero(vmu->language)) 10039 ast_string_field_set(chan, language, vmu->language); 10040 10041 /* Retrieve urgent, old and new message counts */ 10042 ast_debug(1, "Before open_mailbox\n"); 10043 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10044 if (res < 0) 10045 goto out; 10046 vms.oldmessages = vms.lastmsg + 1; 10047 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10048 /* check INBOX */ 10049 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10050 if (res < 0) 10051 goto out; 10052 vms.newmessages = vms.lastmsg + 1; 10053 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10054 /* Start in Urgent */ 10055 in_urgent = 1; 10056 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10057 if (res < 0) 10058 goto out; 10059 vms.urgentmessages = vms.lastmsg + 1; 10060 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10061 10062 /* Select proper mailbox FIRST!! */ 10063 if (play_auto) { 10064 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10065 if (vms.urgentmessages) { 10066 in_urgent = 1; 10067 res = open_mailbox(&vms, vmu, 11); 10068 } else { 10069 in_urgent = 0; 10070 res = open_mailbox(&vms, vmu, play_folder); 10071 } 10072 if (res < 0) 10073 goto out; 10074 10075 /* If there are no new messages, inform the user and hangup */ 10076 if (vms.lastmsg == -1) { 10077 in_urgent = 0; 10078 cmd = vm_browse_messages(chan, &vms, vmu); 10079 res = 0; 10080 goto out; 10081 } 10082 } else { 10083 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10084 /* If we only have old messages start here */ 10085 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10086 in_urgent = 0; 10087 play_folder = 1; 10088 if (res < 0) 10089 goto out; 10090 } else if (!vms.urgentmessages && vms.newmessages) { 10091 /* If we have new messages but none are urgent */ 10092 in_urgent = 0; 10093 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10094 if (res < 0) 10095 goto out; 10096 } 10097 } 10098 10099 if (useadsi) 10100 adsi_status(chan, &vms); 10101 res = 0; 10102 10103 /* Check to see if this is a new user */ 10104 if (!strcasecmp(vmu->mailbox, vmu->password) && 10105 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10106 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10107 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10108 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10109 if ((cmd == 't') || (cmd == '#')) { 10110 /* Timeout */ 10111 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10112 res = 0; 10113 goto out; 10114 } else if (cmd < 0) { 10115 /* Hangup */ 10116 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10117 res = -1; 10118 goto out; 10119 } 10120 } 10121 #ifdef IMAP_STORAGE 10122 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10123 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10124 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10125 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10126 } 10127 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10128 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10129 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10130 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10131 } 10132 #endif 10133 10134 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10135 if (play_auto) { 10136 cmd = '1'; 10137 } else { 10138 cmd = vm_intro(chan, vmu, &vms); 10139 } 10140 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10141 10142 vms.repeats = 0; 10143 vms.starting = 1; 10144 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10145 /* Run main menu */ 10146 switch (cmd) { 10147 case '1': /* First message */ 10148 vms.curmsg = 0; 10149 /* Fall through */ 10150 case '5': /* Play current message */ 10151 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10152 cmd = vm_browse_messages(chan, &vms, vmu); 10153 break; 10154 case '2': /* Change folders */ 10155 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10156 if (useadsi) 10157 adsi_folders(chan, 0, "Change to folder..."); 10158 10159 cmd = get_folder2(chan, "vm-changeto", 0); 10160 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10161 if (cmd == '#') { 10162 cmd = 0; 10163 } else if (cmd > 0) { 10164 cmd = cmd - '0'; 10165 res = close_mailbox(&vms, vmu); 10166 if (res == ERROR_LOCK_PATH) 10167 goto out; 10168 /* If folder is not urgent, set in_urgent to zero! */ 10169 if (cmd != 11) in_urgent = 0; 10170 res = open_mailbox(&vms, vmu, cmd); 10171 if (res < 0) 10172 goto out; 10173 play_folder = cmd; 10174 cmd = 0; 10175 } 10176 if (useadsi) 10177 adsi_status2(chan, &vms); 10178 10179 if (!cmd) { 10180 cmd = vm_play_folder_name(chan, vms.vmbox); 10181 } 10182 10183 vms.starting = 1; 10184 vms.curmsg = 0; 10185 break; 10186 case '3': /* Advanced options */ 10187 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10188 cmd = 0; 10189 vms.repeats = 0; 10190 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10191 switch (cmd) { 10192 case '1': /* Reply */ 10193 if (vms.lastmsg > -1 && !vms.starting) { 10194 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10195 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10196 res = cmd; 10197 goto out; 10198 } 10199 } else { 10200 cmd = ast_play_and_wait(chan, "vm-sorry"); 10201 } 10202 cmd = 't'; 10203 break; 10204 case '2': /* Callback */ 10205 if (!vms.starting) 10206 ast_verb(3, "Callback Requested\n"); 10207 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10208 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10209 if (cmd == 9) { 10210 silentexit = 1; 10211 goto out; 10212 } else if (cmd == ERROR_LOCK_PATH) { 10213 res = cmd; 10214 goto out; 10215 } 10216 } else { 10217 cmd = ast_play_and_wait(chan, "vm-sorry"); 10218 } 10219 cmd = 't'; 10220 break; 10221 case '3': /* Envelope */ 10222 if (vms.lastmsg > -1 && !vms.starting) { 10223 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10224 if (cmd == ERROR_LOCK_PATH) { 10225 res = cmd; 10226 goto out; 10227 } 10228 } else { 10229 cmd = ast_play_and_wait(chan, "vm-sorry"); 10230 } 10231 cmd = 't'; 10232 break; 10233 case '4': /* Dialout */ 10234 if (!ast_strlen_zero(vmu->dialout)) { 10235 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10236 if (cmd == 9) { 10237 silentexit = 1; 10238 goto out; 10239 } 10240 } else { 10241 cmd = ast_play_and_wait(chan, "vm-sorry"); 10242 } 10243 cmd = 't'; 10244 break; 10245 10246 case '5': /* Leave VoiceMail */ 10247 if (ast_test_flag(vmu, VM_SVMAIL)) { 10248 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10249 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10250 res = cmd; 10251 goto out; 10252 } 10253 } else { 10254 cmd = ast_play_and_wait(chan, "vm-sorry"); 10255 } 10256 cmd = 't'; 10257 break; 10258 10259 case '*': /* Return to main menu */ 10260 cmd = 't'; 10261 break; 10262 10263 default: 10264 cmd = 0; 10265 if (!vms.starting) { 10266 cmd = ast_play_and_wait(chan, "vm-toreply"); 10267 } 10268 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10269 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10270 } 10271 if (!cmd && !vms.starting) { 10272 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10273 } 10274 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10275 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10276 } 10277 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10278 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10279 } 10280 if (!cmd) { 10281 cmd = ast_play_and_wait(chan, "vm-starmain"); 10282 } 10283 if (!cmd) { 10284 cmd = ast_waitfordigit(chan, 6000); 10285 } 10286 if (!cmd) { 10287 vms.repeats++; 10288 } 10289 if (vms.repeats > 3) { 10290 cmd = 't'; 10291 } 10292 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10293 } 10294 } 10295 if (cmd == 't') { 10296 cmd = 0; 10297 vms.repeats = 0; 10298 } 10299 break; 10300 case '4': /* Go to the previous message */ 10301 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10302 if (vms.curmsg > 0) { 10303 vms.curmsg--; 10304 cmd = play_message(chan, vmu, &vms); 10305 } else { 10306 /* Check if we were listening to new 10307 messages. If so, go to Urgent messages 10308 instead of saying "no more messages" 10309 */ 10310 if (in_urgent == 0 && vms.urgentmessages > 0) { 10311 /* Check for Urgent messages */ 10312 in_urgent = 1; 10313 res = close_mailbox(&vms, vmu); 10314 if (res == ERROR_LOCK_PATH) 10315 goto out; 10316 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10317 if (res < 0) 10318 goto out; 10319 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10320 vms.curmsg = vms.lastmsg; 10321 if (vms.lastmsg < 0) { 10322 cmd = ast_play_and_wait(chan, "vm-nomore"); 10323 } 10324 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10325 vms.curmsg = vms.lastmsg; 10326 cmd = play_message(chan, vmu, &vms); 10327 } else { 10328 cmd = ast_play_and_wait(chan, "vm-nomore"); 10329 } 10330 } 10331 break; 10332 case '6': /* Go to the next message */ 10333 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10334 if (vms.curmsg < vms.lastmsg) { 10335 vms.curmsg++; 10336 cmd = play_message(chan, vmu, &vms); 10337 } else { 10338 if (in_urgent && vms.newmessages > 0) { 10339 /* Check if we were listening to urgent 10340 * messages. If so, go to regular new messages 10341 * instead of saying "no more messages" 10342 */ 10343 in_urgent = 0; 10344 res = close_mailbox(&vms, vmu); 10345 if (res == ERROR_LOCK_PATH) 10346 goto out; 10347 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10348 if (res < 0) 10349 goto out; 10350 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10351 vms.curmsg = -1; 10352 if (vms.lastmsg < 0) { 10353 cmd = ast_play_and_wait(chan, "vm-nomore"); 10354 } 10355 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10356 vms.curmsg = 0; 10357 cmd = play_message(chan, vmu, &vms); 10358 } else { 10359 cmd = ast_play_and_wait(chan, "vm-nomore"); 10360 } 10361 } 10362 break; 10363 case '7': /* Delete the current message */ 10364 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10365 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10366 if (useadsi) 10367 adsi_delete(chan, &vms); 10368 if (vms.deleted[vms.curmsg]) { 10369 if (play_folder == 0) { 10370 if (in_urgent) { 10371 vms.urgentmessages--; 10372 } else { 10373 vms.newmessages--; 10374 } 10375 } 10376 else if (play_folder == 1) 10377 vms.oldmessages--; 10378 cmd = ast_play_and_wait(chan, "vm-deleted"); 10379 } else { 10380 if (play_folder == 0) { 10381 if (in_urgent) { 10382 vms.urgentmessages++; 10383 } else { 10384 vms.newmessages++; 10385 } 10386 } 10387 else if (play_folder == 1) 10388 vms.oldmessages++; 10389 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10390 } 10391 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10392 if (vms.curmsg < vms.lastmsg) { 10393 vms.curmsg++; 10394 cmd = play_message(chan, vmu, &vms); 10395 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10396 vms.curmsg = 0; 10397 cmd = play_message(chan, vmu, &vms); 10398 } else { 10399 /* Check if we were listening to urgent 10400 messages. If so, go to regular new messages 10401 instead of saying "no more messages" 10402 */ 10403 if (in_urgent == 1) { 10404 /* Check for new messages */ 10405 in_urgent = 0; 10406 res = close_mailbox(&vms, vmu); 10407 if (res == ERROR_LOCK_PATH) 10408 goto out; 10409 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10410 if (res < 0) 10411 goto out; 10412 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10413 vms.curmsg = -1; 10414 if (vms.lastmsg < 0) { 10415 cmd = ast_play_and_wait(chan, "vm-nomore"); 10416 } 10417 } else { 10418 cmd = ast_play_and_wait(chan, "vm-nomore"); 10419 } 10420 } 10421 } 10422 } else /* Delete not valid if we haven't selected a message */ 10423 cmd = 0; 10424 #ifdef IMAP_STORAGE 10425 deleted = 1; 10426 #endif 10427 break; 10428 10429 case '8': /* Forward the current message */ 10430 if (vms.lastmsg > -1) { 10431 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10432 if (cmd == ERROR_LOCK_PATH) { 10433 res = cmd; 10434 goto out; 10435 } 10436 } else { 10437 /* Check if we were listening to urgent 10438 messages. If so, go to regular new messages 10439 instead of saying "no more messages" 10440 */ 10441 if (in_urgent == 1 && vms.newmessages > 0) { 10442 /* Check for new messages */ 10443 in_urgent = 0; 10444 res = close_mailbox(&vms, vmu); 10445 if (res == ERROR_LOCK_PATH) 10446 goto out; 10447 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10448 if (res < 0) 10449 goto out; 10450 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10451 vms.curmsg = -1; 10452 if (vms.lastmsg < 0) { 10453 cmd = ast_play_and_wait(chan, "vm-nomore"); 10454 } 10455 } else { 10456 cmd = ast_play_and_wait(chan, "vm-nomore"); 10457 } 10458 } 10459 break; 10460 case '9': /* Save message to folder */ 10461 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10462 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10463 /* No message selected */ 10464 cmd = 0; 10465 break; 10466 } 10467 if (useadsi) 10468 adsi_folders(chan, 1, "Save to folder..."); 10469 cmd = get_folder2(chan, "vm-savefolder", 1); 10470 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10471 box = 0; /* Shut up compiler */ 10472 if (cmd == '#') { 10473 cmd = 0; 10474 break; 10475 } else if (cmd > 0) { 10476 box = cmd = cmd - '0'; 10477 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10478 if (cmd == ERROR_LOCK_PATH) { 10479 res = cmd; 10480 goto out; 10481 #ifndef IMAP_STORAGE 10482 } else if (!cmd) { 10483 vms.deleted[vms.curmsg] = 1; 10484 #endif 10485 } else { 10486 vms.deleted[vms.curmsg] = 0; 10487 vms.heard[vms.curmsg] = 0; 10488 } 10489 } 10490 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10491 if (useadsi) 10492 adsi_message(chan, &vms); 10493 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10494 if (!cmd) { 10495 cmd = ast_play_and_wait(chan, "vm-message"); 10496 if (!cmd) 10497 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10498 if (!cmd) 10499 cmd = ast_play_and_wait(chan, "vm-savedto"); 10500 if (!cmd) 10501 cmd = vm_play_folder_name(chan, vms.fn); 10502 } else { 10503 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10504 } 10505 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10506 if (vms.curmsg < vms.lastmsg) { 10507 vms.curmsg++; 10508 cmd = play_message(chan, vmu, &vms); 10509 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10510 vms.curmsg = 0; 10511 cmd = play_message(chan, vmu, &vms); 10512 } else { 10513 /* Check if we were listening to urgent 10514 messages. If so, go to regular new messages 10515 instead of saying "no more messages" 10516 */ 10517 if (in_urgent == 1 && vms.newmessages > 0) { 10518 /* Check for new messages */ 10519 in_urgent = 0; 10520 res = close_mailbox(&vms, vmu); 10521 if (res == ERROR_LOCK_PATH) 10522 goto out; 10523 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10524 if (res < 0) 10525 goto out; 10526 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10527 vms.curmsg = -1; 10528 if (vms.lastmsg < 0) { 10529 cmd = ast_play_and_wait(chan, "vm-nomore"); 10530 } 10531 } else { 10532 cmd = ast_play_and_wait(chan, "vm-nomore"); 10533 } 10534 } 10535 } 10536 break; 10537 case '*': /* Help */ 10538 if (!vms.starting) { 10539 cmd = ast_play_and_wait(chan, "vm-onefor"); 10540 if (!strncasecmp(chan->language, "he", 2)) { 10541 cmd = ast_play_and_wait(chan, "vm-for"); 10542 } 10543 if (!cmd) 10544 cmd = vm_play_folder_name(chan, vms.vmbox); 10545 if (!cmd) 10546 cmd = ast_play_and_wait(chan, "vm-opts"); 10547 if (!cmd) 10548 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10549 } else 10550 cmd = 0; 10551 break; 10552 case '0': /* Mailbox options */ 10553 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10554 if (useadsi) 10555 adsi_status(chan, &vms); 10556 break; 10557 default: /* Nothing */ 10558 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10559 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10560 break; 10561 } 10562 } 10563 if ((cmd == 't') || (cmd == '#')) { 10564 /* Timeout */ 10565 res = 0; 10566 } else { 10567 /* Hangup */ 10568 res = -1; 10569 } 10570 10571 out: 10572 if (res > -1) { 10573 ast_stopstream(chan); 10574 adsi_goodbye(chan); 10575 if (valid && res != OPERATOR_EXIT) { 10576 if (silentexit) 10577 res = ast_play_and_wait(chan, "vm-dialout"); 10578 else 10579 res = ast_play_and_wait(chan, "vm-goodbye"); 10580 } 10581 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10582 res = 0; 10583 } 10584 if (useadsi) 10585 ast_adsi_unload_session(chan); 10586 } 10587 if (vmu) 10588 close_mailbox(&vms, vmu); 10589 if (valid) { 10590 int new = 0, old = 0, urgent = 0; 10591 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10592 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10593 /* Urgent flag not passwd to externnotify here */ 10594 run_externnotify(vmu->context, vmu->mailbox, NULL); 10595 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10596 queue_mwi_event(ext_context, urgent, new, old); 10597 } 10598 #ifdef IMAP_STORAGE 10599 /* expunge message - use UID Expunge if supported on IMAP server*/ 10600 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10601 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10602 ast_mutex_lock(&vms.lock); 10603 #ifdef HAVE_IMAP_TK2006 10604 if (LEVELUIDPLUS (vms.mailstream)) { 10605 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10606 } else 10607 #endif 10608 mail_expunge(vms.mailstream); 10609 ast_mutex_unlock(&vms.lock); 10610 } 10611 /* before we delete the state, we should copy pertinent info 10612 * back to the persistent model */ 10613 if (vmu) { 10614 vmstate_delete(&vms); 10615 } 10616 #endif 10617 if (vmu) 10618 free_user(vmu); 10619 10620 #ifdef IMAP_STORAGE 10621 pthread_setspecific(ts_vmstate.key, NULL); 10622 #endif 10623 return res; 10624 }
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/1"); 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/1"); 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 11392 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11394 { 11395 struct ast_vm_user *user; 11396 11397 AST_LIST_LOCK(&users); 11398 AST_LIST_TRAVERSE(&users, user, list) { 11399 vm_users_data_provider_get_helper(search, data_root, user); 11400 } 11401 AST_LIST_UNLOCK(&users); 11402 11403 return 0; 11404 }
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 11345 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().
11347 { 11348 struct ast_data *data_user, *data_zone; 11349 struct ast_data *data_state; 11350 struct vm_zone *zone = NULL; 11351 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11352 char ext_context[256] = ""; 11353 11354 data_user = ast_data_add_node(data_root, "user"); 11355 if (!data_user) { 11356 return -1; 11357 } 11358 11359 ast_data_add_structure(ast_vm_user, data_user, user); 11360 11361 AST_LIST_LOCK(&zones); 11362 AST_LIST_TRAVERSE(&zones, zone, list) { 11363 if (!strcmp(zone->name, user->zonetag)) { 11364 break; 11365 } 11366 } 11367 AST_LIST_UNLOCK(&zones); 11368 11369 /* state */ 11370 data_state = ast_data_add_node(data_user, "state"); 11371 if (!data_state) { 11372 return -1; 11373 } 11374 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11375 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11376 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11377 ast_data_add_int(data_state, "newmsg", newmsg); 11378 ast_data_add_int(data_state, "oldmsg", oldmsg); 11379 11380 if (zone) { 11381 data_zone = ast_data_add_node(data_user, "zone"); 11382 ast_data_add_structure(vm_zone, data_zone, zone); 11383 } 11384 11385 if (!ast_data_search_match(search, data_user)) { 11386 ast_data_remove_node(data_root, data_user); 11387 } 11388 11389 return 0; 11390 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11031 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().
11032 { 11033 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11034 struct ast_vm_user vmus; 11035 char *options = NULL; 11036 int silent = 0, skipuser = 0; 11037 int res = -1; 11038 11039 if (data) { 11040 s = ast_strdupa(data); 11041 user = strsep(&s, ","); 11042 options = strsep(&s, ","); 11043 if (user) { 11044 s = user; 11045 user = strsep(&s, "@"); 11046 context = strsep(&s, ""); 11047 if (!ast_strlen_zero(user)) 11048 skipuser++; 11049 ast_copy_string(mailbox, user, sizeof(mailbox)); 11050 } 11051 } 11052 11053 if (options) { 11054 silent = (strchr(options, 's')) != NULL; 11055 } 11056 11057 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11058 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11059 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11060 ast_play_and_wait(chan, "auth-thankyou"); 11061 res = 0; 11062 } else if (mailbox[0] == '*') { 11063 /* user entered '*' */ 11064 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11065 res = 0; /* prevent hangup */ 11066 } 11067 } 11068 11069 return res; 11070 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12571 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().
12572 { 12573 char *context; 12574 char *args_copy; 12575 int res; 12576 12577 if (ast_strlen_zero(data)) { 12578 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12579 return -1; 12580 } 12581 12582 args_copy = ast_strdupa(data); 12583 if ((context = strchr(args_copy, '@'))) { 12584 *context++ = '\0'; 12585 } else { 12586 context = "default"; 12587 } 12588 12589 if ((res = sayname(chan, args_copy, context) < 0)) { 12590 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12591 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12592 if (!res) { 12593 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12594 } 12595 } 12596 12597 return res; 12598 }
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 12538 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().
12538 { 12539 struct ast_config *conf; 12540 struct ast_category *cat; 12541 struct ast_variable *var; 12542 int res = -1; 12543 12544 if (!(conf = ast_config_new())) { 12545 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12546 return res; 12547 } 12548 if (!(cat = ast_category_new("general", "", 1))) { 12549 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12550 ast_config_destroy(conf); 12551 return res; 12552 } 12553 if (!(var = ast_variable_new("password", password, ""))) { 12554 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12555 ast_config_destroy(conf); 12556 ast_category_destroy(cat); 12557 return res; 12558 } 12559 ast_category_append(conf, cat); 12560 ast_variable_append(cat, var); 12561 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12562 res = 0; 12563 } else { 12564 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12565 } 12566 12567 ast_config_destroy(conf); 12568 return res; 12569 }
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 11270 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 11026 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 11411 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 11406 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.