Comedian Mail - Voicemail System. More...
#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj2.h"
#include "asterisk/event.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
Go to the source code of this file.
Data Structures | |
struct | ast_vm_user |
struct | baseio |
struct | inprocess |
struct | leave_vm_options |
Options for leaving voicemail with the voicemail() application. More... | |
struct | mwi_sub |
An MWI subscription. More... | |
struct | mwi_sub_task |
struct | vm_state |
struct | vm_zone |
Defines | |
#define | ASTERISK_USERNAME "asterisk" |
#define | BASELINELEN 72 |
#define | BASEMAXINLINE 256 |
#define | CHUNKSIZE 65536 |
#define | COMMAND_TIMEOUT 5000 |
#define | COPY(a, b, c, d, e, f, g, h) (copy_plain_file(g,h)); |
#define | DATA_EXPORT_VM_USERS(USER) |
#define | DATA_EXPORT_VM_ZONES(ZONE) |
#define | DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
#define | DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
#define | DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
#define | DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
#define | DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
#define | DEFAULT_POLL_FREQ 30 |
#define | DELETE(a, b, c, d) (vm_delete(c)) |
#define | DISPOSE(a, b) |
#define | ENDL "\n" |
#define | ERROR_LOCK_PATH -100 |
#define | EXISTS(a, b, c, d) (ast_fileexists(c,NULL,d) > 0) |
#define | HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define | HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define | INTRO "vm-intro" |
#define | MAX_DATETIME_FORMAT 512 |
#define | MAX_NUM_CID_CONTEXTS 10 |
#define | MAXMSG 100 |
#define | MAXMSGLIMIT 9999 |
#define | MINPASSWORD 0 |
#define | OPERATOR_EXIT 300 |
#define | PWDCHANGE_EXTERNAL (1 << 2) |
#define | PWDCHANGE_INTERNAL (1 << 1) |
#define | RENAME(a, b, c, d, e, f, g, h) (rename_file(g,h)); |
#define | RETRIEVE(a, b, c, d) |
#define | SENDMAIL "/usr/sbin/sendmail -t" |
#define | SMDI_MWI_WAIT_TIMEOUT 1000 |
#define | STORE(a, b, c, d, e, f, g, h, i, j) |
#define | tdesc "Comedian Mail (Voicemail System)" |
#define | VALID_DTMF "1234567890*#" |
#define | VM_ALLOCED (1 << 13) |
#define | VM_ATTACH (1 << 11) |
#define | VM_DELETE (1 << 12) |
#define | VM_DIRECFORWARD (1 << 10) |
#define | VM_ENVELOPE (1 << 4) |
#define | VM_FORCEGREET (1 << 8) |
#define | VM_FORCENAME (1 << 7) |
#define | VM_FWDURGAUTO (1 << 18) |
#define | VM_MESSAGEWRAP (1 << 17) |
#define | VM_MOVEHEARD (1 << 16) |
#define | VM_OPERATOR (1 << 1) |
#define | VM_PBXSKIP (1 << 9) |
#define | VM_REVIEW (1 << 0) |
#define | VM_SAYCID (1 << 2) |
#define | VM_SAYDURATION (1 << 5) |
#define | VM_SEARCH (1 << 14) |
#define | VM_SKIPAFTERCMD (1 << 6) |
#define | VM_SVMAIL (1 << 3) |
#define | VM_TEMPGREETWARN (1 << 15) |
#define | VMSTATE_MAX_MSG_ARRAY 256 |
#define | VOICEMAIL_CONFIG "voicemail.conf" |
#define | VOICEMAIL_DIR_MODE 0777 |
#define | VOICEMAIL_FILE_MODE 0666 |
Enumerations | |
enum | vm_box { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER } |
enum | vm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
enum | vm_option_flags { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9) } |
enum | vm_passwordlocation { OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2 } |
Functions | |
static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
static int | acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len) |
static int | actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg) |
static int | add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum) |
static void | adsi_begin (struct ast_channel *chan, int *useadsi) |
static void | adsi_delete (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_folders (struct ast_channel *chan, int start, char *label) |
static void | adsi_goodbye (struct ast_channel *chan) |
static int | adsi_load_vmail (struct ast_channel *chan, int *useadsi) |
static void | adsi_login (struct ast_channel *chan) |
static int | adsi_logo (unsigned char *buf) |
static void | adsi_message (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_password (struct ast_channel *chan) |
static void | adsi_status (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_status2 (struct ast_channel *chan, struct vm_state *vms) |
static int | advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain) |
The advanced options within a message. | |
static int | append_mailbox (const char *context, const char *box, const char *data) |
static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
Sets a a specific property value. | |
static void | apply_options (struct ast_vm_user *vmu, const char *options) |
Destructively Parse options and apply. | |
static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
Loads the options specific to a voicemail user. | |
AST_APP_OPTIONS (vm_app_options,{AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION_ARG('d', OPT_DTMFEXIT, OPT_ARG_DTMFEXIT), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER), AST_APP_OPTION('U', OPT_MESSAGE_Urgent),}) | |
AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
static | AST_LIST_HEAD_STATIC (zones, vm_zone) |
static | AST_LIST_HEAD_STATIC (users, ast_vm_user) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,.nonoptreq="res_adsi,res_smdi",) | |
AST_MUTEX_DEFINE_STATIC (poll_lock) | |
static | AST_RWLIST_HEAD_STATIC (mwi_subs, mwi_sub) |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble) |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. | |
static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
AST_TEST_DEFINE (test_voicemail_vmuser) | |
static int | base_encode (char *filename, FILE *so) |
Performs a base 64 encode algorithm on the contents of a File. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
static int | check_mime (const char *str) |
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. | |
static int | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
static int | close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu) |
static char * | complete_voicemail_show_users (const char *line, const char *word, int pos, int state) |
static int | copy (char *infile, char *outfile) |
Utility function to copy a file. | |
static int | copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag) |
Copies a message from one mailbox to another. | |
static void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
static int | count_messages (struct ast_vm_user *vmu, char *dir) |
Find all .txt files - even if they are not in sequence from 0000. | |
static int | create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder) |
basically mkdir -p $dest/$context/$ext/$folder | |
static int | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the users file or the realtime engine. | |
static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the realtime engine. | |
static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent) |
Sends a voicemail message to a mailbox recipient. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
static void | free_zone (struct vm_zone *z) |
static int | get_date (char *s, int len) |
Gets the current date and time, as formatted string. | |
static int | get_folder (struct ast_channel *chan, int start) |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
plays a prompt and waits for a keypress. | |
static int | get_folder_by_name (const char *name) |
static int | handle_subscribe (void *datap) |
static int | handle_unsubscribe (void *datap) |
static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload voicemail configuration from the CLI. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
static int | inbuf (struct baseio *bio, FILE *fi) |
utility used by inchar(), for base_encode() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
static int | inprocess_count (const char *context, const char *mailbox, int delta) |
static int | inprocess_hash_fn (const void *obj, const int flags) |
static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
static int | is_valid_dtmf (const char *key) |
Determines if a DTMF key entered is valid. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
static int | load_config (int reload) |
static int | load_module (void) |
static int | make_dir (char *dest, int len, const char *context, const char *ext, const char *folder) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static int | make_file (char *dest, const int len, const char *dir, const int num) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
static void * | mb_poll_thread (void *data) |
static const char * | mbox (struct ast_vm_user *vmu, int id) |
static int | messagecount (const char *context, const char *mailbox, const char *folder) |
static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
Sends email notification that a user has a new voicemail waiting for them. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback) |
static int | play_message_category (struct ast_channel *chan, const char *category) |
static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag) |
static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
static void | poll_subscribed_mailboxes (void) |
static void | populate_defaults (struct ast_vm_user *vmu) |
Sets default voicemail system options to a voicemail user. | |
static void | prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
static FILE * | vm_mkftemp (char *template) |
static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
static int | vm_play_folder_name_gr (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static char * | addesc = "Comedian Mail" |
static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
static int | adsiver = 1 |
static char * | app = "VoiceMail" |
static char * | app2 = "VoiceMailMain" |
static char * | app3 = "MailboxExists" |
static char * | app4 = "VMAuthenticate" |
static char | callcontext [AST_MAX_CONTEXT] = "" |
static char | charset [32] = "ISO-8859-1" |
static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
static struct ast_cli_entry | cli_voicemail [] |
static char | dialcontext [AST_MAX_CONTEXT] = "" |
static char * | emailbody = NULL |
static char | emaildateformat [32] = "%A, %B %d, %Y at %r" |
static char * | emailsubject = NULL |
static char | exitcontext [AST_MAX_CONTEXT] = "" |
static char | ext_pass_check_cmd [128] |
static char | ext_pass_cmd [128] |
static char | externnotify [160] |
static char | fromstring [100] |
static struct ast_flags | globalflags = {0} |
struct ao2_container * | inprocess_container |
static char | listen_control_forward_key [12] |
static char | listen_control_pause_key [12] |
static char | listen_control_restart_key [12] |
static char | listen_control_reverse_key [12] |
static char | listen_control_stop_key [12] |
static char | locale [20] |
static struct ast_custom_function | mailbox_exists_acf |
static const char *const | mailbox_folders [] |
static char | mailcmd [160] |
static int | maxdeletedmsg |
static int | maxgreet |
static int | maxlogins |
static int | maxmsg |
static int | maxsilence |
static int | minpassword |
static struct ast_event_sub * | mwi_sub_sub |
static struct ast_taskprocessor * | mwi_subscription_tps |
static struct ast_event_sub * | mwi_unsub_sub |
static int | my_umask |
static char * | pagerbody = NULL |
static char | pagerdateformat [32] = "%A, %B %d, %Y at %r" |
static char | pagerfromstring [100] |
static char * | pagersubject = NULL |
static int | passwordlocation |
static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
static unsigned int | poll_freq |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char * | sayname_app = "VMSayName" |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static struct ast_data_entry | vm_data_providers [] |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
static char | vm_passchanged [80] = "vm-passchanged" |
static char | vm_password [80] = "vm-password" |
static char | vm_pls_try_again [80] = "vm-pls-try-again" |
static char | vm_prepend_timeout [80] = "vm-then-pound" |
static char | vm_reenterpassword [80] = "vm-reenterpassword" |
static char | VM_SPOOL_DIR [PATH_MAX] |
static struct ast_data_handler | vm_users_data_provider |
static char | vmfmts [80] |
static int | vmmaxsecs |
static int | vmminsecs |
static double | volgain |
static char | zonetag [80] |
Comedian Mail - Voicemail System.
Definition in file app_voicemail_odbcstorage.c.
#define ASTERISK_USERNAME "asterisk" |
Definition at line 411 of file app_voicemail_odbcstorage.c.
#define BASELINELEN 72 |
Definition at line 434 of file app_voicemail_odbcstorage.c.
#define BASEMAXINLINE 256 |
Definition at line 435 of file app_voicemail_odbcstorage.c.
#define CHUNKSIZE 65536 |
Definition at line 408 of file app_voicemail_odbcstorage.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 404 of file app_voicemail_odbcstorage.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
Definition at line 721 of file app_voicemail_odbcstorage.c.
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11324 of file app_voicemail_odbcstorage.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 11351 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 416 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 418 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 419 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 417 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 420 of file app_voicemail_odbcstorage.c.
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 791 of file app_voicemail_odbcstorage.c.
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 722 of file app_voicemail_odbcstorage.c.
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 717 of file app_voicemail_odbcstorage.c.
#define ENDL "\n" |
Definition at line 439 of file app_voicemail_odbcstorage.c.
#define ERROR_LOCK_PATH -100 |
Definition at line 464 of file app_voicemail_odbcstorage.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 719 of file app_voicemail_odbcstorage.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 427 of file app_voicemail_odbcstorage.c.
#define MAX_DATETIME_FORMAT 512 |
Definition at line 442 of file app_voicemail_odbcstorage.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 443 of file app_voicemail_odbcstorage.c.
#define MAXMSG 100 |
Definition at line 429 of file app_voicemail_odbcstorage.c.
#define MAXMSGLIMIT 9999 |
Definition at line 430 of file app_voicemail_odbcstorage.c.
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 432 of file app_voicemail_odbcstorage.c.
#define OPERATOR_EXIT 300 |
Definition at line 465 of file app_voicemail_odbcstorage.c.
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 734 of file app_voicemail_odbcstorage.c.
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 733 of file app_voicemail_odbcstorage.c.
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 720 of file app_voicemail_odbcstorage.c.
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 716 of file app_voicemail_odbcstorage.c.
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 425 of file app_voicemail_odbcstorage.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 402 of file app_voicemail_odbcstorage.c.
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 718 of file app_voicemail_odbcstorage.c.
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 743 of file app_voicemail_odbcstorage.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 421 of file app_voicemail_odbcstorage.c.
#define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 458 of file app_voicemail_odbcstorage.c.
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 456 of file app_voicemail_odbcstorage.c.
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 457 of file app_voicemail_odbcstorage.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 455 of file app_voicemail_odbcstorage.c.
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 449 of file app_voicemail_odbcstorage.c.
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 453 of file app_voicemail_odbcstorage.c.
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 452 of file app_voicemail_odbcstorage.c.
#define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 463 of file app_voicemail_odbcstorage.c.
#define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 462 of file app_voicemail_odbcstorage.c.
#define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 461 of file app_voicemail_odbcstorage.c.
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 446 of file app_voicemail_odbcstorage.c.
#define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 454 of file app_voicemail_odbcstorage.c.
#define VM_REVIEW (1 << 0) |
After recording, permit the caller to review the recording before saving
Definition at line 445 of file app_voicemail_odbcstorage.c.
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 447 of file app_voicemail_odbcstorage.c.
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 450 of file app_voicemail_odbcstorage.c.
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 459 of file app_voicemail_odbcstorage.c.
#define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 451 of file app_voicemail_odbcstorage.c.
#define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 448 of file app_voicemail_odbcstorage.c.
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 460 of file app_voicemail_odbcstorage.c.
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 658 of file app_voicemail_odbcstorage.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 410 of file app_voicemail_odbcstorage.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 406 of file app_voicemail_odbcstorage.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 407 of file app_voicemail_odbcstorage.c.
enum vm_box |
Definition at line 468 of file app_voicemail_odbcstorage.c.
00468 { 00469 NEW_FOLDER, 00470 OLD_FOLDER, 00471 WORK_FOLDER, 00472 FAMILY_FOLDER, 00473 FRIENDS_FOLDER, 00474 GREETINGS_FOLDER 00475 };
enum vm_option_args |
Definition at line 489 of file app_voicemail_odbcstorage.c.
00489 { 00490 OPT_ARG_RECORDGAIN = 0, 00491 OPT_ARG_PLAYFOLDER = 1, 00492 OPT_ARG_DTMFEXIT = 2, 00493 /* This *must* be the last value in this enum! */ 00494 OPT_ARG_ARRAY_SIZE = 3, 00495 };
enum vm_option_flags |
Definition at line 477 of file app_voicemail_odbcstorage.c.
00477 { 00478 OPT_SILENT = (1 << 0), 00479 OPT_BUSY_GREETING = (1 << 1), 00480 OPT_UNAVAIL_GREETING = (1 << 2), 00481 OPT_RECORDGAIN = (1 << 3), 00482 OPT_PREPEND_MAILBOX = (1 << 4), 00483 OPT_AUTOPLAY = (1 << 6), 00484 OPT_DTMFEXIT = (1 << 7), 00485 OPT_MESSAGE_Urgent = (1 << 8), 00486 OPT_MESSAGE_PRIORITY = (1 << 9) 00487 };
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 497 of file app_voicemail_odbcstorage.c.
00497 { 00498 OPT_PWLOC_VOICEMAILCONF = 0, 00499 OPT_PWLOC_SPOOLDIR = 1, 00500 OPT_PWLOC_USERSCONF = 2, 00501 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5369 of file app_voicemail_odbcstorage.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05370 { 05371 DIR *dir; 05372 struct dirent *de; 05373 char fn[256]; 05374 int ret = 0; 05375 05376 /* If no mailbox, return immediately */ 05377 if (ast_strlen_zero(mailbox)) 05378 return 0; 05379 05380 if (ast_strlen_zero(folder)) 05381 folder = "INBOX"; 05382 if (ast_strlen_zero(context)) 05383 context = "default"; 05384 05385 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05386 05387 if (!(dir = opendir(fn))) 05388 return 0; 05389 05390 while ((de = readdir(dir))) { 05391 if (!strncasecmp(de->d_name, "msg", 3)) { 05392 if (shortcircuit) { 05393 ret = 1; 05394 break; 05395 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05396 ret++; 05397 } 05398 } 05399 } 05400 05401 closedir(dir); 05402 05403 return ret; 05404 }
static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | args, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 11027 of file app_voicemail_odbcstorage.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().
11028 { 11029 struct ast_vm_user svm; 11030 AST_DECLARE_APP_ARGS(arg, 11031 AST_APP_ARG(mbox); 11032 AST_APP_ARG(context); 11033 ); 11034 11035 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11036 11037 if (ast_strlen_zero(arg.mbox)) { 11038 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11039 return -1; 11040 } 11041 11042 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11043 return 0; 11044 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11861 of file app_voicemail_odbcstorage.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().
11862 { 11863 struct ast_vm_user *current; 11864 char *cat; 11865 struct ast_variable *var; 11866 const char *val; 11867 char *q, *stringp, *tmp; 11868 int x; 11869 int tmpadsi[4]; 11870 char secretfn[PATH_MAX] = ""; 11871 11872 #ifdef IMAP_STORAGE 11873 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11874 #endif 11875 /* set audio control prompts */ 11876 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11877 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11878 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11879 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11880 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11881 11882 /* Free all the users structure */ 11883 free_vm_users(); 11884 11885 /* Free all the zones structure */ 11886 free_vm_zones(); 11887 11888 AST_LIST_LOCK(&users); 11889 11890 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11891 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11892 11893 if (cfg) { 11894 /* General settings */ 11895 11896 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11897 val = "default"; 11898 ast_copy_string(userscontext, val, sizeof(userscontext)); 11899 /* Attach voice message to mail message ? */ 11900 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11901 val = "yes"; 11902 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11903 11904 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11905 val = "no"; 11906 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11907 11908 volgain = 0.0; 11909 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11910 sscanf(val, "%30lf", &volgain); 11911 11912 #ifdef ODBC_STORAGE 11913 strcpy(odbc_database, "asterisk"); 11914 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11915 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11916 } 11917 strcpy(odbc_table, "voicemessages"); 11918 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11919 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11920 } 11921 #endif 11922 /* Mail command */ 11923 strcpy(mailcmd, SENDMAIL); 11924 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11925 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11926 11927 maxsilence = 0; 11928 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11929 maxsilence = atoi(val); 11930 if (maxsilence > 0) 11931 maxsilence *= 1000; 11932 } 11933 11934 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11935 maxmsg = MAXMSG; 11936 } else { 11937 maxmsg = atoi(val); 11938 if (maxmsg < 0) { 11939 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11940 maxmsg = MAXMSG; 11941 } else if (maxmsg > MAXMSGLIMIT) { 11942 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11943 maxmsg = MAXMSGLIMIT; 11944 } 11945 } 11946 11947 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11948 maxdeletedmsg = 0; 11949 } else { 11950 if (sscanf(val, "%30d", &x) == 1) 11951 maxdeletedmsg = x; 11952 else if (ast_true(val)) 11953 maxdeletedmsg = MAXMSG; 11954 else 11955 maxdeletedmsg = 0; 11956 11957 if (maxdeletedmsg < 0) { 11958 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11959 maxdeletedmsg = MAXMSG; 11960 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11961 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11962 maxdeletedmsg = MAXMSGLIMIT; 11963 } 11964 } 11965 11966 /* Load date format config for voicemail mail */ 11967 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11968 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11969 } 11970 11971 /* Load date format config for voicemail pager mail */ 11972 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11973 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11974 } 11975 11976 /* External password changing command */ 11977 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11978 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11979 pwdchange = PWDCHANGE_EXTERNAL; 11980 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11981 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11982 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11983 } 11984 11985 /* External password validation command */ 11986 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11987 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11988 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11989 } 11990 11991 #ifdef IMAP_STORAGE 11992 /* IMAP server address */ 11993 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11994 ast_copy_string(imapserver, val, sizeof(imapserver)); 11995 } else { 11996 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11997 } 11998 /* IMAP server port */ 11999 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12000 ast_copy_string(imapport, val, sizeof(imapport)); 12001 } else { 12002 ast_copy_string(imapport, "143", sizeof(imapport)); 12003 } 12004 /* IMAP server flags */ 12005 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12006 ast_copy_string(imapflags, val, sizeof(imapflags)); 12007 } 12008 /* IMAP server master username */ 12009 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12010 ast_copy_string(authuser, val, sizeof(authuser)); 12011 } 12012 /* IMAP server master password */ 12013 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12014 ast_copy_string(authpassword, val, sizeof(authpassword)); 12015 } 12016 /* Expunge on exit */ 12017 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12018 if (ast_false(val)) 12019 expungeonhangup = 0; 12020 else 12021 expungeonhangup = 1; 12022 } else { 12023 expungeonhangup = 1; 12024 } 12025 /* IMAP voicemail folder */ 12026 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12027 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12028 } else { 12029 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12030 } 12031 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12032 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12033 } 12034 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12035 imapgreetings = ast_true(val); 12036 } else { 12037 imapgreetings = 0; 12038 } 12039 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12040 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12041 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12042 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12043 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12044 } else { 12045 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12046 } 12047 12048 /* There is some very unorthodox casting done here. This is due 12049 * to the way c-client handles the argument passed in. It expects a 12050 * void pointer and casts the pointer directly to a long without 12051 * first dereferencing it. */ 12052 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12053 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12054 } else { 12055 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12056 } 12057 12058 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12059 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12060 } else { 12061 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12062 } 12063 12064 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12065 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12066 } else { 12067 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12068 } 12069 12070 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12071 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12072 } else { 12073 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12074 } 12075 12076 /* Increment configuration version */ 12077 imapversion++; 12078 #endif 12079 /* External voicemail notify application */ 12080 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12081 ast_copy_string(externnotify, val, sizeof(externnotify)); 12082 ast_debug(1, "found externnotify: %s\n", externnotify); 12083 } else { 12084 externnotify[0] = '\0'; 12085 } 12086 12087 /* SMDI voicemail notification */ 12088 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12089 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12090 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12091 smdi_iface = ast_smdi_interface_find(val); 12092 } else { 12093 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12094 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12095 } 12096 if (!smdi_iface) { 12097 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12098 } 12099 } 12100 12101 /* Silence treshold */ 12102 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12103 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12104 silencethreshold = atoi(val); 12105 12106 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12107 val = ASTERISK_USERNAME; 12108 ast_copy_string(serveremail, val, sizeof(serveremail)); 12109 12110 vmmaxsecs = 0; 12111 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12112 if (sscanf(val, "%30d", &x) == 1) { 12113 vmmaxsecs = x; 12114 } else { 12115 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12116 } 12117 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12118 static int maxmessage_deprecate = 0; 12119 if (maxmessage_deprecate == 0) { 12120 maxmessage_deprecate = 1; 12121 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12122 } 12123 if (sscanf(val, "%30d", &x) == 1) { 12124 vmmaxsecs = x; 12125 } else { 12126 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12127 } 12128 } 12129 12130 vmminsecs = 0; 12131 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12132 if (sscanf(val, "%30d", &x) == 1) { 12133 vmminsecs = x; 12134 if (maxsilence / 1000 >= vmminsecs) { 12135 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12136 } 12137 } else { 12138 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12139 } 12140 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12141 static int maxmessage_deprecate = 0; 12142 if (maxmessage_deprecate == 0) { 12143 maxmessage_deprecate = 1; 12144 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12145 } 12146 if (sscanf(val, "%30d", &x) == 1) { 12147 vmminsecs = x; 12148 if (maxsilence / 1000 >= vmminsecs) { 12149 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12150 } 12151 } else { 12152 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12153 } 12154 } 12155 12156 val = ast_variable_retrieve(cfg, "general", "format"); 12157 if (!val) { 12158 val = "wav"; 12159 } else { 12160 tmp = ast_strdupa(val); 12161 val = ast_format_str_reduce(tmp); 12162 if (!val) { 12163 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12164 val = "wav"; 12165 } 12166 } 12167 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12168 12169 skipms = 3000; 12170 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12171 if (sscanf(val, "%30d", &x) == 1) { 12172 maxgreet = x; 12173 } else { 12174 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12175 } 12176 } 12177 12178 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12179 if (sscanf(val, "%30d", &x) == 1) { 12180 skipms = x; 12181 } else { 12182 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12183 } 12184 } 12185 12186 maxlogins = 3; 12187 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12188 if (sscanf(val, "%30d", &x) == 1) { 12189 maxlogins = x; 12190 } else { 12191 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12192 } 12193 } 12194 12195 minpassword = MINPASSWORD; 12196 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12197 if (sscanf(val, "%30d", &x) == 1) { 12198 minpassword = x; 12199 } else { 12200 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12201 } 12202 } 12203 12204 /* Force new user to record name ? */ 12205 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12206 val = "no"; 12207 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12208 12209 /* Force new user to record greetings ? */ 12210 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12211 val = "no"; 12212 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12213 12214 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12215 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12216 stringp = ast_strdupa(val); 12217 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12218 if (!ast_strlen_zero(stringp)) { 12219 q = strsep(&stringp, ","); 12220 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12221 q++; 12222 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12223 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12224 } else { 12225 cidinternalcontexts[x][0] = '\0'; 12226 } 12227 } 12228 } 12229 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12230 ast_debug(1, "VM Review Option disabled globally\n"); 12231 val = "no"; 12232 } 12233 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12234 12235 /* Temporary greeting reminder */ 12236 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12237 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12238 val = "no"; 12239 } else { 12240 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12241 } 12242 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12243 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12244 ast_debug(1, "VM next message wrap disabled globally\n"); 12245 val = "no"; 12246 } 12247 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12248 12249 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12250 ast_debug(1, "VM Operator break disabled globally\n"); 12251 val = "no"; 12252 } 12253 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12254 12255 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12256 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12257 val = "no"; 12258 } 12259 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12260 12261 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12262 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12263 val = "no"; 12264 } 12265 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12266 12267 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12268 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12269 val = "yes"; 12270 } 12271 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12272 12273 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12274 ast_debug(1, "Move Heard enabled globally\n"); 12275 val = "yes"; 12276 } 12277 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12278 12279 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12280 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12281 val = "no"; 12282 } 12283 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12284 12285 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12286 ast_debug(1, "Duration info before msg enabled globally\n"); 12287 val = "yes"; 12288 } 12289 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12290 12291 saydurationminfo = 2; 12292 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12293 if (sscanf(val, "%30d", &x) == 1) { 12294 saydurationminfo = x; 12295 } else { 12296 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12297 } 12298 } 12299 12300 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12301 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12302 val = "no"; 12303 } 12304 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12305 12306 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12307 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12308 ast_debug(1, "found dialout context: %s\n", dialcontext); 12309 } else { 12310 dialcontext[0] = '\0'; 12311 } 12312 12313 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12314 ast_copy_string(callcontext, val, sizeof(callcontext)); 12315 ast_debug(1, "found callback context: %s\n", callcontext); 12316 } else { 12317 callcontext[0] = '\0'; 12318 } 12319 12320 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12321 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12322 ast_debug(1, "found operator context: %s\n", exitcontext); 12323 } else { 12324 exitcontext[0] = '\0'; 12325 } 12326 12327 /* load password sounds configuration */ 12328 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12329 ast_copy_string(vm_password, val, sizeof(vm_password)); 12330 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12331 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12332 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12333 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12334 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12335 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12336 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12337 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12338 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12339 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12340 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12341 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12342 } 12343 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12344 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12345 } 12346 /* load configurable audio prompts */ 12347 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12348 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12349 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12350 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12351 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12352 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12353 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12354 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12355 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12356 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12357 12358 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12359 val = "no"; 12360 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12361 12362 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12363 val = "voicemail.conf"; 12364 } 12365 if (!(strcmp(val, "spooldir"))) { 12366 passwordlocation = OPT_PWLOC_SPOOLDIR; 12367 } else { 12368 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12369 } 12370 12371 poll_freq = DEFAULT_POLL_FREQ; 12372 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12373 if (sscanf(val, "%30u", &poll_freq) != 1) { 12374 poll_freq = DEFAULT_POLL_FREQ; 12375 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12376 } 12377 } 12378 12379 poll_mailboxes = 0; 12380 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12381 poll_mailboxes = ast_true(val); 12382 12383 memset(fromstring, 0, sizeof(fromstring)); 12384 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12385 strcpy(charset, "ISO-8859-1"); 12386 if (emailbody) { 12387 ast_free(emailbody); 12388 emailbody = NULL; 12389 } 12390 if (emailsubject) { 12391 ast_free(emailsubject); 12392 emailsubject = NULL; 12393 } 12394 if (pagerbody) { 12395 ast_free(pagerbody); 12396 pagerbody = NULL; 12397 } 12398 if (pagersubject) { 12399 ast_free(pagersubject); 12400 pagersubject = NULL; 12401 } 12402 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12403 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12404 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12405 ast_copy_string(fromstring, val, sizeof(fromstring)); 12406 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12407 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12408 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12409 ast_copy_string(charset, val, sizeof(charset)); 12410 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12411 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12412 for (x = 0; x < 4; x++) { 12413 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12414 } 12415 } 12416 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12417 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12418 for (x = 0; x < 4; x++) { 12419 memcpy(&adsisec[x], &tmpadsi[x], 1); 12420 } 12421 } 12422 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12423 if (atoi(val)) { 12424 adsiver = atoi(val); 12425 } 12426 } 12427 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12428 ast_copy_string(zonetag, val, sizeof(zonetag)); 12429 } 12430 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12431 ast_copy_string(locale, val, sizeof(locale)); 12432 } 12433 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12434 emailsubject = ast_strdup(substitute_escapes(val)); 12435 } 12436 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12437 emailbody = ast_strdup(substitute_escapes(val)); 12438 } 12439 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12440 pagersubject = ast_strdup(substitute_escapes(val)); 12441 } 12442 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12443 pagerbody = ast_strdup(substitute_escapes(val)); 12444 } 12445 12446 /* load mailboxes from users.conf */ 12447 if (ucfg) { 12448 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12449 if (!strcasecmp(cat, "general")) { 12450 continue; 12451 } 12452 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12453 continue; 12454 if ((current = find_or_create(userscontext, cat))) { 12455 populate_defaults(current); 12456 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12457 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12458 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12459 current->passwordlocation = OPT_PWLOC_USERSCONF; 12460 } 12461 12462 switch (current->passwordlocation) { 12463 case OPT_PWLOC_SPOOLDIR: 12464 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12465 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12466 } 12467 } 12468 } 12469 } 12470 12471 /* load mailboxes from voicemail.conf */ 12472 cat = ast_category_browse(cfg, NULL); 12473 while (cat) { 12474 if (strcasecmp(cat, "general")) { 12475 var = ast_variable_browse(cfg, cat); 12476 if (strcasecmp(cat, "zonemessages")) { 12477 /* Process mailboxes in this context */ 12478 while (var) { 12479 append_mailbox(cat, var->name, var->value); 12480 var = var->next; 12481 } 12482 } else { 12483 /* Timezones in this context */ 12484 while (var) { 12485 struct vm_zone *z; 12486 if ((z = ast_malloc(sizeof(*z)))) { 12487 char *msg_format, *tzone; 12488 msg_format = ast_strdupa(var->value); 12489 tzone = strsep(&msg_format, "|,"); 12490 if (msg_format) { 12491 ast_copy_string(z->name, var->name, sizeof(z->name)); 12492 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12493 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12494 AST_LIST_LOCK(&zones); 12495 AST_LIST_INSERT_HEAD(&zones, z, list); 12496 AST_LIST_UNLOCK(&zones); 12497 } else { 12498 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12499 ast_free(z); 12500 } 12501 } else { 12502 AST_LIST_UNLOCK(&users); 12503 return -1; 12504 } 12505 var = var->next; 12506 } 12507 } 12508 } 12509 cat = ast_category_browse(cfg, cat); 12510 } 12511 12512 AST_LIST_UNLOCK(&users); 12513 12514 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12515 start_poll_thread(); 12516 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12517 stop_poll_thread();; 12518 12519 return 0; 12520 } else { 12521 AST_LIST_UNLOCK(&users); 12522 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12523 return 0; 12524 } 12525 }
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 4783 of file app_voicemail_odbcstorage.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().
04784 { 04785 char tmpdir[256], newtmp[256]; 04786 char fname[256]; 04787 char tmpcmd[256]; 04788 int tmpfd = -1; 04789 int soxstatus = 0; 04790 04791 /* Eww. We want formats to tell us their own MIME type */ 04792 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04793 04794 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04795 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04796 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04797 tmpfd = mkstemp(newtmp); 04798 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04799 ast_debug(3, "newtmp: %s\n", newtmp); 04800 if (tmpfd > -1) { 04801 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04802 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04803 attach = newtmp; 04804 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04805 } else { 04806 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04807 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04808 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04809 } 04810 } 04811 } 04812 fprintf(p, "--%s" ENDL, bound); 04813 if (msgnum > -1) 04814 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04815 else 04816 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04817 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04818 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04819 if (msgnum > -1) 04820 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04821 else 04822 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04823 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04824 base_encode(fname, p); 04825 if (last) 04826 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04827 if (tmpfd > -1) { 04828 if (soxstatus == 0) { 04829 unlink(fname); 04830 } 04831 close(tmpfd); 04832 unlink(newtmp); 04833 } 04834 return 0; 04835 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6389 of file app_voicemail_odbcstorage.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().
06390 { 06391 int x; 06392 if (!ast_adsi_available(chan)) 06393 return; 06394 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06395 if (x < 0) 06396 return; 06397 if (!x) { 06398 if (adsi_load_vmail(chan, useadsi)) { 06399 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06400 return; 06401 } 06402 } else 06403 *useadsi = 1; 06404 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6584 of file app_voicemail_odbcstorage.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().
06585 { 06586 int bytes = 0; 06587 unsigned char buf[256]; 06588 unsigned char keys[8]; 06589 06590 int x; 06591 06592 if (!ast_adsi_available(chan)) 06593 return; 06594 06595 /* New meaning for keys */ 06596 for (x = 0; x < 5; x++) 06597 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06598 06599 keys[6] = 0x0; 06600 keys[7] = 0x0; 06601 06602 if (!vms->curmsg) { 06603 /* No prev key, provide "Folder" instead */ 06604 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06605 } 06606 if (vms->curmsg >= vms->lastmsg) { 06607 /* If last message ... */ 06608 if (vms->curmsg) { 06609 /* but not only message, provide "Folder" instead */ 06610 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06611 } else { 06612 /* Otherwise if only message, leave blank */ 06613 keys[3] = 1; 06614 } 06615 } 06616 06617 /* If deleted, show "undeleted" */ 06618 #ifdef IMAP_STORAGE 06619 ast_mutex_lock(&vms->lock); 06620 #endif 06621 if (vms->deleted[vms->curmsg]) { 06622 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06623 } 06624 #ifdef IMAP_STORAGE 06625 ast_mutex_unlock(&vms->lock); 06626 #endif 06627 06628 /* Except "Exit" */ 06629 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06630 bytes += ast_adsi_set_keys(buf + bytes, keys); 06631 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06632 06633 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06634 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6454 of file app_voicemail_odbcstorage.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().
06455 { 06456 unsigned char buf[256]; 06457 int bytes = 0; 06458 unsigned char keys[8]; 06459 int x, y; 06460 06461 if (!ast_adsi_available(chan)) 06462 return; 06463 06464 for (x = 0; x < 5; x++) { 06465 y = ADSI_KEY_APPS + 12 + start + x; 06466 if (y > ADSI_KEY_APPS + 12 + 4) 06467 y = 0; 06468 keys[x] = ADSI_KEY_SKT | y; 06469 } 06470 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06471 keys[6] = 0; 06472 keys[7] = 0; 06473 06474 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06475 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06476 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06477 bytes += ast_adsi_set_keys(buf + bytes, keys); 06478 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06479 06480 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06481 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6739 of file app_voicemail_odbcstorage.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().
06740 { 06741 unsigned char buf[256]; 06742 int bytes = 0; 06743 06744 if (!ast_adsi_available(chan)) 06745 return; 06746 bytes += adsi_logo(buf + bytes); 06747 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06748 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06749 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06750 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06751 06752 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06753 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6260 of file app_voicemail_odbcstorage.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().
06261 { 06262 unsigned char buf[256]; 06263 int bytes = 0; 06264 int x; 06265 char num[5]; 06266 06267 *useadsi = 0; 06268 bytes += ast_adsi_data_mode(buf + bytes); 06269 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06270 06271 bytes = 0; 06272 bytes += adsi_logo(buf); 06273 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06274 #ifdef DISPLAY 06275 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06276 #endif 06277 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06278 bytes += ast_adsi_data_mode(buf + bytes); 06279 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06280 06281 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06282 bytes = 0; 06283 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06284 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06285 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06286 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06287 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06288 return 0; 06289 } 06290 06291 #ifdef DISPLAY 06292 /* Add a dot */ 06293 bytes = 0; 06294 bytes += ast_adsi_logo(buf); 06295 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06296 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06297 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06298 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06299 #endif 06300 bytes = 0; 06301 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06302 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06303 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06304 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06305 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06306 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06307 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06308 06309 #ifdef DISPLAY 06310 /* Add another dot */ 06311 bytes = 0; 06312 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06313 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06314 06315 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06316 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06317 #endif 06318 06319 bytes = 0; 06320 /* These buttons we load but don't use yet */ 06321 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06322 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06323 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06324 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06325 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06326 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06327 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06328 06329 #ifdef DISPLAY 06330 /* Add another dot */ 06331 bytes = 0; 06332 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06333 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06334 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06335 #endif 06336 06337 bytes = 0; 06338 for (x = 0; x < 5; x++) { 06339 snprintf(num, sizeof(num), "%d", x); 06340 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06341 } 06342 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06343 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06344 06345 #ifdef DISPLAY 06346 /* Add another dot */ 06347 bytes = 0; 06348 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06349 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06350 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06351 #endif 06352 06353 if (ast_adsi_end_download(chan)) { 06354 bytes = 0; 06355 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06356 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06357 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06358 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06359 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06360 return 0; 06361 } 06362 bytes = 0; 06363 bytes += ast_adsi_download_disconnect(buf + bytes); 06364 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06365 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06366 06367 ast_debug(1, "Done downloading scripts...\n"); 06368 06369 #ifdef DISPLAY 06370 /* Add last dot */ 06371 bytes = 0; 06372 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06373 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06374 #endif 06375 ast_debug(1, "Restarting session...\n"); 06376 06377 bytes = 0; 06378 /* Load the session now */ 06379 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06380 *useadsi = 1; 06381 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06382 } else 06383 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06384 06385 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06386 return 0; 06387 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6406 of file app_voicemail_odbcstorage.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().
06407 { 06408 unsigned char buf[256]; 06409 int bytes = 0; 06410 unsigned char keys[8]; 06411 int x; 06412 if (!ast_adsi_available(chan)) 06413 return; 06414 06415 for (x = 0; x < 8; x++) 06416 keys[x] = 0; 06417 /* Set one key for next */ 06418 keys[3] = ADSI_KEY_APPS + 3; 06419 06420 bytes += adsi_logo(buf + bytes); 06421 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06422 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06423 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06424 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06425 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06426 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06427 bytes += ast_adsi_set_keys(buf + bytes, keys); 06428 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06429 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06430 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6252 of file app_voicemail_odbcstorage.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().
06253 { 06254 int bytes = 0; 06255 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06256 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06257 return bytes; 06258 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6483 of file app_voicemail_odbcstorage.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().
06484 { 06485 int bytes = 0; 06486 unsigned char buf[256]; 06487 char buf1[256], buf2[256]; 06488 char fn2[PATH_MAX]; 06489 06490 char cid[256] = ""; 06491 char *val; 06492 char *name, *num; 06493 char datetime[21] = ""; 06494 FILE *f; 06495 06496 unsigned char keys[8]; 06497 06498 int x; 06499 06500 if (!ast_adsi_available(chan)) 06501 return; 06502 06503 /* Retrieve important info */ 06504 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06505 f = fopen(fn2, "r"); 06506 if (f) { 06507 while (!feof(f)) { 06508 if (!fgets((char *) buf, sizeof(buf), f)) { 06509 continue; 06510 } 06511 if (!feof(f)) { 06512 char *stringp = NULL; 06513 stringp = (char *) buf; 06514 strsep(&stringp, "="); 06515 val = strsep(&stringp, "="); 06516 if (!ast_strlen_zero(val)) { 06517 if (!strcmp((char *) buf, "callerid")) 06518 ast_copy_string(cid, val, sizeof(cid)); 06519 if (!strcmp((char *) buf, "origdate")) 06520 ast_copy_string(datetime, val, sizeof(datetime)); 06521 } 06522 } 06523 } 06524 fclose(f); 06525 } 06526 /* New meaning for keys */ 06527 for (x = 0; x < 5; x++) 06528 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06529 keys[6] = 0x0; 06530 keys[7] = 0x0; 06531 06532 if (!vms->curmsg) { 06533 /* No prev key, provide "Folder" instead */ 06534 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06535 } 06536 if (vms->curmsg >= vms->lastmsg) { 06537 /* If last message ... */ 06538 if (vms->curmsg) { 06539 /* but not only message, provide "Folder" instead */ 06540 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06541 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06542 06543 } else { 06544 /* Otherwise if only message, leave blank */ 06545 keys[3] = 1; 06546 } 06547 } 06548 06549 if (!ast_strlen_zero(cid)) { 06550 ast_callerid_parse(cid, &name, &num); 06551 if (!name) 06552 name = num; 06553 } else 06554 name = "Unknown Caller"; 06555 06556 /* If deleted, show "undeleted" */ 06557 #ifdef IMAP_STORAGE 06558 ast_mutex_lock(&vms->lock); 06559 #endif 06560 if (vms->deleted[vms->curmsg]) { 06561 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06562 } 06563 #ifdef IMAP_STORAGE 06564 ast_mutex_unlock(&vms->lock); 06565 #endif 06566 06567 /* Except "Exit" */ 06568 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06569 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06570 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06571 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06572 06573 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06574 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06575 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06576 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06577 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06578 bytes += ast_adsi_set_keys(buf + bytes, keys); 06579 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06580 06581 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06582 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6432 of file app_voicemail_odbcstorage.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().
06433 { 06434 unsigned char buf[256]; 06435 int bytes = 0; 06436 unsigned char keys[8]; 06437 int x; 06438 if (!ast_adsi_available(chan)) 06439 return; 06440 06441 for (x = 0; x < 8; x++) 06442 keys[x] = 0; 06443 /* Set one key for next */ 06444 keys[3] = ADSI_KEY_APPS + 3; 06445 06446 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06447 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06448 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06449 bytes += ast_adsi_set_keys(buf + bytes, keys); 06450 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06451 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06452 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6636 of file app_voicemail_odbcstorage.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().
06637 { 06638 unsigned char buf[256] = ""; 06639 char buf1[256] = "", buf2[256] = ""; 06640 int bytes = 0; 06641 unsigned char keys[8]; 06642 int x; 06643 06644 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06645 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06646 if (!ast_adsi_available(chan)) 06647 return; 06648 if (vms->newmessages) { 06649 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06650 if (vms->oldmessages) { 06651 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06652 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06653 } else { 06654 snprintf(buf2, sizeof(buf2), "%s.", newm); 06655 } 06656 } else if (vms->oldmessages) { 06657 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06658 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06659 } else { 06660 strcpy(buf1, "You have no messages."); 06661 buf2[0] = ' '; 06662 buf2[1] = '\0'; 06663 } 06664 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06665 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06666 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06667 06668 for (x = 0; x < 6; x++) 06669 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06670 keys[6] = 0; 06671 keys[7] = 0; 06672 06673 /* Don't let them listen if there are none */ 06674 if (vms->lastmsg < 0) 06675 keys[0] = 1; 06676 bytes += ast_adsi_set_keys(buf + bytes, keys); 06677 06678 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06679 06680 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06681 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6683 of file app_voicemail_odbcstorage.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().
06684 { 06685 unsigned char buf[256] = ""; 06686 char buf1[256] = "", buf2[256] = ""; 06687 int bytes = 0; 06688 unsigned char keys[8]; 06689 int x; 06690 06691 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06692 06693 if (!ast_adsi_available(chan)) 06694 return; 06695 06696 /* Original command keys */ 06697 for (x = 0; x < 6; x++) 06698 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06699 06700 keys[6] = 0; 06701 keys[7] = 0; 06702 06703 if ((vms->lastmsg + 1) < 1) 06704 keys[0] = 0; 06705 06706 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06707 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06708 06709 if (vms->lastmsg + 1) 06710 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06711 else 06712 strcpy(buf2, "no messages."); 06713 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06714 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06715 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06716 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06717 bytes += ast_adsi_set_keys(buf + bytes, keys); 06718 06719 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06720 06721 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06722 06723 }
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 13232 of file app_voicemail_odbcstorage.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
13233 { 13234 int res = 0; 13235 char filename[PATH_MAX]; 13236 struct ast_config *msg_cfg = NULL; 13237 const char *origtime, *context; 13238 char *name, *num; 13239 int retries = 0; 13240 char *cid; 13241 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13242 13243 vms->starting = 0; 13244 13245 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13246 13247 /* Retrieve info from VM attribute file */ 13248 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13249 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13250 msg_cfg = ast_config_load(filename, config_flags); 13251 DISPOSE(vms->curdir, vms->curmsg); 13252 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13253 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13254 return 0; 13255 } 13256 13257 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13258 ast_config_destroy(msg_cfg); 13259 return 0; 13260 } 13261 13262 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13263 13264 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13265 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13266 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13267 switch (option) { 13268 case 3: /* Play message envelope */ 13269 if (!res) 13270 res = play_message_datetime(chan, vmu, origtime, filename); 13271 if (!res) 13272 res = play_message_callerid(chan, vms, cid, context, 0); 13273 13274 res = 't'; 13275 break; 13276 13277 case 2: /* Call back */ 13278 13279 if (ast_strlen_zero(cid)) 13280 break; 13281 13282 ast_callerid_parse(cid, &name, &num); 13283 while ((res > -1) && (res != 't')) { 13284 switch (res) { 13285 case '1': 13286 if (num) { 13287 /* Dial the CID number */ 13288 res = dialout(chan, vmu, num, vmu->callback); 13289 if (res) { 13290 ast_config_destroy(msg_cfg); 13291 return 9; 13292 } 13293 } else { 13294 res = '2'; 13295 } 13296 break; 13297 13298 case '2': 13299 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13300 if (!ast_strlen_zero(vmu->dialout)) { 13301 res = dialout(chan, vmu, NULL, vmu->dialout); 13302 if (res) { 13303 ast_config_destroy(msg_cfg); 13304 return 9; 13305 } 13306 } else { 13307 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13308 res = ast_play_and_wait(chan, "vm-sorry"); 13309 } 13310 ast_config_destroy(msg_cfg); 13311 return res; 13312 case '*': 13313 res = 't'; 13314 break; 13315 case '3': 13316 case '4': 13317 case '5': 13318 case '6': 13319 case '7': 13320 case '8': 13321 case '9': 13322 case '0': 13323 13324 res = ast_play_and_wait(chan, "vm-sorry"); 13325 retries++; 13326 break; 13327 default: 13328 if (num) { 13329 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13330 res = ast_play_and_wait(chan, "vm-num-i-have"); 13331 if (!res) 13332 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13333 if (!res) 13334 res = ast_play_and_wait(chan, "vm-tocallnum"); 13335 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13336 if (!ast_strlen_zero(vmu->dialout)) { 13337 if (!res) 13338 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13339 } 13340 } else { 13341 res = ast_play_and_wait(chan, "vm-nonumber"); 13342 if (!ast_strlen_zero(vmu->dialout)) { 13343 if (!res) 13344 res = ast_play_and_wait(chan, "vm-toenternumber"); 13345 } 13346 } 13347 if (!res) { 13348 res = ast_play_and_wait(chan, "vm-star-cancel"); 13349 } 13350 if (!res) { 13351 res = ast_waitfordigit(chan, 6000); 13352 } 13353 if (!res) { 13354 retries++; 13355 if (retries > 3) { 13356 res = 't'; 13357 } 13358 } 13359 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13360 break; 13361 13362 } 13363 if (res == 't') 13364 res = 0; 13365 else if (res == '*') 13366 res = -1; 13367 } 13368 break; 13369 13370 case 1: /* Reply */ 13371 /* Send reply directly to sender */ 13372 if (ast_strlen_zero(cid)) 13373 break; 13374 13375 ast_callerid_parse(cid, &name, &num); 13376 if (!num) { 13377 ast_verb(3, "No CID number available, no reply sent\n"); 13378 if (!res) 13379 res = ast_play_and_wait(chan, "vm-nonumber"); 13380 ast_config_destroy(msg_cfg); 13381 return res; 13382 } else { 13383 struct ast_vm_user vmu2; 13384 if (find_user(&vmu2, vmu->context, num)) { 13385 struct leave_vm_options leave_options; 13386 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13387 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13388 13389 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13390 13391 memset(&leave_options, 0, sizeof(leave_options)); 13392 leave_options.record_gain = record_gain; 13393 res = leave_voicemail(chan, mailbox, &leave_options); 13394 if (!res) 13395 res = 't'; 13396 ast_config_destroy(msg_cfg); 13397 return res; 13398 } else { 13399 /* Sender has no mailbox, can't reply */ 13400 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13401 ast_play_and_wait(chan, "vm-nobox"); 13402 res = 't'; 13403 ast_config_destroy(msg_cfg); 13404 return res; 13405 } 13406 } 13407 res = 0; 13408 13409 break; 13410 } 13411 13412 #ifndef IMAP_STORAGE 13413 ast_config_destroy(msg_cfg); 13414 13415 if (!res) { 13416 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13417 vms->heard[msg] = 1; 13418 res = wait_file(chan, vms, vms->fn); 13419 } 13420 #endif 13421 return res; 13422 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10754 of file app_voicemail_odbcstorage.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().
10755 { 10756 /* Assumes lock is already held */ 10757 char *tmp; 10758 char *stringp; 10759 char *s; 10760 struct ast_vm_user *vmu; 10761 char *mailbox_full; 10762 int new = 0, old = 0, urgent = 0; 10763 char secretfn[PATH_MAX] = ""; 10764 10765 tmp = ast_strdupa(data); 10766 10767 if (!(vmu = find_or_create(context, box))) 10768 return -1; 10769 10770 populate_defaults(vmu); 10771 10772 stringp = tmp; 10773 if ((s = strsep(&stringp, ","))) { 10774 if (!ast_strlen_zero(s) && s[0] == '*') { 10775 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10776 "\n\tmust be reset in voicemail.conf.\n", box); 10777 } 10778 /* assign password regardless of validity to prevent NULL password from being assigned */ 10779 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10780 } 10781 if (stringp && (s = strsep(&stringp, ","))) { 10782 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10783 } 10784 if (stringp && (s = strsep(&stringp, ","))) { 10785 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10786 } 10787 if (stringp && (s = strsep(&stringp, ","))) { 10788 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10789 } 10790 if (stringp && (s = strsep(&stringp, ","))) { 10791 apply_options(vmu, s); 10792 } 10793 10794 switch (vmu->passwordlocation) { 10795 case OPT_PWLOC_SPOOLDIR: 10796 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10797 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10798 } 10799 10800 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10801 strcpy(mailbox_full, box); 10802 strcat(mailbox_full, "@"); 10803 strcat(mailbox_full, context); 10804 10805 inboxcount2(mailbox_full, &urgent, &new, &old); 10806 queue_mwi_event(mailbox_full, urgent, new, old); 10807 10808 return 0; 10809 }
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 1036 of file app_voicemail_odbcstorage.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().
01037 { 01038 int x; 01039 if (!strcasecmp(var, "attach")) { 01040 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01041 } else if (!strcasecmp(var, "attachfmt")) { 01042 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01043 } else if (!strcasecmp(var, "serveremail")) { 01044 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01045 } else if (!strcasecmp(var, "emailbody")) { 01046 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01047 } else if (!strcasecmp(var, "emailsubject")) { 01048 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01049 } else if (!strcasecmp(var, "language")) { 01050 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01051 } else if (!strcasecmp(var, "tz")) { 01052 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01053 } else if (!strcasecmp(var, "locale")) { 01054 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01055 #ifdef IMAP_STORAGE 01056 } else if (!strcasecmp(var, "imapuser")) { 01057 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01058 vmu->imapversion = imapversion; 01059 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01060 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01061 vmu->imapversion = imapversion; 01062 } else if (!strcasecmp(var, "imapfolder")) { 01063 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01064 } else if (!strcasecmp(var, "imapvmshareid")) { 01065 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01066 vmu->imapversion = imapversion; 01067 #endif 01068 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01069 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01070 } else if (!strcasecmp(var, "saycid")){ 01071 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01072 } else if (!strcasecmp(var, "sendvoicemail")){ 01073 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01074 } else if (!strcasecmp(var, "review")){ 01075 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01076 } else if (!strcasecmp(var, "tempgreetwarn")){ 01077 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01078 } else if (!strcasecmp(var, "messagewrap")){ 01079 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01080 } else if (!strcasecmp(var, "operator")) { 01081 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01082 } else if (!strcasecmp(var, "envelope")){ 01083 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01084 } else if (!strcasecmp(var, "moveheard")){ 01085 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01086 } else if (!strcasecmp(var, "sayduration")){ 01087 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01088 } else if (!strcasecmp(var, "saydurationm")){ 01089 if (sscanf(value, "%30d", &x) == 1) { 01090 vmu->saydurationm = x; 01091 } else { 01092 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01093 } 01094 } else if (!strcasecmp(var, "forcename")){ 01095 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01096 } else if (!strcasecmp(var, "forcegreetings")){ 01097 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01098 } else if (!strcasecmp(var, "callback")) { 01099 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01100 } else if (!strcasecmp(var, "dialout")) { 01101 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01102 } else if (!strcasecmp(var, "exitcontext")) { 01103 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01104 } else if (!strcasecmp(var, "minsecs")) { 01105 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01106 vmu->minsecs = x; 01107 } else { 01108 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01109 vmu->minsecs = vmminsecs; 01110 } 01111 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01112 vmu->maxsecs = atoi(value); 01113 if (vmu->maxsecs <= 0) { 01114 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01115 vmu->maxsecs = vmmaxsecs; 01116 } else { 01117 vmu->maxsecs = atoi(value); 01118 } 01119 if (!strcasecmp(var, "maxmessage")) 01120 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01121 } else if (!strcasecmp(var, "maxmsg")) { 01122 vmu->maxmsg = atoi(value); 01123 /* Accept maxmsg=0 (Greetings only voicemail) */ 01124 if (vmu->maxmsg < 0) { 01125 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01126 vmu->maxmsg = MAXMSG; 01127 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01128 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01129 vmu->maxmsg = MAXMSGLIMIT; 01130 } 01131 } else if (!strcasecmp(var, "nextaftercmd")) { 01132 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01133 } else if (!strcasecmp(var, "backupdeleted")) { 01134 if (sscanf(value, "%30d", &x) == 1) 01135 vmu->maxdeletedmsg = x; 01136 else if (ast_true(value)) 01137 vmu->maxdeletedmsg = MAXMSG; 01138 else 01139 vmu->maxdeletedmsg = 0; 01140 01141 if (vmu->maxdeletedmsg < 0) { 01142 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01143 vmu->maxdeletedmsg = MAXMSG; 01144 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01145 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01146 vmu->maxdeletedmsg = MAXMSGLIMIT; 01147 } 01148 } else if (!strcasecmp(var, "volgain")) { 01149 sscanf(value, "%30lf", &vmu->volgain); 01150 } else if (!strcasecmp(var, "passwordlocation")) { 01151 if (!strcasecmp(value, "spooldir")) { 01152 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01153 } else { 01154 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01155 } 01156 } else if (!strcasecmp(var, "options")) { 01157 apply_options(vmu, value); 01158 } 01159 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1277 of file app_voicemail_odbcstorage.c.
References apply_option(), ast_strdupa, value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01278 { 01279 char *stringp; 01280 char *s; 01281 char *var, *value; 01282 stringp = ast_strdupa(options); 01283 while ((s = strsep(&stringp, "|"))) { 01284 value = s; 01285 if ((var = strsep(&value, "=")) && value) { 01286 apply_option(vmu, var, value); 01287 } 01288 } 01289 }
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 1296 of file app_voicemail_odbcstorage.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().
01297 { 01298 for (; var; var = var->next) { 01299 if (!strcasecmp(var->name, "vmsecret")) { 01300 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01301 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01302 if (ast_strlen_zero(retval->password)) { 01303 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01304 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01305 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01306 } else { 01307 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01308 } 01309 } 01310 } else if (!strcasecmp(var->name, "uniqueid")) { 01311 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01312 } else if (!strcasecmp(var->name, "pager")) { 01313 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01314 } else if (!strcasecmp(var->name, "email")) { 01315 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01316 } else if (!strcasecmp(var->name, "fullname")) { 01317 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01318 } else if (!strcasecmp(var->name, "context")) { 01319 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01320 } else if (!strcasecmp(var->name, "emailsubject")) { 01321 ast_free(retval->emailsubject); 01322 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01323 } else if (!strcasecmp(var->name, "emailbody")) { 01324 ast_free(retval->emailbody); 01325 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01326 #ifdef IMAP_STORAGE 01327 } else if (!strcasecmp(var->name, "imapuser")) { 01328 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01329 retval->imapversion = imapversion; 01330 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01331 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01332 retval->imapversion = imapversion; 01333 } else if (!strcasecmp(var->name, "imapfolder")) { 01334 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01335 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01336 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01337 retval->imapversion = imapversion; 01338 #endif 01339 } else 01340 apply_option(retval, var->name, var->value); 01341 } 01342 }
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 4458 of file app_voicemail_odbcstorage.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().
04459 { 04460 struct ast_str *tmp = ast_str_alloca(80); 04461 int first_section = 1; 04462 04463 ast_str_reset(*end); 04464 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04465 for (; *start; start++) { 04466 int need_encoding = 0; 04467 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04468 need_encoding = 1; 04469 } 04470 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04471 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04472 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04473 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04474 /* Start new line */ 04475 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04476 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04477 first_section = 0; 04478 } 04479 if (need_encoding && *start == ' ') { 04480 ast_str_append(&tmp, -1, "_"); 04481 } else if (need_encoding) { 04482 ast_str_append(&tmp, -1, "=%hhX", *start); 04483 } else { 04484 ast_str_append(&tmp, -1, "%c", *start); 04485 } 04486 } 04487 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04488 return ast_str_buffer(*end); 04489 }
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 4386 of file app_voicemail_odbcstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), and sendpage().
04387 { 04388 const char *ptr; 04389 04390 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04391 ast_str_set(buf, maxlen, "\""); 04392 for (ptr = from; *ptr; ptr++) { 04393 if (*ptr == '"' || *ptr == '\\') { 04394 ast_str_append(buf, maxlen, "\\%c", *ptr); 04395 } else { 04396 ast_str_append(buf, maxlen, "%c", *ptr); 04397 } 04398 } 04399 ast_str_append(buf, maxlen, "\""); 04400 04401 return ast_str_buffer(*buf); 04402 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10811 of file app_voicemail_odbcstorage.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.
10812 { 10813 int res = 0; 10814 struct ast_vm_user *vmu; 10815 /* language parameter seems to only be used for display in manager action */ 10816 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10817 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10818 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10819 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10820 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10821 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10822 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10823 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10824 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10825 #ifdef IMAP_STORAGE 10826 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10827 "imapfolder=INBOX|imapvmshareid=6000"; 10828 #endif 10829 10830 switch (cmd) { 10831 case TEST_INIT: 10832 info->name = "vmuser"; 10833 info->category = "/apps/app_voicemail/"; 10834 info->summary = "Vmuser unit test"; 10835 info->description = 10836 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10837 return AST_TEST_NOT_RUN; 10838 case TEST_EXECUTE: 10839 break; 10840 } 10841 10842 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10843 return AST_TEST_NOT_RUN; 10844 } 10845 populate_defaults(vmu); 10846 ast_set_flag(vmu, VM_ALLOCED); 10847 10848 apply_options(vmu, options_string); 10849 10850 if (!ast_test_flag(vmu, VM_ATTACH)) { 10851 ast_test_status_update(test, "Parse failure for attach option\n"); 10852 res = 1; 10853 } 10854 if (strcasecmp(vmu->attachfmt, "wav49")) { 10855 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10856 res = 1; 10857 } 10858 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10859 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10860 res = 1; 10861 } 10862 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10863 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10864 res = 1; 10865 } 10866 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10867 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10868 res = 1; 10869 } 10870 if (strcasecmp(vmu->zonetag, "central")) { 10871 ast_test_status_update(test, "Parse failure for tz option\n"); 10872 res = 1; 10873 } 10874 if (!ast_test_flag(vmu, VM_DELETE)) { 10875 ast_test_status_update(test, "Parse failure for delete option\n"); 10876 res = 1; 10877 } 10878 if (!ast_test_flag(vmu, VM_SAYCID)) { 10879 ast_test_status_update(test, "Parse failure for saycid option\n"); 10880 res = 1; 10881 } 10882 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10883 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10884 res = 1; 10885 } 10886 if (!ast_test_flag(vmu, VM_REVIEW)) { 10887 ast_test_status_update(test, "Parse failure for review option\n"); 10888 res = 1; 10889 } 10890 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10891 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10892 res = 1; 10893 } 10894 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10895 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10896 res = 1; 10897 } 10898 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10899 ast_test_status_update(test, "Parse failure for operator option\n"); 10900 res = 1; 10901 } 10902 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10903 ast_test_status_update(test, "Parse failure for envelope option\n"); 10904 res = 1; 10905 } 10906 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10907 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10908 res = 1; 10909 } 10910 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10911 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10912 res = 1; 10913 } 10914 if (vmu->saydurationm != 5) { 10915 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10916 res = 1; 10917 } 10918 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10919 ast_test_status_update(test, "Parse failure for forcename option\n"); 10920 res = 1; 10921 } 10922 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10923 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10924 res = 1; 10925 } 10926 if (strcasecmp(vmu->callback, "somecontext")) { 10927 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10928 res = 1; 10929 } 10930 if (strcasecmp(vmu->dialout, "somecontext2")) { 10931 ast_test_status_update(test, "Parse failure for dialout option\n"); 10932 res = 1; 10933 } 10934 if (strcasecmp(vmu->exit, "somecontext3")) { 10935 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10936 res = 1; 10937 } 10938 if (vmu->minsecs != 10) { 10939 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10940 res = 1; 10941 } 10942 if (vmu->maxsecs != 100) { 10943 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10944 res = 1; 10945 } 10946 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10947 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10948 res = 1; 10949 } 10950 if (vmu->maxdeletedmsg != 50) { 10951 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10952 res = 1; 10953 } 10954 if (vmu->volgain != 1.3) { 10955 ast_test_status_update(test, "Parse failure for volgain option\n"); 10956 res = 1; 10957 } 10958 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10959 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10960 res = 1; 10961 } 10962 #ifdef IMAP_STORAGE 10963 apply_options(vmu, option_string2); 10964 10965 if (strcasecmp(vmu->imapuser, "imapuser")) { 10966 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10967 res = 1; 10968 } 10969 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10970 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10971 res = 1; 10972 } 10973 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10974 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 10975 res = 1; 10976 } 10977 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10978 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10979 res = 1; 10980 } 10981 #endif 10982 10983 free_user(vmu); 10984 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10985 }
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 4262 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
Referenced by add_email_attachment().
04263 { 04264 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04265 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04266 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04267 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04268 int i, hiteof = 0; 04269 FILE *fi; 04270 struct baseio bio; 04271 04272 memset(&bio, 0, sizeof(bio)); 04273 bio.iocp = BASEMAXINLINE; 04274 04275 if (!(fi = fopen(filename, "rb"))) { 04276 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04277 return -1; 04278 } 04279 04280 while (!hiteof){ 04281 unsigned char igroup[3], ogroup[4]; 04282 int c, n; 04283 04284 memset(igroup, 0, sizeof(igroup)); 04285 04286 for (n = 0; n < 3; n++) { 04287 if ((c = inchar(&bio, fi)) == EOF) { 04288 hiteof = 1; 04289 break; 04290 } 04291 04292 igroup[n] = (unsigned char) c; 04293 } 04294 04295 if (n > 0) { 04296 ogroup[0]= dtable[igroup[0] >> 2]; 04297 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04298 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04299 ogroup[3]= dtable[igroup[2] & 0x3F]; 04300 04301 if (n < 3) { 04302 ogroup[3] = '='; 04303 04304 if (n < 2) 04305 ogroup[2] = '='; 04306 } 04307 04308 for (i = 0; i < 4; i++) 04309 ochar(&bio, ogroup[i], so); 04310 } 04311 } 04312 04313 fclose(fi); 04314 04315 if (fputs(ENDL, so) == EOF) { 04316 return 0; 04317 } 04318 04319 return 1; 04320 }
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 1255 of file app_voicemail_odbcstorage.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().
01256 { 01257 int res = -1; 01258 if (!strcmp(vmu->password, password)) { 01259 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01260 return 0; 01261 } 01262 01263 if (strlen(password) > 10) { 01264 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01265 } 01266 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01267 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01268 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01269 res = 0; 01270 } 01271 return res; 01272 }
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 4431 of file app_voicemail_odbcstorage.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 1214 of file app_voicemail_odbcstorage.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().
01215 { 01216 /* check minimum length */ 01217 if (strlen(password) < minpassword) 01218 return 1; 01219 /* check that password does not contain '*' character */ 01220 if (!ast_strlen_zero(password) && password[0] == '*') 01221 return 1; 01222 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01223 char cmd[255], buf[255]; 01224 01225 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01226 01227 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01228 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01229 ast_debug(5, "Result: %s\n", buf); 01230 if (!strncasecmp(buf, "VALID", 5)) { 01231 ast_debug(3, "Passed password check: '%s'\n", buf); 01232 return 0; 01233 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01234 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01235 return 0; 01236 } else { 01237 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01238 return 1; 01239 } 01240 } 01241 } 01242 return 0; 01243 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7949 of file app_voicemail_odbcstorage.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().
07950 { 07951 int x = 0; 07952 int last_msg_idx = 0; 07953 07954 #ifndef IMAP_STORAGE 07955 int res = 0, nummsg; 07956 char fn2[PATH_MAX]; 07957 #endif 07958 07959 if (vms->lastmsg <= -1) { 07960 goto done; 07961 } 07962 07963 vms->curmsg = -1; 07964 #ifndef IMAP_STORAGE 07965 /* Get the deleted messages fixed */ 07966 if (vm_lock_path(vms->curdir)) { 07967 return ERROR_LOCK_PATH; 07968 } 07969 07970 /* update count as message may have arrived while we've got mailbox open */ 07971 last_msg_idx = last_message_index(vmu, vms->curdir); 07972 if (last_msg_idx != vms->lastmsg) { 07973 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07974 } 07975 07976 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07977 for (x = 0; x < last_msg_idx + 1; x++) { 07978 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07979 /* Save this message. It's not in INBOX or hasn't been heard */ 07980 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07981 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07982 break; 07983 } 07984 vms->curmsg++; 07985 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07986 if (strcmp(vms->fn, fn2)) { 07987 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07988 } 07989 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07990 /* Move to old folder before deleting */ 07991 res = save_to_folder(vmu, vms, x, 1); 07992 if (res == ERROR_LOCK_PATH) { 07993 /* If save failed do not delete the message */ 07994 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07995 vms->deleted[x] = 0; 07996 vms->heard[x] = 0; 07997 --x; 07998 } 07999 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08000 /* Move to deleted folder */ 08001 res = save_to_folder(vmu, vms, x, 10); 08002 if (res == ERROR_LOCK_PATH) { 08003 /* If save failed do not delete the message */ 08004 vms->deleted[x] = 0; 08005 vms->heard[x] = 0; 08006 --x; 08007 } 08008 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08009 /* If realtime storage enabled - we should explicitly delete this message, 08010 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08011 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08012 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08013 DELETE(vms->curdir, x, vms->fn, vmu); 08014 } 08015 } 08016 } 08017 08018 /* Delete ALL remaining messages */ 08019 nummsg = x - 1; 08020 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08021 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08022 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08023 DELETE(vms->curdir, x, vms->fn, vmu); 08024 } 08025 } 08026 ast_unlock_path(vms->curdir); 08027 #else /* defined(IMAP_STORAGE) */ 08028 ast_mutex_lock(&vms->lock); 08029 if (vms->deleted) { 08030 /* Since we now expunge after each delete, deleting in reverse order 08031 * ensures that no reordering occurs between each step. */ 08032 last_msg_idx = vms->dh_arraysize; 08033 for (x = last_msg_idx - 1; x >= 0; x--) { 08034 if (vms->deleted[x]) { 08035 ast_debug(3, "IMAP delete of %d\n", x); 08036 DELETE(vms->curdir, x, vms->fn, vmu); 08037 } 08038 } 08039 } 08040 #endif 08041 08042 done: 08043 if (vms->deleted) { 08044 ast_free(vms->deleted); 08045 vms->deleted = NULL; 08046 } 08047 if (vms->heard) { 08048 ast_free(vms->heard); 08049 vms->heard = NULL; 08050 } 08051 vms->dh_arraysize = 0; 08052 #ifdef IMAP_STORAGE 08053 ast_mutex_unlock(&vms->lock); 08054 #endif 08055 08056 return 0; 08057 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11131 of file app_voicemail_odbcstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11132 { 11133 int which = 0; 11134 int wordlen; 11135 struct ast_vm_user *vmu; 11136 const char *context = ""; 11137 11138 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11139 if (pos > 4) 11140 return NULL; 11141 if (pos == 3) 11142 return (state == 0) ? ast_strdup("for") : NULL; 11143 wordlen = strlen(word); 11144 AST_LIST_TRAVERSE(&users, vmu, list) { 11145 if (!strncasecmp(word, vmu->context, wordlen)) { 11146 if (context && strcmp(context, vmu->context) && ++which > state) 11147 return ast_strdup(vmu->context); 11148 /* ignore repeated contexts ? */ 11149 context = vmu->context; 11150 } 11151 } 11152 return NULL; 11153 }
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 4067 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by copy_plain_file(), and vm_forwardoptions().
04068 { 04069 int ifd; 04070 int ofd; 04071 int res; 04072 int len; 04073 char buf[4096]; 04074 04075 #ifdef HARDLINK_WHEN_POSSIBLE 04076 /* Hard link if possible; saves disk space & is faster */ 04077 if (link(infile, outfile)) { 04078 #endif 04079 if ((ifd = open(infile, O_RDONLY)) < 0) { 04080 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04081 return -1; 04082 } 04083 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04084 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04085 close(ifd); 04086 return -1; 04087 } 04088 do { 04089 len = read(ifd, buf, sizeof(buf)); 04090 if (len < 0) { 04091 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04092 close(ifd); 04093 close(ofd); 04094 unlink(outfile); 04095 } else if (len) { 04096 res = write(ofd, buf, len); 04097 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04098 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04099 close(ifd); 04100 close(ofd); 04101 unlink(outfile); 04102 } 04103 } 04104 } while (len); 04105 close(ifd); 04106 close(ofd); 04107 return 0; 04108 #ifdef HARDLINK_WHEN_POSSIBLE 04109 } else { 04110 /* Hard link succeeded */ 04111 return 0; 04112 } 04113 #endif 04114 }
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 5303 of file app_voicemail_odbcstorage.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().
05304 { 05305 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05306 const char *frombox = mbox(vmu, imbox); 05307 const char *userfolder; 05308 int recipmsgnum; 05309 int res = 0; 05310 05311 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05312 05313 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05314 userfolder = "Urgent"; 05315 } else { 05316 userfolder = "INBOX"; 05317 } 05318 05319 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05320 05321 if (!dir) 05322 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05323 else 05324 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05325 05326 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05327 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05328 05329 if (vm_lock_path(todir)) 05330 return ERROR_LOCK_PATH; 05331 05332 recipmsgnum = last_message_index(recip, todir) + 1; 05333 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05334 make_file(topath, sizeof(topath), todir, recipmsgnum); 05335 #ifndef ODBC_STORAGE 05336 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05337 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05338 } else { 05339 #endif 05340 /* If we are prepending a message for ODBC, then the message already 05341 * exists in the database, but we want to force copying from the 05342 * filesystem (since only the FS contains the prepend). */ 05343 copy_plain_file(frompath, topath); 05344 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05345 vm_delete(topath); 05346 #ifndef ODBC_STORAGE 05347 } 05348 #endif 05349 } else { 05350 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05351 res = -1; 05352 } 05353 ast_unlock_path(todir); 05354 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05355 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05356 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05357 flag); 05358 05359 return res; 05360 }
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 4125 of file app_voicemail_odbcstorage.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().
04126 { 04127 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04128 struct ast_variable *tmp,*var = NULL; 04129 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04130 ast_filecopy(frompath, topath, NULL); 04131 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04132 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04133 if (ast_check_realtime("voicemail_data")) { 04134 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04135 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04136 for (tmp = var; tmp; tmp = tmp->next) { 04137 if (!strcasecmp(tmp->name, "origmailbox")) { 04138 origmailbox = tmp->value; 04139 } else if (!strcasecmp(tmp->name, "context")) { 04140 context = tmp->value; 04141 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04142 macrocontext = tmp->value; 04143 } else if (!strcasecmp(tmp->name, "exten")) { 04144 exten = tmp->value; 04145 } else if (!strcasecmp(tmp->name, "priority")) { 04146 priority = tmp->value; 04147 } else if (!strcasecmp(tmp->name, "callerchan")) { 04148 callerchan = tmp->value; 04149 } else if (!strcasecmp(tmp->name, "callerid")) { 04150 callerid = tmp->value; 04151 } else if (!strcasecmp(tmp->name, "origdate")) { 04152 origdate = tmp->value; 04153 } else if (!strcasecmp(tmp->name, "origtime")) { 04154 origtime = tmp->value; 04155 } else if (!strcasecmp(tmp->name, "category")) { 04156 category = tmp->value; 04157 } else if (!strcasecmp(tmp->name, "duration")) { 04158 duration = tmp->value; 04159 } 04160 } 04161 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); 04162 } 04163 copy(frompath2, topath2); 04164 ast_variables_destroy(var); 04165 }
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 3962 of file app_voicemail_odbcstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().
03963 { 03964 03965 int vmcount = 0; 03966 DIR *vmdir = NULL; 03967 struct dirent *vment = NULL; 03968 03969 if (vm_lock_path(dir)) 03970 return ERROR_LOCK_PATH; 03971 03972 if ((vmdir = opendir(dir))) { 03973 while ((vment = readdir(vmdir))) { 03974 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03975 vmcount++; 03976 } 03977 } 03978 closedir(vmdir); 03979 } 03980 ast_unlock_path(dir); 03981 03982 return vmcount; 03983 }
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 1665 of file app_voicemail_odbcstorage.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().
01666 { 01667 mode_t mode = VOICEMAIL_DIR_MODE; 01668 int res; 01669 01670 make_dir(dest, len, context, ext, folder); 01671 if ((res = ast_mkdir(dest, mode))) { 01672 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01673 return -1; 01674 } 01675 return 0; 01676 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13159 of file app_voicemail_odbcstorage.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().
13160 { 13161 int cmd = 0; 13162 char destination[80] = ""; 13163 int retries = 0; 13164 13165 if (!num) { 13166 ast_verb(3, "Destination number will be entered manually\n"); 13167 while (retries < 3 && cmd != 't') { 13168 destination[1] = '\0'; 13169 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13170 if (!cmd) 13171 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13172 if (!cmd) 13173 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13174 if (!cmd) { 13175 cmd = ast_waitfordigit(chan, 6000); 13176 if (cmd) 13177 destination[0] = cmd; 13178 } 13179 if (!cmd) { 13180 retries++; 13181 } else { 13182 13183 if (cmd < 0) 13184 return 0; 13185 if (cmd == '*') { 13186 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13187 return 0; 13188 } 13189 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13190 retries++; 13191 else 13192 cmd = 't'; 13193 } 13194 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13195 } 13196 if (retries >= 3) { 13197 return 0; 13198 } 13199 13200 } else { 13201 if (option_verbose > 2) 13202 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13203 ast_copy_string(destination, num, sizeof(destination)); 13204 } 13205 13206 if (!ast_strlen_zero(destination)) { 13207 if (destination[strlen(destination) -1 ] == '*') 13208 return 0; 13209 if (option_verbose > 2) 13210 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13211 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13212 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13213 chan->priority = 0; 13214 return 9; 13215 } 13216 return 0; 13217 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10714 of file app_voicemail_odbcstorage.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().
10715 { 10716 struct ast_vm_user *vmu; 10717 10718 if (!ast_strlen_zero(box) && box[0] == '*') { 10719 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10720 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10721 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10722 "\n\tand will be ignored.\n", box, context); 10723 return NULL; 10724 } 10725 10726 AST_LIST_TRAVERSE(&users, vmu, list) { 10727 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10728 if (strcasecmp(vmu->context, context)) { 10729 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10730 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10731 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10732 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10733 } 10734 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10735 return NULL; 10736 } 10737 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10738 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10739 return NULL; 10740 } 10741 } 10742 10743 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10744 return NULL; 10745 10746 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10747 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10748 10749 AST_LIST_INSERT_TAIL(&users, vmu, list); 10750 10751 return vmu; 10752 }
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 1417 of file app_voicemail_odbcstorage.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().
01418 { 01419 /* This function could be made to generate one from a database, too */ 01420 struct ast_vm_user *vmu = NULL, *cur; 01421 AST_LIST_LOCK(&users); 01422 01423 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01424 context = "default"; 01425 01426 AST_LIST_TRAVERSE(&users, cur, list) { 01427 #ifdef IMAP_STORAGE 01428 if (cur->imapversion != imapversion) { 01429 continue; 01430 } 01431 #endif 01432 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01433 break; 01434 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01435 break; 01436 } 01437 if (cur) { 01438 /* Make a copy, so that on a reload, we have no race */ 01439 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01440 *vmu = *cur; 01441 if (!ivm) { 01442 vmu->emailbody = ast_strdup(cur->emailbody); 01443 vmu->emailsubject = ast_strdup(cur->emailsubject); 01444 } 01445 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01446 AST_LIST_NEXT(vmu, list) = NULL; 01447 } 01448 } else 01449 vmu = find_user_realtime(ivm, context, mailbox); 01450 AST_LIST_UNLOCK(&users); 01451 return vmu; 01452 }
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 1376 of file app_voicemail_odbcstorage.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().
01377 { 01378 struct ast_variable *var; 01379 struct ast_vm_user *retval; 01380 01381 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01382 if (ivm) { 01383 memset(retval, 0, sizeof(*retval)); 01384 } 01385 populate_defaults(retval); 01386 if (!ivm) { 01387 ast_set_flag(retval, VM_ALLOCED); 01388 } 01389 if (mailbox) { 01390 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01391 } 01392 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01393 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01394 } else { 01395 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01396 } 01397 if (var) { 01398 apply_options_full(retval, var); 01399 ast_variables_destroy(var); 01400 } else { 01401 if (!ivm) 01402 free_user(retval); 01403 retval = NULL; 01404 } 01405 } 01406 return retval; 01407 }
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 7150 of file app_voicemail_odbcstorage.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().
07151 { 07152 #ifdef IMAP_STORAGE 07153 int todircount = 0; 07154 struct vm_state *dstvms; 07155 #endif 07156 char username[70]=""; 07157 char fn[PATH_MAX]; /* for playback of name greeting */ 07158 char ecodes[16] = "#"; 07159 int res = 0, cmd = 0; 07160 struct ast_vm_user *receiver = NULL, *vmtmp; 07161 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07162 char *stringp; 07163 const char *s; 07164 int saved_messages = 0; 07165 int valid_extensions = 0; 07166 char *dir; 07167 int curmsg; 07168 char urgent_str[7] = ""; 07169 int prompt_played = 0; 07170 #ifndef IMAP_STORAGE 07171 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07172 #endif 07173 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07174 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07175 } 07176 07177 if (vms == NULL) return -1; 07178 dir = vms->curdir; 07179 curmsg = vms->curmsg; 07180 07181 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07182 while (!res && !valid_extensions) { 07183 int use_directory = 0; 07184 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07185 int done = 0; 07186 int retries = 0; 07187 cmd = 0; 07188 while ((cmd >= 0) && !done ){ 07189 if (cmd) 07190 retries = 0; 07191 switch (cmd) { 07192 case '1': 07193 use_directory = 0; 07194 done = 1; 07195 break; 07196 case '2': 07197 use_directory = 1; 07198 done = 1; 07199 break; 07200 case '*': 07201 cmd = 't'; 07202 done = 1; 07203 break; 07204 default: 07205 /* Press 1 to enter an extension press 2 to use the directory */ 07206 cmd = ast_play_and_wait(chan, "vm-forward"); 07207 if (!cmd) { 07208 cmd = ast_waitfordigit(chan, 3000); 07209 } 07210 if (!cmd) { 07211 retries++; 07212 } 07213 if (retries > 3) { 07214 cmd = 't'; 07215 done = 1; 07216 } 07217 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07218 } 07219 } 07220 if (cmd < 0 || cmd == 't') 07221 break; 07222 } 07223 07224 if (use_directory) { 07225 /* use app_directory */ 07226 07227 char old_context[sizeof(chan->context)]; 07228 char old_exten[sizeof(chan->exten)]; 07229 int old_priority; 07230 struct ast_app* directory_app; 07231 07232 directory_app = pbx_findapp("Directory"); 07233 if (directory_app) { 07234 char vmcontext[256]; 07235 /* make backup copies */ 07236 memcpy(old_context, chan->context, sizeof(chan->context)); 07237 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07238 old_priority = chan->priority; 07239 07240 /* call the the Directory, changes the channel */ 07241 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07242 res = pbx_exec(chan, directory_app, vmcontext); 07243 07244 ast_copy_string(username, chan->exten, sizeof(username)); 07245 07246 /* restore the old context, exten, and priority */ 07247 memcpy(chan->context, old_context, sizeof(chan->context)); 07248 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07249 chan->priority = old_priority; 07250 } else { 07251 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07252 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07253 } 07254 } else { 07255 /* Ask for an extension */ 07256 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07257 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07258 prompt_played++; 07259 if (res || prompt_played > 4) 07260 break; 07261 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07262 break; 07263 } 07264 07265 /* start all over if no username */ 07266 if (ast_strlen_zero(username)) 07267 continue; 07268 stringp = username; 07269 s = strsep(&stringp, "*"); 07270 /* start optimistic */ 07271 valid_extensions = 1; 07272 while (s) { 07273 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07274 int oldmsgs; 07275 int newmsgs; 07276 int capacity; 07277 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07278 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07279 /* Shouldn't happen, but allow trying another extension if it does */ 07280 res = ast_play_and_wait(chan, "pbx-invalid"); 07281 valid_extensions = 0; 07282 break; 07283 } 07284 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07285 if ((newmsgs + oldmsgs) >= capacity) { 07286 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07287 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07288 valid_extensions = 0; 07289 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07290 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07291 free_user(vmtmp); 07292 } 07293 inprocess_count(receiver->mailbox, receiver->context, -1); 07294 break; 07295 } 07296 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07297 } else { 07298 /* XXX Optimization for the future. When we encounter a single bad extension, 07299 * bailing out on all of the extensions may not be the way to go. We should 07300 * probably just bail on that single extension, then allow the user to enter 07301 * several more. XXX 07302 */ 07303 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07304 free_user(receiver); 07305 } 07306 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07307 /* "I am sorry, that's not a valid extension. Please try again." */ 07308 res = ast_play_and_wait(chan, "pbx-invalid"); 07309 valid_extensions = 0; 07310 break; 07311 } 07312 07313 /* play name if available, else play extension number */ 07314 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07315 RETRIEVE(fn, -1, s, receiver->context); 07316 if (ast_fileexists(fn, NULL, NULL) > 0) { 07317 res = ast_stream_and_wait(chan, fn, ecodes); 07318 if (res) { 07319 DISPOSE(fn, -1); 07320 return res; 07321 } 07322 } else { 07323 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07324 } 07325 DISPOSE(fn, -1); 07326 07327 s = strsep(&stringp, "*"); 07328 } 07329 /* break from the loop of reading the extensions */ 07330 if (valid_extensions) 07331 break; 07332 } 07333 /* check if we're clear to proceed */ 07334 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07335 return res; 07336 if (is_new_message == 1) { 07337 struct leave_vm_options leave_options; 07338 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07339 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07340 07341 /* Send VoiceMail */ 07342 memset(&leave_options, 0, sizeof(leave_options)); 07343 leave_options.record_gain = record_gain; 07344 cmd = leave_voicemail(chan, mailbox, &leave_options); 07345 } else { 07346 /* Forward VoiceMail */ 07347 long duration = 0; 07348 struct vm_state vmstmp; 07349 int copy_msg_result = 0; 07350 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07351 07352 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07353 07354 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07355 if (!cmd) { 07356 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07357 #ifdef IMAP_STORAGE 07358 int attach_user_voicemail; 07359 char *myserveremail = serveremail; 07360 07361 /* get destination mailbox */ 07362 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07363 if (!dstvms) { 07364 dstvms = create_vm_state_from_user(vmtmp); 07365 } 07366 if (dstvms) { 07367 init_mailstream(dstvms, 0); 07368 if (!dstvms->mailstream) { 07369 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07370 } else { 07371 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07372 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07373 } 07374 } else { 07375 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07376 } 07377 if (!ast_strlen_zero(vmtmp->serveremail)) 07378 myserveremail = vmtmp->serveremail; 07379 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07380 /* NULL category for IMAP storage */ 07381 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07382 dstvms->curbox, 07383 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07384 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07385 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07386 NULL, urgent_str); 07387 #else 07388 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07389 #endif 07390 saved_messages++; 07391 AST_LIST_REMOVE_CURRENT(list); 07392 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07393 free_user(vmtmp); 07394 if (res) 07395 break; 07396 } 07397 AST_LIST_TRAVERSE_SAFE_END; 07398 if (saved_messages > 0 && !copy_msg_result) { 07399 /* give confirmation that the message was saved */ 07400 /* commented out since we can't forward batches yet 07401 if (saved_messages == 1) 07402 res = ast_play_and_wait(chan, "vm-message"); 07403 else 07404 res = ast_play_and_wait(chan, "vm-messages"); 07405 if (!res) 07406 res = ast_play_and_wait(chan, "vm-saved"); */ 07407 #ifdef IMAP_STORAGE 07408 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07409 if (ast_strlen_zero(vmstmp.introfn)) 07410 #endif 07411 res = ast_play_and_wait(chan, "vm-msgsaved"); 07412 } 07413 #ifndef IMAP_STORAGE 07414 else { 07415 /* with IMAP, mailbox full warning played by imap_check_limits */ 07416 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07417 } 07418 /* Restore original message without prepended message if backup exists */ 07419 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07420 strcpy(textfile, msgfile); 07421 strcpy(backup, msgfile); 07422 strcpy(backup_textfile, msgfile); 07423 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07424 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07425 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07426 if (ast_fileexists(backup, NULL, NULL) > 0) { 07427 ast_filerename(backup, msgfile, NULL); 07428 rename(backup_textfile, textfile); 07429 } 07430 #endif 07431 } 07432 DISPOSE(dir, curmsg); 07433 #ifndef IMAP_STORAGE 07434 if (cmd) { /* assuming hangup, cleanup backup file */ 07435 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07436 strcpy(textfile, msgfile); 07437 strcpy(backup_textfile, msgfile); 07438 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07439 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07440 rename(backup_textfile, textfile); 07441 } 07442 #endif 07443 } 07444 07445 /* If anything failed above, we still have this list to free */ 07446 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07447 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07448 free_user(vmtmp); 07449 } 07450 return res ? res : cmd; 07451 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1720 of file app_voicemail_odbcstorage.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().
01721 { 01722 if (ast_test_flag(vmu, VM_ALLOCED)) { 01723 01724 ast_free(vmu->emailbody); 01725 vmu->emailbody = NULL; 01726 01727 ast_free(vmu->emailsubject); 01728 vmu->emailsubject = NULL; 01729 01730 ast_free(vmu); 01731 } 01732 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11743 of file app_voicemail_odbcstorage.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().
11744 { 11745 struct ast_vm_user *current; 11746 AST_LIST_LOCK(&users); 11747 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11748 ast_set_flag(current, VM_ALLOCED); 11749 free_user(current); 11750 } 11751 AST_LIST_UNLOCK(&users); 11752 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11755 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by actual_load_config(), and unload_module().
11756 { 11757 struct vm_zone *zcur; 11758 AST_LIST_LOCK(&zones); 11759 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11760 free_zone(zcur); 11761 AST_LIST_UNLOCK(&zones); 11762 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5071 of file app_voicemail_odbcstorage.c.
References ast_free.
Referenced by free_vm_zones().
05072 { 05073 ast_free(z); 05074 }
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 5027 of file app_voicemail_odbcstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
05028 { 05029 struct ast_tm tm; 05030 struct timeval t = ast_tvnow(); 05031 05032 ast_localtime(&t, &tm, "UTC"); 05033 05034 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05035 }
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 6759 of file app_voicemail_odbcstorage.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().
06760 { 06761 int x; 06762 int d; 06763 char fn[PATH_MAX]; 06764 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06765 if (d) 06766 return d; 06767 for (x = start; x < 5; x++) { /* For all folders */ 06768 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06769 return d; 06770 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06771 if (d) 06772 return d; 06773 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06774 06775 /* The inbox folder can have its name changed under certain conditions 06776 * so this checks if the sound file exists for the inbox folder name and 06777 * if it doesn't, plays the default name instead. */ 06778 if (x == 0) { 06779 if (ast_fileexists(fn, NULL, NULL)) { 06780 d = vm_play_folder_name(chan, fn); 06781 } else { 06782 ast_verb(1, "failed to find %s\n", fn); 06783 d = vm_play_folder_name(chan, "vm-INBOX"); 06784 } 06785 } else { 06786 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06787 d = vm_play_folder_name(chan, fn); 06788 } 06789 06790 if (d) 06791 return d; 06792 d = ast_waitfordigit(chan, 500); 06793 if (d) 06794 return d; 06795 } 06796 06797 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06798 if (d) 06799 return d; 06800 d = ast_waitfordigit(chan, 4000); 06801 return d; 06802 }
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 6816 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06817 { 06818 int res = 0; 06819 int loops = 0; 06820 06821 res = ast_play_and_wait(chan, fn); /* Folder name */ 06822 while (((res < '0') || (res > '9')) && 06823 (res != '#') && (res >= 0) && 06824 loops < 4) { 06825 res = get_folder(chan, 0); 06826 loops++; 06827 } 06828 if (loops == 4) { /* give up */ 06829 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06830 return '#'; 06831 } 06832 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06833 return res; 06834 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1707 of file app_voicemail_odbcstorage.c.
References ARRAY_LEN.
Referenced by vm_execmain().
01708 { 01709 size_t i; 01710 01711 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01712 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01713 return i; 01714 } 01715 } 01716 01717 return -1; 01718 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11513 of file app_voicemail_odbcstorage.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().
11514 { 11515 unsigned int len; 11516 struct mwi_sub *mwi_sub; 11517 struct mwi_sub_task *p = datap; 11518 11519 len = sizeof(*mwi_sub); 11520 if (!ast_strlen_zero(p->mailbox)) 11521 len += strlen(p->mailbox); 11522 11523 if (!ast_strlen_zero(p->context)) 11524 len += strlen(p->context) + 1; /* Allow for seperator */ 11525 11526 if (!(mwi_sub = ast_calloc(1, len))) 11527 return -1; 11528 11529 mwi_sub->uniqueid = p->uniqueid; 11530 if (!ast_strlen_zero(p->mailbox)) 11531 strcpy(mwi_sub->mailbox, p->mailbox); 11532 11533 if (!ast_strlen_zero(p->context)) { 11534 strcat(mwi_sub->mailbox, "@"); 11535 strcat(mwi_sub->mailbox, p->context); 11536 } 11537 11538 AST_RWLIST_WRLOCK(&mwi_subs); 11539 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11540 AST_RWLIST_UNLOCK(&mwi_subs); 11541 ast_free((void *) p->mailbox); 11542 ast_free((void *) p->context); 11543 ast_free(p); 11544 poll_subscribed_mailbox(mwi_sub); 11545 return 0; 11546 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11491 of file app_voicemail_odbcstorage.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().
11492 { 11493 struct mwi_sub *mwi_sub; 11494 uint32_t *uniqueid = datap; 11495 11496 AST_RWLIST_WRLOCK(&mwi_subs); 11497 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11498 if (mwi_sub->uniqueid == *uniqueid) { 11499 AST_LIST_REMOVE_CURRENT(entry); 11500 break; 11501 } 11502 } 11503 AST_RWLIST_TRAVERSE_SAFE_END 11504 AST_RWLIST_UNLOCK(&mwi_subs); 11505 11506 if (mwi_sub) 11507 mwi_sub_destroy(mwi_sub); 11508 11509 ast_free(uniqueid); 11510 return 0; 11511 }
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 11268 of file app_voicemail_odbcstorage.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.
11269 { 11270 switch (cmd) { 11271 case CLI_INIT: 11272 e->command = "voicemail reload"; 11273 e->usage = 11274 "Usage: voicemail reload\n" 11275 " Reload voicemail configuration\n"; 11276 return NULL; 11277 case CLI_GENERATE: 11278 return NULL; 11279 } 11280 11281 if (a->argc != 2) 11282 return CLI_SHOWUSAGE; 11283 11284 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11285 load_config(1); 11286 11287 return CLI_SUCCESS; 11288 }
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 11156 of file app_voicemail_odbcstorage.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.
11157 { 11158 struct ast_vm_user *vmu; 11159 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11160 const char *context = NULL; 11161 int users_counter = 0; 11162 11163 switch (cmd) { 11164 case CLI_INIT: 11165 e->command = "voicemail show users"; 11166 e->usage = 11167 "Usage: voicemail show users [for <context>]\n" 11168 " Lists all mailboxes currently set up\n"; 11169 return NULL; 11170 case CLI_GENERATE: 11171 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11172 } 11173 11174 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11175 return CLI_SHOWUSAGE; 11176 if (a->argc == 5) { 11177 if (strcmp(a->argv[3],"for")) 11178 return CLI_SHOWUSAGE; 11179 context = a->argv[4]; 11180 } 11181 11182 if (ast_check_realtime("voicemail")) { 11183 if (!context) { 11184 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11185 return CLI_SHOWUSAGE; 11186 } 11187 return show_users_realtime(a->fd, context); 11188 } 11189 11190 AST_LIST_LOCK(&users); 11191 if (AST_LIST_EMPTY(&users)) { 11192 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11193 AST_LIST_UNLOCK(&users); 11194 return CLI_FAILURE; 11195 } 11196 if (!context) { 11197 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11198 } else { 11199 int count = 0; 11200 AST_LIST_TRAVERSE(&users, vmu, list) { 11201 if (!strcmp(context, vmu->context)) { 11202 count++; 11203 break; 11204 } 11205 } 11206 if (count) { 11207 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11208 } else { 11209 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11210 AST_LIST_UNLOCK(&users); 11211 return CLI_FAILURE; 11212 } 11213 } 11214 AST_LIST_TRAVERSE(&users, vmu, list) { 11215 int newmsgs = 0, oldmsgs = 0; 11216 char count[12], tmp[256] = ""; 11217 11218 if (!context || !strcmp(context, vmu->context)) { 11219 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11220 inboxcount(tmp, &newmsgs, &oldmsgs); 11221 snprintf(count, sizeof(count), "%d", newmsgs); 11222 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11223 users_counter++; 11224 } 11225 } 11226 AST_LIST_UNLOCK(&users); 11227 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11228 return CLI_SUCCESS; 11229 }
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 11232 of file app_voicemail_odbcstorage.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.
11233 { 11234 struct vm_zone *zone; 11235 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11236 char *res = CLI_SUCCESS; 11237 11238 switch (cmd) { 11239 case CLI_INIT: 11240 e->command = "voicemail show zones"; 11241 e->usage = 11242 "Usage: voicemail show zones\n" 11243 " Lists zone message formats\n"; 11244 return NULL; 11245 case CLI_GENERATE: 11246 return NULL; 11247 } 11248 11249 if (a->argc != 3) 11250 return CLI_SHOWUSAGE; 11251 11252 AST_LIST_LOCK(&zones); 11253 if (!AST_LIST_EMPTY(&zones)) { 11254 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11255 AST_LIST_TRAVERSE(&zones, zone, list) { 11256 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11257 } 11258 } else { 11259 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11260 res = CLI_FAILURE; 11261 } 11262 AST_LIST_UNLOCK(&zones); 11263 11264 return res; 11265 }
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 5415 of file app_voicemail_odbcstorage.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by load_module(), and vm_execmain().
05416 { 05417 char tmp[256], *tmp2 = tmp, *box, *context; 05418 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05419 if (ast_strlen_zero(folder)) { 05420 folder = "INBOX"; 05421 } 05422 while ((box = strsep(&tmp2, ",&"))) { 05423 if ((context = strchr(box, '@'))) 05424 *context++ = '\0'; 05425 else 05426 context = "default"; 05427 if (__has_voicemail(context, box, folder, 1)) 05428 return 1; 05429 /* If we are checking INBOX, we should check Urgent as well */ 05430 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05431 return 1; 05432 } 05433 } 05434 return 0; 05435 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5497 of file app_voicemail_odbcstorage.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05498 { 05499 int urgentmsgs = 0; 05500 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05501 if (newmsgs) { 05502 *newmsgs += urgentmsgs; 05503 } 05504 return res; 05505 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5438 of file app_voicemail_odbcstorage.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().
05439 { 05440 char tmp[256]; 05441 char *context; 05442 05443 /* If no mailbox, return immediately */ 05444 if (ast_strlen_zero(mailbox)) 05445 return 0; 05446 05447 if (newmsgs) 05448 *newmsgs = 0; 05449 if (oldmsgs) 05450 *oldmsgs = 0; 05451 if (urgentmsgs) 05452 *urgentmsgs = 0; 05453 05454 if (strchr(mailbox, ',')) { 05455 int tmpnew, tmpold, tmpurgent; 05456 char *mb, *cur; 05457 05458 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05459 mb = tmp; 05460 while ((cur = strsep(&mb, ", "))) { 05461 if (!ast_strlen_zero(cur)) { 05462 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05463 return -1; 05464 else { 05465 if (newmsgs) 05466 *newmsgs += tmpnew; 05467 if (oldmsgs) 05468 *oldmsgs += tmpold; 05469 if (urgentmsgs) 05470 *urgentmsgs += tmpurgent; 05471 } 05472 } 05473 } 05474 return 0; 05475 } 05476 05477 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05478 05479 if ((context = strchr(tmp, '@'))) 05480 *context++ = '\0'; 05481 else 05482 context = "default"; 05483 05484 if (newmsgs) 05485 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05486 if (oldmsgs) 05487 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05488 if (urgentmsgs) 05489 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05490 05491 return 0; 05492 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4197 of file app_voicemail_odbcstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by inchar().
04198 { 04199 int l; 04200 04201 if (bio->ateof) 04202 return 0; 04203 04204 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04205 if (ferror(fi)) 04206 return -1; 04207 04208 bio->ateof = 1; 04209 return 0; 04210 } 04211 04212 bio->iolen = l; 04213 bio->iocp = 0; 04214 04215 return 1; 04216 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4221 of file app_voicemail_odbcstorage.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 915 of file app_voicemail_odbcstorage.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 924 of file app_voicemail_odbcstorage.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().
00925 { 00926 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00927 arg->context = arg->mailbox + strlen(mailbox) + 1; 00928 strcpy(arg->mailbox, mailbox); /* SAFE */ 00929 strcpy(arg->context, context); /* SAFE */ 00930 ao2_lock(inprocess_container); 00931 if ((i = ao2_find(inprocess_container, arg, 0))) { 00932 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00933 ao2_unlock(inprocess_container); 00934 ao2_ref(i, -1); 00935 return ret; 00936 } 00937 if (delta < 0) { 00938 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00939 } 00940 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00941 ao2_unlock(inprocess_container); 00942 return 0; 00943 } 00944 i->context = i->mailbox + strlen(mailbox) + 1; 00945 strcpy(i->mailbox, mailbox); /* SAFE */ 00946 strcpy(i->context, context); /* SAFE */ 00947 i->count = delta; 00948 ao2_link(inprocess_container, i); 00949 ao2_unlock(inprocess_container); 00950 ao2_ref(i, -1); 00951 return 0; 00952 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 909 of file app_voicemail_odbcstorage.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 5037 of file app_voicemail_odbcstorage.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().
05038 { 05039 int res; 05040 char fn[PATH_MAX]; 05041 char dest[PATH_MAX]; 05042 05043 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05044 05045 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05046 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05047 return -1; 05048 } 05049 05050 RETRIEVE(fn, -1, ext, context); 05051 if (ast_fileexists(fn, NULL, NULL) > 0) { 05052 res = ast_stream_and_wait(chan, fn, ecodes); 05053 if (res) { 05054 DISPOSE(fn, -1); 05055 return res; 05056 } 05057 } else { 05058 /* Dispose just in case */ 05059 DISPOSE(fn, -1); 05060 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05061 if (res) 05062 return res; 05063 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05064 if (res) 05065 return res; 05066 } 05067 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05068 return res; 05069 }
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 1351 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01352 { 01353 int i; 01354 char *local_key = ast_strdupa(key); 01355 01356 for (i = 0; i < strlen(key); ++i) { 01357 if (!strchr(VALID_DTMF, *local_key)) { 01358 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01359 return 0; 01360 } 01361 local_key++; 01362 } 01363 return 1; 01364 }
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 4016 of file app_voicemail_odbcstorage.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().
04017 { 04018 int x; 04019 unsigned char map[MAXMSGLIMIT] = ""; 04020 DIR *msgdir; 04021 struct dirent *msgdirent; 04022 int msgdirint; 04023 char extension[4]; 04024 int stopcount = 0; 04025 04026 /* Reading the entire directory into a file map scales better than 04027 * doing a stat repeatedly on a predicted sequence. I suspect this 04028 * is partially due to stat(2) internally doing a readdir(2) itself to 04029 * find each file. */ 04030 if (!(msgdir = opendir(dir))) { 04031 return -1; 04032 } 04033 04034 while ((msgdirent = readdir(msgdir))) { 04035 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04036 map[msgdirint] = 1; 04037 stopcount++; 04038 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04039 } 04040 } 04041 closedir(msgdir); 04042 04043 for (x = 0; x < vmu->maxmsg; x++) { 04044 if (map[x] == 1) { 04045 stopcount--; 04046 } else if (map[x] == 0 && !stopcount) { 04047 break; 04048 } 04049 } 04050 04051 return x - 1; 04052 }
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 5570 of file app_voicemail_odbcstorage.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().
05571 { 05572 #ifdef IMAP_STORAGE 05573 int newmsgs, oldmsgs; 05574 #else 05575 char urgdir[PATH_MAX]; 05576 #endif 05577 char txtfile[PATH_MAX]; 05578 char tmptxtfile[PATH_MAX]; 05579 struct vm_state *vms = NULL; 05580 char callerid[256]; 05581 FILE *txt; 05582 char date[256]; 05583 int txtdes; 05584 int res = 0; 05585 int msgnum; 05586 int duration = 0; 05587 int sound_duration = 0; 05588 int ausemacro = 0; 05589 int ousemacro = 0; 05590 int ouseexten = 0; 05591 char tmpdur[16]; 05592 char priority[16]; 05593 char origtime[16]; 05594 char dir[PATH_MAX]; 05595 char tmpdir[PATH_MAX]; 05596 char fn[PATH_MAX]; 05597 char prefile[PATH_MAX] = ""; 05598 char tempfile[PATH_MAX] = ""; 05599 char ext_context[256] = ""; 05600 char fmt[80]; 05601 char *context; 05602 char ecodes[17] = "#"; 05603 struct ast_str *tmp = ast_str_create(16); 05604 char *tmpptr; 05605 struct ast_vm_user *vmu; 05606 struct ast_vm_user svm; 05607 const char *category = NULL; 05608 const char *code; 05609 const char *alldtmf = "0123456789ABCD*#"; 05610 char flag[80]; 05611 05612 if (!tmp) { 05613 return -1; 05614 } 05615 05616 ast_str_set(&tmp, 0, "%s", ext); 05617 ext = ast_str_buffer(tmp); 05618 if ((context = strchr(ext, '@'))) { 05619 *context++ = '\0'; 05620 tmpptr = strchr(context, '&'); 05621 } else { 05622 tmpptr = strchr(ext, '&'); 05623 } 05624 05625 if (tmpptr) 05626 *tmpptr++ = '\0'; 05627 05628 ast_channel_lock(chan); 05629 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05630 category = ast_strdupa(category); 05631 } 05632 ast_channel_unlock(chan); 05633 05634 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05635 ast_copy_string(flag, "Urgent", sizeof(flag)); 05636 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05637 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05638 } else { 05639 flag[0] = '\0'; 05640 } 05641 05642 ast_debug(3, "Before find_user\n"); 05643 if (!(vmu = find_user(&svm, context, ext))) { 05644 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05645 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05646 ast_free(tmp); 05647 return res; 05648 } 05649 /* Setup pre-file if appropriate */ 05650 if (strcmp(vmu->context, "default")) 05651 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05652 else 05653 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05654 05655 /* Set the path to the prefile. Will be one of 05656 VM_SPOOL_DIRcontext/ext/busy 05657 VM_SPOOL_DIRcontext/ext/unavail 05658 Depending on the flag set in options. 05659 */ 05660 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05661 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05662 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05663 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05664 } 05665 /* Set the path to the tmpfile as 05666 VM_SPOOL_DIR/context/ext/temp 05667 and attempt to create the folder structure. 05668 */ 05669 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05670 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05671 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05672 ast_free(tmp); 05673 return -1; 05674 } 05675 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05676 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05677 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05678 05679 DISPOSE(tempfile, -1); 05680 /* It's easier just to try to make it than to check for its existence */ 05681 #ifndef IMAP_STORAGE 05682 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05683 #else 05684 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05685 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05686 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05687 } 05688 #endif 05689 05690 /* Check current or macro-calling context for special extensions */ 05691 if (ast_test_flag(vmu, VM_OPERATOR)) { 05692 if (!ast_strlen_zero(vmu->exit)) { 05693 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05694 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05695 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05696 ouseexten = 1; 05697 } 05698 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05699 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05700 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05701 ouseexten = 1; 05702 } else if (!ast_strlen_zero(chan->macrocontext) 05703 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05704 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05705 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05706 ousemacro = 1; 05707 } 05708 } 05709 05710 if (!ast_strlen_zero(vmu->exit)) { 05711 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05712 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05713 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05714 } 05715 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05716 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05717 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05718 } else if (!ast_strlen_zero(chan->macrocontext) 05719 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05720 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05721 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05722 ausemacro = 1; 05723 } 05724 05725 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05726 for (code = alldtmf; *code; code++) { 05727 char e[2] = ""; 05728 e[0] = *code; 05729 if (strchr(ecodes, e[0]) == NULL 05730 && ast_canmatch_extension(chan, 05731 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05732 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05733 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05734 } 05735 } 05736 } 05737 05738 /* Play the beginning intro if desired */ 05739 if (!ast_strlen_zero(prefile)) { 05740 #ifdef ODBC_STORAGE 05741 int success = 05742 #endif 05743 RETRIEVE(prefile, -1, ext, context); 05744 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05745 if (ast_streamfile(chan, prefile, chan->language) > -1) 05746 res = ast_waitstream(chan, ecodes); 05747 #ifdef ODBC_STORAGE 05748 if (success == -1) { 05749 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05750 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05751 store_file(prefile, vmu->mailbox, vmu->context, -1); 05752 } 05753 #endif 05754 } else { 05755 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05756 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05757 } 05758 DISPOSE(prefile, -1); 05759 if (res < 0) { 05760 ast_debug(1, "Hang up during prefile playback\n"); 05761 free_user(vmu); 05762 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05763 ast_free(tmp); 05764 return -1; 05765 } 05766 } 05767 if (res == '#') { 05768 /* On a '#' we skip the instructions */ 05769 ast_set_flag(options, OPT_SILENT); 05770 res = 0; 05771 } 05772 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05773 if (vmu->maxmsg == 0) { 05774 if (option_debug > 2) 05775 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05776 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05777 goto leave_vm_out; 05778 } 05779 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05780 res = ast_stream_and_wait(chan, INTRO, ecodes); 05781 if (res == '#') { 05782 ast_set_flag(options, OPT_SILENT); 05783 res = 0; 05784 } 05785 } 05786 if (res > 0) 05787 ast_stopstream(chan); 05788 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05789 other than the operator -- an automated attendant or mailbox login for example */ 05790 if (res == '*') { 05791 chan->exten[0] = 'a'; 05792 chan->exten[1] = '\0'; 05793 if (!ast_strlen_zero(vmu->exit)) { 05794 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05795 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05796 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05797 } 05798 chan->priority = 0; 05799 free_user(vmu); 05800 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05801 ast_free(tmp); 05802 return 0; 05803 } 05804 05805 /* Check for a '0' here */ 05806 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05807 transfer: 05808 if (ouseexten || ousemacro) { 05809 chan->exten[0] = 'o'; 05810 chan->exten[1] = '\0'; 05811 if (!ast_strlen_zero(vmu->exit)) { 05812 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05813 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05814 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05815 } 05816 ast_play_and_wait(chan, "transfer"); 05817 chan->priority = 0; 05818 free_user(vmu); 05819 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05820 } 05821 ast_free(tmp); 05822 return OPERATOR_EXIT; 05823 } 05824 05825 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05826 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05827 if (!ast_strlen_zero(options->exitcontext)) { 05828 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05829 } 05830 free_user(vmu); 05831 ast_free(tmp); 05832 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05833 return res; 05834 } 05835 05836 if (res < 0) { 05837 free_user(vmu); 05838 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05839 ast_free(tmp); 05840 return -1; 05841 } 05842 /* The meat of recording the message... All the announcements and beeps have been played*/ 05843 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05844 if (!ast_strlen_zero(fmt)) { 05845 msgnum = 0; 05846 05847 #ifdef IMAP_STORAGE 05848 /* Is ext a mailbox? */ 05849 /* must open stream for this user to get info! */ 05850 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05851 if (res < 0) { 05852 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05853 ast_free(tmp); 05854 return -1; 05855 } 05856 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05857 /* It is possible under certain circumstances that inboxcount did not 05858 * create a vm_state when it was needed. This is a catchall which will 05859 * rarely be used. 05860 */ 05861 if (!(vms = create_vm_state_from_user(vmu))) { 05862 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05863 ast_free(tmp); 05864 return -1; 05865 } 05866 } 05867 vms->newmessages++; 05868 05869 /* here is a big difference! We add one to it later */ 05870 msgnum = newmsgs + oldmsgs; 05871 ast_debug(3, "Messagecount set to %d\n", msgnum); 05872 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05873 /* set variable for compatibility */ 05874 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05875 05876 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05877 goto leave_vm_out; 05878 } 05879 #else 05880 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05881 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05882 if (!res) 05883 res = ast_waitstream(chan, ""); 05884 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05885 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05886 inprocess_count(vmu->mailbox, vmu->context, -1); 05887 goto leave_vm_out; 05888 } 05889 05890 #endif 05891 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05892 txtdes = mkstemp(tmptxtfile); 05893 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05894 if (txtdes < 0) { 05895 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05896 if (!res) 05897 res = ast_waitstream(chan, ""); 05898 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05899 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05900 inprocess_count(vmu->mailbox, vmu->context, -1); 05901 goto leave_vm_out; 05902 } 05903 05904 /* Now play the beep once we have the message number for our next message. */ 05905 if (res >= 0) { 05906 /* Unless we're *really* silent, try to send the beep */ 05907 res = ast_stream_and_wait(chan, "beep", ""); 05908 } 05909 05910 /* Store information in real-time storage */ 05911 if (ast_check_realtime("voicemail_data")) { 05912 snprintf(priority, sizeof(priority), "%d", chan->priority); 05913 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05914 get_date(date, sizeof(date)); 05915 ast_callerid_merge(callerid, sizeof(callerid), 05916 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05917 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05918 "Unknown"); 05919 ast_store_realtime("voicemail_data", 05920 "origmailbox", ext, 05921 "context", chan->context, 05922 "macrocontext", chan->macrocontext, 05923 "exten", chan->exten, 05924 "priority", priority, 05925 "callerchan", chan->name, 05926 "callerid", callerid, 05927 "origdate", date, 05928 "origtime", origtime, 05929 "category", S_OR(category, ""), 05930 "filename", tmptxtfile, 05931 SENTINEL); 05932 } 05933 05934 /* Store information */ 05935 txt = fdopen(txtdes, "w+"); 05936 if (txt) { 05937 get_date(date, sizeof(date)); 05938 ast_callerid_merge(callerid, sizeof(callerid), 05939 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05940 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05941 "Unknown"); 05942 fprintf(txt, 05943 ";\n" 05944 "; Message Information file\n" 05945 ";\n" 05946 "[message]\n" 05947 "origmailbox=%s\n" 05948 "context=%s\n" 05949 "macrocontext=%s\n" 05950 "exten=%s\n" 05951 "rdnis=%s\n" 05952 "priority=%d\n" 05953 "callerchan=%s\n" 05954 "callerid=%s\n" 05955 "origdate=%s\n" 05956 "origtime=%ld\n" 05957 "category=%s\n", 05958 ext, 05959 chan->context, 05960 chan->macrocontext, 05961 chan->exten, 05962 S_COR(chan->redirecting.from.number.valid, 05963 chan->redirecting.from.number.str, "unknown"), 05964 chan->priority, 05965 chan->name, 05966 callerid, 05967 date, (long) time(NULL), 05968 category ? category : ""); 05969 } else { 05970 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05971 inprocess_count(vmu->mailbox, vmu->context, -1); 05972 if (ast_check_realtime("voicemail_data")) { 05973 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05974 } 05975 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05976 goto leave_vm_out; 05977 } 05978 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05979 05980 if (txt) { 05981 fprintf(txt, "flag=%s\n", flag); 05982 if (sound_duration < vmu->minsecs) { 05983 fclose(txt); 05984 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 05985 ast_filedelete(tmptxtfile, NULL); 05986 unlink(tmptxtfile); 05987 if (ast_check_realtime("voicemail_data")) { 05988 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05989 } 05990 inprocess_count(vmu->mailbox, vmu->context, -1); 05991 } else { 05992 fprintf(txt, "duration=%d\n", duration); 05993 fclose(txt); 05994 if (vm_lock_path(dir)) { 05995 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05996 /* Delete files */ 05997 ast_filedelete(tmptxtfile, NULL); 05998 unlink(tmptxtfile); 05999 inprocess_count(vmu->mailbox, vmu->context, -1); 06000 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06001 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06002 unlink(tmptxtfile); 06003 ast_unlock_path(dir); 06004 inprocess_count(vmu->mailbox, vmu->context, -1); 06005 if (ast_check_realtime("voicemail_data")) { 06006 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06007 } 06008 } else { 06009 #ifndef IMAP_STORAGE 06010 msgnum = last_message_index(vmu, dir) + 1; 06011 #endif 06012 make_file(fn, sizeof(fn), dir, msgnum); 06013 06014 /* assign a variable with the name of the voicemail file */ 06015 #ifndef IMAP_STORAGE 06016 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06017 #else 06018 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06019 #endif 06020 06021 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06022 ast_filerename(tmptxtfile, fn, NULL); 06023 rename(tmptxtfile, txtfile); 06024 inprocess_count(vmu->mailbox, vmu->context, -1); 06025 06026 /* Properly set permissions on voicemail text descriptor file. 06027 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06028 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06029 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06030 06031 ast_unlock_path(dir); 06032 if (ast_check_realtime("voicemail_data")) { 06033 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06034 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06035 } 06036 /* We must store the file first, before copying the message, because 06037 * ODBC storage does the entire copy with SQL. 06038 */ 06039 if (ast_fileexists(fn, NULL, NULL) > 0) { 06040 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06041 } 06042 06043 /* Are there to be more recipients of this message? */ 06044 while (tmpptr) { 06045 struct ast_vm_user recipu, *recip; 06046 char *exten, *cntx; 06047 06048 exten = strsep(&tmpptr, "&"); 06049 cntx = strchr(exten, '@'); 06050 if (cntx) { 06051 *cntx = '\0'; 06052 cntx++; 06053 } 06054 if ((recip = find_user(&recipu, cntx, exten))) { 06055 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06056 free_user(recip); 06057 } 06058 } 06059 #ifndef IMAP_STORAGE 06060 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06061 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06062 char sfn[PATH_MAX]; 06063 char dfn[PATH_MAX]; 06064 int x; 06065 /* It's easier just to try to make it than to check for its existence */ 06066 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06067 x = last_message_index(vmu, urgdir) + 1; 06068 make_file(sfn, sizeof(sfn), dir, msgnum); 06069 make_file(dfn, sizeof(dfn), urgdir, x); 06070 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06071 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06072 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06073 ast_copy_string(fn, dfn, sizeof(fn)); 06074 msgnum = x; 06075 } 06076 #endif 06077 /* Notification needs to happen after the copy, though. */ 06078 if (ast_fileexists(fn, NULL, NULL)) { 06079 #ifdef IMAP_STORAGE 06080 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06081 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06082 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06083 flag); 06084 #else 06085 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06086 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06087 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06088 flag); 06089 #endif 06090 } 06091 06092 /* Disposal needs to happen after the optional move and copy */ 06093 if (ast_fileexists(fn, NULL, NULL)) { 06094 DISPOSE(dir, msgnum); 06095 } 06096 } 06097 } 06098 } else { 06099 inprocess_count(vmu->mailbox, vmu->context, -1); 06100 } 06101 if (res == '0') { 06102 goto transfer; 06103 } else if (res > 0 && res != 't') 06104 res = 0; 06105 06106 if (sound_duration < vmu->minsecs) 06107 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06108 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06109 else 06110 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06111 } else 06112 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06113 leave_vm_out: 06114 free_user(vmu); 06115 06116 #ifdef IMAP_STORAGE 06117 /* expunge message - use UID Expunge if supported on IMAP server*/ 06118 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06119 if (expungeonhangup == 1) { 06120 ast_mutex_lock(&vms->lock); 06121 #ifdef HAVE_IMAP_TK2006 06122 if (LEVELUIDPLUS (vms->mailstream)) { 06123 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06124 } else 06125 #endif 06126 mail_expunge(vms->mailstream); 06127 ast_mutex_unlock(&vms->lock); 06128 } 06129 #endif 06130 06131 ast_free(tmp); 06132 return res; 06133 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11811 of file app_voicemail_odbcstorage.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().
11812 { 11813 struct ast_config *cfg, *ucfg; 11814 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11815 int res; 11816 11817 ast_unload_realtime("voicemail"); 11818 ast_unload_realtime("voicemail_data"); 11819 11820 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11821 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11822 return 0; 11823 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11824 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11825 ucfg = NULL; 11826 } 11827 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11828 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11829 ast_config_destroy(ucfg); 11830 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11831 return 0; 11832 } 11833 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11834 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11835 return 0; 11836 } else { 11837 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11838 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11839 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11840 ucfg = NULL; 11841 } 11842 } 11843 11844 res = actual_load_config(reload, cfg, ucfg); 11845 11846 ast_config_destroy(cfg); 11847 ast_config_destroy(ucfg); 11848 11849 return res; 11850 }
static int load_module | ( | void | ) | [static] |
Definition at line 13111 of file app_voicemail_odbcstorage.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().
13112 { 13113 int res; 13114 my_umask = umask(0); 13115 umask(my_umask); 13116 13117 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13118 return AST_MODULE_LOAD_DECLINE; 13119 } 13120 13121 /* compute the location of the voicemail spool directory */ 13122 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13123 13124 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13125 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13126 } 13127 13128 if ((res = load_config(0))) 13129 return res; 13130 13131 res = ast_register_application_xml(app, vm_exec); 13132 res |= ast_register_application_xml(app2, vm_execmain); 13133 res |= ast_register_application_xml(app3, vm_box_exists); 13134 res |= ast_register_application_xml(app4, vmauthenticate); 13135 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13136 res |= ast_custom_function_register(&mailbox_exists_acf); 13137 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13138 #ifdef TEST_FRAMEWORK 13139 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13140 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13141 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13142 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13143 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13144 #endif 13145 13146 if (res) 13147 return res; 13148 13149 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13150 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13151 13152 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13153 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13154 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13155 13156 return res; 13157 }
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 1619 of file app_voicemail_odbcstorage.c.
Referenced by copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01620 { 01621 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01622 }
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 4514 of file app_voicemail_odbcstorage.c.
References add_email_attachment(), ast_channel_unref, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc, ast_free, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ENDL, ast_vm_user::fullname, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04515 { 04516 char date[256]; 04517 char host[MAXHOSTNAMELEN] = ""; 04518 char who[256]; 04519 char bound[256]; 04520 char dur[256]; 04521 struct ast_tm tm; 04522 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04523 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04524 char *greeting_attachment; 04525 char filename[256]; 04526 04527 if (!str1 || !str2) { 04528 ast_free(str1); 04529 ast_free(str2); 04530 return; 04531 } 04532 04533 if (cidnum) { 04534 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04535 } 04536 if (cidname) { 04537 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04538 } 04539 gethostname(host, sizeof(host) - 1); 04540 04541 if (strchr(srcemail, '@')) { 04542 ast_copy_string(who, srcemail, sizeof(who)); 04543 } else { 04544 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04545 } 04546 04547 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04548 if (greeting_attachment) { 04549 *greeting_attachment++ = '\0'; 04550 } 04551 04552 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04553 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04554 fprintf(p, "Date: %s" ENDL, date); 04555 04556 /* Set date format for voicemail mail */ 04557 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04558 04559 if (!ast_strlen_zero(fromstring)) { 04560 struct ast_channel *ast; 04561 if ((ast = ast_dummy_channel_alloc())) { 04562 char *ptr; 04563 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04564 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04565 04566 if (check_mime(ast_str_buffer(str1))) { 04567 int first_line = 1; 04568 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04569 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04570 *ptr = '\0'; 04571 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04572 first_line = 0; 04573 /* Substring is smaller, so this will never grow */ 04574 ast_str_set(&str2, 0, "%s", ptr + 1); 04575 } 04576 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04577 } else { 04578 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04579 } 04580 ast = ast_channel_unref(ast); 04581 } else { 04582 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04583 } 04584 } else { 04585 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04586 } 04587 04588 if (check_mime(vmu->fullname)) { 04589 int first_line = 1; 04590 char *ptr; 04591 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04592 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04593 *ptr = '\0'; 04594 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04595 first_line = 0; 04596 /* Substring is smaller, so this will never grow */ 04597 ast_str_set(&str2, 0, "%s", ptr + 1); 04598 } 04599 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04600 } else { 04601 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04602 } 04603 04604 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04605 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04606 struct ast_channel *ast; 04607 if ((ast = ast_dummy_channel_alloc())) { 04608 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04609 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04610 if (check_mime(ast_str_buffer(str1))) { 04611 int first_line = 1; 04612 char *ptr; 04613 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04614 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04615 *ptr = '\0'; 04616 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04617 first_line = 0; 04618 /* Substring is smaller, so this will never grow */ 04619 ast_str_set(&str2, 0, "%s", ptr + 1); 04620 } 04621 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04622 } else { 04623 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04624 } 04625 ast = ast_channel_unref(ast); 04626 } else { 04627 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04628 } 04629 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04630 if (ast_strlen_zero(flag)) { 04631 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04632 } else { 04633 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04634 } 04635 } else { 04636 if (ast_strlen_zero(flag)) { 04637 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04638 } else { 04639 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04640 } 04641 } 04642 04643 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04644 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04645 if (imap) { 04646 /* additional information needed for IMAP searching */ 04647 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04648 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04649 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04650 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04651 #ifdef IMAP_STORAGE 04652 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04653 #else 04654 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04655 #endif 04656 /* flag added for Urgent */ 04657 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04658 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04659 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04660 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04661 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04662 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04663 if (!ast_strlen_zero(category)) { 04664 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04665 } else { 04666 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04667 } 04668 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04669 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04670 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04671 } 04672 if (!ast_strlen_zero(cidnum)) { 04673 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04674 } 04675 if (!ast_strlen_zero(cidname)) { 04676 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04677 } 04678 fprintf(p, "MIME-Version: 1.0" ENDL); 04679 if (attach_user_voicemail) { 04680 /* Something unique. */ 04681 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04682 (int) getpid(), (unsigned int) ast_random()); 04683 04684 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04685 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04686 fprintf(p, "--%s" ENDL, bound); 04687 } 04688 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04689 if (emailbody || vmu->emailbody) { 04690 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04691 struct ast_channel *ast; 04692 if ((ast = ast_dummy_channel_alloc())) { 04693 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04694 ast_str_substitute_variables(&str1, 0, ast, e_body); 04695 #ifdef IMAP_STORAGE 04696 { 04697 /* Convert body to native line terminators for IMAP backend */ 04698 char *line = ast_str_buffer(str1), *next; 04699 do { 04700 /* Terminate line before outputting it to the file */ 04701 if ((next = strchr(line, '\n'))) { 04702 *next++ = '\0'; 04703 } 04704 fprintf(p, "%s" ENDL, line); 04705 line = next; 04706 } while (!ast_strlen_zero(line)); 04707 } 04708 #else 04709 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04710 #endif 04711 ast = ast_channel_unref(ast); 04712 } else { 04713 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04714 } 04715 } else if (msgnum > -1) { 04716 if (strcmp(vmu->mailbox, mailbox)) { 04717 /* Forwarded type */ 04718 struct ast_config *msg_cfg; 04719 const char *v; 04720 int inttime; 04721 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04722 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04723 /* Retrieve info from VM attribute file */ 04724 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04725 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04726 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04727 strcat(fromfile, ".txt"); 04728 } 04729 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04730 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04731 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04732 } 04733 04734 /* You might be tempted to do origdate, except that a) it's in the wrong 04735 * format, and b) it's missing for IMAP recordings. */ 04736 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04737 struct timeval tv = { inttime, }; 04738 struct ast_tm tm; 04739 ast_localtime(&tv, &tm, NULL); 04740 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04741 } 04742 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04743 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04744 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04745 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04746 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04747 date, origcallerid, origdate); 04748 ast_config_destroy(msg_cfg); 04749 } else { 04750 goto plain_message; 04751 } 04752 } else { 04753 plain_message: 04754 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04755 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04756 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04757 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04758 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04759 } 04760 } else { 04761 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04762 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04763 } 04764 04765 if (imap || attach_user_voicemail) { 04766 if (!ast_strlen_zero(attach2)) { 04767 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04768 ast_debug(5, "creating second attachment filename %s\n", filename); 04769 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04770 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04771 ast_debug(5, "creating attachment filename %s\n", filename); 04772 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04773 } else { 04774 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04775 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04776 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04777 } 04778 } 04779 ast_free(str1); 04780 ast_free(str2); 04781 }
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 1636 of file app_voicemail_odbcstorage.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().
01637 { 01638 return snprintf(dest, len, "%s/msg%04d", dir, num); 01639 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11642 of file app_voicemail_odbcstorage.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().
11643 { 11644 struct ast_vm_user *vmu = NULL; 11645 const char *id = astman_get_header(m, "ActionID"); 11646 char actionid[128] = ""; 11647 11648 if (!ast_strlen_zero(id)) 11649 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11650 11651 AST_LIST_LOCK(&users); 11652 11653 if (AST_LIST_EMPTY(&users)) { 11654 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11655 AST_LIST_UNLOCK(&users); 11656 return RESULT_SUCCESS; 11657 } 11658 11659 astman_send_ack(s, m, "Voicemail user list will follow"); 11660 11661 AST_LIST_TRAVERSE(&users, vmu, list) { 11662 char dirname[256]; 11663 11664 #ifdef IMAP_STORAGE 11665 int new, old; 11666 inboxcount(vmu->mailbox, &new, &old); 11667 #endif 11668 11669 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11670 astman_append(s, 11671 "%s" 11672 "Event: VoicemailUserEntry\r\n" 11673 "VMContext: %s\r\n" 11674 "VoiceMailbox: %s\r\n" 11675 "Fullname: %s\r\n" 11676 "Email: %s\r\n" 11677 "Pager: %s\r\n" 11678 "ServerEmail: %s\r\n" 11679 "MailCommand: %s\r\n" 11680 "Language: %s\r\n" 11681 "TimeZone: %s\r\n" 11682 "Callback: %s\r\n" 11683 "Dialout: %s\r\n" 11684 "UniqueID: %s\r\n" 11685 "ExitContext: %s\r\n" 11686 "SayDurationMinimum: %d\r\n" 11687 "SayEnvelope: %s\r\n" 11688 "SayCID: %s\r\n" 11689 "AttachMessage: %s\r\n" 11690 "AttachmentFormat: %s\r\n" 11691 "DeleteMessage: %s\r\n" 11692 "VolumeGain: %.2f\r\n" 11693 "CanReview: %s\r\n" 11694 "CallOperator: %s\r\n" 11695 "MaxMessageCount: %d\r\n" 11696 "MaxMessageLength: %d\r\n" 11697 "NewMessageCount: %d\r\n" 11698 #ifdef IMAP_STORAGE 11699 "OldMessageCount: %d\r\n" 11700 "IMAPUser: %s\r\n" 11701 #endif 11702 "\r\n", 11703 actionid, 11704 vmu->context, 11705 vmu->mailbox, 11706 vmu->fullname, 11707 vmu->email, 11708 vmu->pager, 11709 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11710 mailcmd, 11711 vmu->language, 11712 vmu->zonetag, 11713 vmu->callback, 11714 vmu->dialout, 11715 vmu->uniqueid, 11716 vmu->exit, 11717 vmu->saydurationm, 11718 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11719 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11720 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11721 vmu->attachfmt, 11722 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11723 vmu->volgain, 11724 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11725 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11726 vmu->maxmsg, 11727 vmu->maxsecs, 11728 #ifdef IMAP_STORAGE 11729 new, old, vmu->imapuser 11730 #else 11731 count_messages(vmu, dirname) 11732 #endif 11733 ); 11734 } 11735 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11736 11737 AST_LIST_UNLOCK(&users); 11738 11739 return RESULT_SUCCESS; 11740 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11463 of file app_voicemail_odbcstorage.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().
11464 { 11465 while (poll_thread_run) { 11466 struct timespec ts = { 0, }; 11467 struct timeval wait; 11468 11469 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11470 ts.tv_sec = wait.tv_sec; 11471 ts.tv_nsec = wait.tv_usec * 1000; 11472 11473 ast_mutex_lock(&poll_lock); 11474 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11475 ast_mutex_unlock(&poll_lock); 11476 11477 if (!poll_thread_run) 11478 break; 11479 11480 poll_subscribed_mailboxes(); 11481 } 11482 11483 return NULL; 11484 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1697 of file app_voicemail_odbcstorage.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().
01698 { 01699 #ifdef IMAP_STORAGE 01700 if (vmu && id == 0) { 01701 return vmu->imapfolder; 01702 } 01703 #endif 01704 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01705 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5364 of file app_voicemail_odbcstorage.c.
References __has_voicemail().
Referenced by load_module().
05365 { 05366 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05367 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11486 of file app_voicemail_odbcstorage.c.
References ast_free.
Referenced by handle_unsubscribe().
11487 { 11488 ast_free(mwi_sub); 11489 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11574 of file app_voicemail_odbcstorage.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().
11575 { 11576 struct mwi_sub_task *mwist; 11577 11578 if (ast_event_get_type(event) != AST_EVENT_SUB) 11579 return; 11580 11581 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11582 return; 11583 11584 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11585 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11586 return; 11587 } 11588 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11589 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11590 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11591 11592 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11593 ast_free(mwist); 11594 } 11595 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11548 of file app_voicemail_odbcstorage.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().
11549 { 11550 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11551 11552 if (!uniqueid) { 11553 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11554 return; 11555 } 11556 11557 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11558 ast_free(uniqueid); 11559 return; 11560 } 11561 11562 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11563 ast_free(uniqueid); 11564 return; 11565 } 11566 11567 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11568 *uniqueid = u; 11569 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11570 ast_free(uniqueid); 11571 } 11572 }
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 7047 of file app_voicemail_odbcstorage.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().
07048 { 07049 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07050 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07051 const char *category; 07052 char *myserveremail = serveremail; 07053 07054 ast_channel_lock(chan); 07055 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07056 category = ast_strdupa(category); 07057 } 07058 ast_channel_unlock(chan); 07059 07060 #ifndef IMAP_STORAGE 07061 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07062 #else 07063 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07064 #endif 07065 make_file(fn, sizeof(fn), todir, msgnum); 07066 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07067 07068 if (!ast_strlen_zero(vmu->attachfmt)) { 07069 if (strstr(fmt, vmu->attachfmt)) 07070 fmt = vmu->attachfmt; 07071 else 07072 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); 07073 } 07074 07075 /* Attach only the first format */ 07076 fmt = ast_strdupa(fmt); 07077 stringp = fmt; 07078 strsep(&stringp, "|"); 07079 07080 if (!ast_strlen_zero(vmu->serveremail)) 07081 myserveremail = vmu->serveremail; 07082 07083 if (!ast_strlen_zero(vmu->email)) { 07084 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07085 07086 if (attach_user_voicemail) 07087 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07088 07089 /* XXX possible imap issue, should category be NULL XXX */ 07090 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07091 07092 if (attach_user_voicemail) 07093 DISPOSE(todir, msgnum); 07094 } 07095 07096 if (!ast_strlen_zero(vmu->pager)) { 07097 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07098 } 07099 07100 if (ast_test_flag(vmu, VM_DELETE)) 07101 DELETE(todir, msgnum, fn, vmu); 07102 07103 /* Leave voicemail for someone */ 07104 if (ast_app_has_voicemail(ext_context, NULL)) 07105 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07106 07107 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07108 07109 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); 07110 run_externnotify(vmu->context, vmu->mailbox, flag); 07111 07112 #ifdef IMAP_STORAGE 07113 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07114 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07115 vm_imap_delete(NULL, vms->curmsg, vmu); 07116 vms->newmessages--; /* Fix new message count */ 07117 } 07118 #endif 07119 07120 return 0; 07121 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4234 of file app_voicemail_odbcstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04235 { 04236 if (bio->linelength >= BASELINELEN) { 04237 if (fputs(ENDL, so) == EOF) { 04238 return -1; 04239 } 04240 04241 bio->linelength = 0; 04242 } 04243 04244 if (putc(((unsigned char) c), so) == EOF) { 04245 return -1; 04246 } 04247 04248 bio->linelength++; 04249 04250 return 1; 04251 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7896 of file app_voicemail_odbcstorage.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().
07897 { 07898 int count_msg, last_msg; 07899 07900 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07901 07902 /* Rename the member vmbox HERE so that we don't try to return before 07903 * we know what's going on. 07904 */ 07905 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07906 07907 /* Faster to make the directory than to check if it exists. */ 07908 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07909 07910 /* traverses directory using readdir (or select query for ODBC) */ 07911 count_msg = count_messages(vmu, vms->curdir); 07912 if (count_msg < 0) { 07913 return count_msg; 07914 } else { 07915 vms->lastmsg = count_msg - 1; 07916 } 07917 07918 if (vm_allocate_dh(vms, vmu, count_msg)) { 07919 return -1; 07920 } 07921 07922 /* 07923 The following test is needed in case sequencing gets messed up. 07924 There appears to be more than one way to mess up sequence, so 07925 we will not try to find all of the root causes--just fix it when 07926 detected. 07927 */ 07928 07929 if (vm_lock_path(vms->curdir)) { 07930 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07931 return ERROR_LOCK_PATH; 07932 } 07933 07934 /* for local storage, checks directory for messages up to maxmsg limit */ 07935 last_msg = last_message_index(vmu, vms->curdir); 07936 ast_unlock_path(vms->curdir); 07937 07938 if (last_msg < -1) { 07939 return last_msg; 07940 } else if (vms->lastmsg != last_msg) { 07941 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); 07942 resequence_mailbox(vmu, vms->curdir, count_msg); 07943 } 07944 07945 return 0; 07946 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7670 of file app_voicemail_odbcstorage.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
Referenced by vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), vm_browse_messages_zh(), and vm_execmain().
07671 { 07672 int res = 0; 07673 char filename[256], *cid; 07674 const char *origtime, *context, *category, *duration, *flag; 07675 struct ast_config *msg_cfg; 07676 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07677 07678 vms->starting = 0; 07679 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07680 adsi_message(chan, vms); 07681 if (!vms->curmsg) { 07682 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07683 } else if (vms->curmsg == vms->lastmsg) { 07684 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07685 } 07686 07687 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07688 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07689 msg_cfg = ast_config_load(filename, config_flags); 07690 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07691 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07692 return 0; 07693 } 07694 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07695 07696 /* Play the word urgent if we are listening to urgent messages */ 07697 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07698 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07699 } 07700 07701 if (!res) { 07702 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07703 /* POLISH syntax */ 07704 if (!strncasecmp(chan->language, "pl", 2)) { 07705 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07706 int ten, one; 07707 char nextmsg[256]; 07708 ten = (vms->curmsg + 1) / 10; 07709 one = (vms->curmsg + 1) % 10; 07710 07711 if (vms->curmsg < 20) { 07712 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07713 res = wait_file2(chan, vms, nextmsg); 07714 } else { 07715 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07716 res = wait_file2(chan, vms, nextmsg); 07717 if (one > 0) { 07718 if (!res) { 07719 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07720 res = wait_file2(chan, vms, nextmsg); 07721 } 07722 } 07723 } 07724 } 07725 if (!res) 07726 res = wait_file2(chan, vms, "vm-message"); 07727 /* HEBREW syntax */ 07728 } else if (!strncasecmp(chan->language, "he", 2)) { 07729 if (!vms->curmsg) { 07730 res = wait_file2(chan, vms, "vm-message"); 07731 res = wait_file2(chan, vms, "vm-first"); 07732 } else if (vms->curmsg == vms->lastmsg) { 07733 res = wait_file2(chan, vms, "vm-message"); 07734 res = wait_file2(chan, vms, "vm-last"); 07735 } else { 07736 res = wait_file2(chan, vms, "vm-message"); 07737 res = wait_file2(chan, vms, "vm-number"); 07738 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07739 } 07740 /* VIETNAMESE syntax */ 07741 } else if (!strncasecmp(chan->language, "vi", 2)) { 07742 if (!vms->curmsg) { 07743 res = wait_file2(chan, vms, "vm-message"); 07744 res = wait_file2(chan, vms, "vm-first"); 07745 } else if (vms->curmsg == vms->lastmsg) { 07746 res = wait_file2(chan, vms, "vm-message"); 07747 res = wait_file2(chan, vms, "vm-last"); 07748 } else { 07749 res = wait_file2(chan, vms, "vm-message"); 07750 res = wait_file2(chan, vms, "vm-number"); 07751 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07752 } 07753 } else { 07754 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07755 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07756 } else { /* DEFAULT syntax */ 07757 res = wait_file2(chan, vms, "vm-message"); 07758 } 07759 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07760 if (!res) { 07761 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07762 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07763 } 07764 } 07765 } 07766 } 07767 07768 if (!msg_cfg) { 07769 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07770 return 0; 07771 } 07772 07773 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07774 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07775 DISPOSE(vms->curdir, vms->curmsg); 07776 ast_config_destroy(msg_cfg); 07777 return 0; 07778 } 07779 07780 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07781 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07782 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07783 07784 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07785 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07786 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07787 if (!res) { 07788 res = play_message_category(chan, category); 07789 } 07790 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07791 res = play_message_datetime(chan, vmu, origtime, filename); 07792 } 07793 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07794 res = play_message_callerid(chan, vms, cid, context, 0); 07795 } 07796 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07797 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07798 } 07799 /* Allow pressing '1' to skip envelope / callerid */ 07800 if (res == '1') { 07801 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07802 res = 0; 07803 } 07804 ast_config_destroy(msg_cfg); 07805 07806 if (!res) { 07807 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07808 #ifdef IMAP_STORAGE 07809 ast_mutex_lock(&vms->lock); 07810 #endif 07811 vms->heard[vms->curmsg] = 1; 07812 #ifdef IMAP_STORAGE 07813 ast_mutex_unlock(&vms->lock); 07814 /*IMAP storage stores any prepended message from a forward 07815 * as a separate file from the rest of the message 07816 */ 07817 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07818 wait_file(chan, vms, vms->introfn); 07819 } 07820 #endif 07821 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07822 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07823 res = 0; 07824 } 07825 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07826 } 07827 DISPOSE(vms->curdir, vms->curmsg); 07828 return res; 07829 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7556 of file app_voicemail_odbcstorage.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().
07557 { 07558 int res = 0; 07559 int i; 07560 char *callerid, *name; 07561 char prefile[PATH_MAX] = ""; 07562 07563 07564 /* If voicemail cid is not enabled, or we didn't get cid or context from 07565 * the attribute file, leave now. 07566 * 07567 * TODO Still need to change this so that if this function is called by the 07568 * message envelope (and someone is explicitly requesting to hear the CID), 07569 * it does not check to see if CID is enabled in the config file. 07570 */ 07571 if ((cid == NULL)||(context == NULL)) 07572 return res; 07573 07574 /* Strip off caller ID number from name */ 07575 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07576 ast_callerid_parse(cid, &name, &callerid); 07577 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07578 /* Check for internal contexts and only */ 07579 /* say extension when the call didn't come from an internal context in the list */ 07580 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07581 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07582 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07583 break; 07584 } 07585 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07586 if (!res) { 07587 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07588 if (!ast_strlen_zero(prefile)) { 07589 /* See if we can find a recorded name for this person instead of their extension number */ 07590 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07591 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07592 if (!callback) 07593 res = wait_file2(chan, vms, "vm-from"); 07594 res = ast_stream_and_wait(chan, prefile, ""); 07595 } else { 07596 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07597 /* Say "from extension" as one saying to sound smoother */ 07598 if (!callback) 07599 res = wait_file2(chan, vms, "vm-from-extension"); 07600 res = ast_say_digit_str(chan, callerid, "", chan->language); 07601 } 07602 } 07603 } 07604 } else if (!res) { 07605 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07606 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07607 if (!callback) 07608 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07609 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07610 } 07611 } else { 07612 /* Number unknown */ 07613 ast_debug(1, "VM-CID: From an unknown number\n"); 07614 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07615 res = wait_file2(chan, vms, "vm-unknown-caller"); 07616 } 07617 return res; 07618 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7467 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07468 { 07469 int res = 0; 07470 07471 if (!ast_strlen_zero(category)) 07472 res = ast_play_and_wait(chan, category); 07473 07474 if (res) { 07475 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07476 res = 0; 07477 } 07478 07479 return res; 07480 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7482 of file app_voicemail_odbcstorage.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().
07483 { 07484 int res = 0; 07485 struct vm_zone *the_zone = NULL; 07486 time_t t; 07487 07488 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07489 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07490 return 0; 07491 } 07492 07493 /* Does this user have a timezone specified? */ 07494 if (!ast_strlen_zero(vmu->zonetag)) { 07495 /* Find the zone in the list */ 07496 struct vm_zone *z; 07497 AST_LIST_LOCK(&zones); 07498 AST_LIST_TRAVERSE(&zones, z, list) { 07499 if (!strcmp(z->name, vmu->zonetag)) { 07500 the_zone = z; 07501 break; 07502 } 07503 } 07504 AST_LIST_UNLOCK(&zones); 07505 } 07506 07507 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07508 #if 0 07509 /* Set the DIFF_* variables */ 07510 ast_localtime(&t, &time_now, NULL); 07511 tv_now = ast_tvnow(); 07512 ast_localtime(&tv_now, &time_then, NULL); 07513 07514 /* Day difference */ 07515 if (time_now.tm_year == time_then.tm_year) 07516 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07517 else 07518 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07519 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07520 07521 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07522 #endif 07523 if (the_zone) { 07524 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07525 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07526 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07527 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07528 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07529 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07530 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); 07531 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07532 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07533 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07534 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07535 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07536 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07537 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07538 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); 07539 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07540 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07541 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07542 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07543 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07544 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); 07545 } else { 07546 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07547 } 07548 #if 0 07549 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07550 #endif 07551 return res; 07552 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7620 of file app_voicemail_odbcstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), say_and_wait(), and wait_file2().
Referenced by play_message().
07621 { 07622 int res = 0; 07623 int durationm; 07624 int durations; 07625 /* Verify that we have a duration for the message */ 07626 if (duration == NULL) 07627 return res; 07628 07629 /* Convert from seconds to minutes */ 07630 durations = atoi(duration); 07631 durationm = (durations / 60); 07632 07633 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07634 07635 if ((!res) && (durationm >= minduration)) { 07636 res = wait_file2(chan, vms, "vm-duration"); 07637 07638 /* POLISH syntax */ 07639 if (!strncasecmp(chan->language, "pl", 2)) { 07640 div_t num = div(durationm, 10); 07641 07642 if (durationm == 1) { 07643 res = ast_play_and_wait(chan, "digits/1z"); 07644 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07645 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07646 if (num.rem == 2) { 07647 if (!num.quot) { 07648 res = ast_play_and_wait(chan, "digits/2-ie"); 07649 } else { 07650 res = say_and_wait(chan, durationm - 2 , chan->language); 07651 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07652 } 07653 } else { 07654 res = say_and_wait(chan, durationm, chan->language); 07655 } 07656 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07657 } else { 07658 res = say_and_wait(chan, durationm, chan->language); 07659 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07660 } 07661 /* DEFAULT syntax */ 07662 } else { 07663 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07664 res = wait_file2(chan, vms, "vm-minutes"); 07665 } 07666 } 07667 return res; 07668 }
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 13424 of file app_voicemail_odbcstorage.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().
13427 { 13428 /* Record message & let caller review or re-record it, or set options if applicable */ 13429 int res = 0; 13430 int cmd = 0; 13431 int max_attempts = 3; 13432 int attempts = 0; 13433 int recorded = 0; 13434 int msg_exists = 0; 13435 signed char zero_gain = 0; 13436 char tempfile[PATH_MAX]; 13437 char *acceptdtmf = "#"; 13438 char *canceldtmf = ""; 13439 int canceleddtmf = 0; 13440 13441 /* Note that urgent and private are for flagging messages as such in the future */ 13442 13443 /* barf if no pointer passed to store duration in */ 13444 if (duration == NULL) { 13445 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13446 return -1; 13447 } 13448 13449 if (!outsidecaller) 13450 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13451 else 13452 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13453 13454 cmd = '3'; /* Want to start by recording */ 13455 13456 while ((cmd >= 0) && (cmd != 't')) { 13457 switch (cmd) { 13458 case '1': 13459 if (!msg_exists) { 13460 /* In this case, 1 is to record a message */ 13461 cmd = '3'; 13462 break; 13463 } else { 13464 /* Otherwise 1 is to save the existing message */ 13465 ast_verb(3, "Saving message as is\n"); 13466 if (!outsidecaller) 13467 ast_filerename(tempfile, recordfile, NULL); 13468 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13469 if (!outsidecaller) { 13470 /* Saves to IMAP server only if imapgreeting=yes */ 13471 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13472 DISPOSE(recordfile, -1); 13473 } 13474 cmd = 't'; 13475 return res; 13476 } 13477 case '2': 13478 /* Review */ 13479 ast_verb(3, "Reviewing the message\n"); 13480 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13481 break; 13482 case '3': 13483 msg_exists = 0; 13484 /* Record */ 13485 if (recorded == 1) 13486 ast_verb(3, "Re-recording the message\n"); 13487 else 13488 ast_verb(3, "Recording the message\n"); 13489 13490 if (recorded && outsidecaller) { 13491 cmd = ast_play_and_wait(chan, INTRO); 13492 cmd = ast_play_and_wait(chan, "beep"); 13493 } 13494 recorded = 1; 13495 /* 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 */ 13496 if (record_gain) 13497 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13498 if (ast_test_flag(vmu, VM_OPERATOR)) 13499 canceldtmf = "0"; 13500 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13501 if (strchr(canceldtmf, cmd)) { 13502 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13503 canceleddtmf = 1; 13504 } 13505 if (record_gain) 13506 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13507 if (cmd == -1) { 13508 /* User has hung up, no options to give */ 13509 if (!outsidecaller) { 13510 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13511 ast_filedelete(tempfile, NULL); 13512 } 13513 return cmd; 13514 } 13515 if (cmd == '0') { 13516 break; 13517 } else if (cmd == '*') { 13518 break; 13519 #if 0 13520 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13521 /* Message is too short */ 13522 ast_verb(3, "Message too short\n"); 13523 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13524 cmd = ast_filedelete(tempfile, NULL); 13525 break; 13526 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13527 /* Message is all silence */ 13528 ast_verb(3, "Nothing recorded\n"); 13529 cmd = ast_filedelete(tempfile, NULL); 13530 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13531 if (!cmd) 13532 cmd = ast_play_and_wait(chan, "vm-speakup"); 13533 break; 13534 #endif 13535 } else { 13536 /* If all is well, a message exists */ 13537 msg_exists = 1; 13538 cmd = 0; 13539 } 13540 break; 13541 case '4': 13542 if (outsidecaller) { /* only mark vm messages */ 13543 /* Mark Urgent */ 13544 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13545 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13546 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13547 strcpy(flag, "Urgent"); 13548 } else if (flag) { 13549 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13550 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13551 strcpy(flag, ""); 13552 } else { 13553 ast_play_and_wait(chan, "vm-sorry"); 13554 } 13555 cmd = 0; 13556 } else { 13557 cmd = ast_play_and_wait(chan, "vm-sorry"); 13558 } 13559 break; 13560 case '5': 13561 case '6': 13562 case '7': 13563 case '8': 13564 case '9': 13565 case '*': 13566 case '#': 13567 cmd = ast_play_and_wait(chan, "vm-sorry"); 13568 break; 13569 #if 0 13570 /* XXX Commented out for the moment because of the dangers of deleting 13571 a message while recording (can put the message numbers out of sync) */ 13572 case '*': 13573 /* Cancel recording, delete message, offer to take another message*/ 13574 cmd = ast_play_and_wait(chan, "vm-deleted"); 13575 cmd = ast_filedelete(tempfile, NULL); 13576 if (outsidecaller) { 13577 res = vm_exec(chan, NULL); 13578 return res; 13579 } 13580 else 13581 return 1; 13582 #endif 13583 case '0': 13584 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13585 cmd = ast_play_and_wait(chan, "vm-sorry"); 13586 break; 13587 } 13588 if (msg_exists || recorded) { 13589 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13590 if (!cmd) 13591 cmd = ast_waitfordigit(chan, 3000); 13592 if (cmd == '1') { 13593 ast_filerename(tempfile, recordfile, NULL); 13594 ast_play_and_wait(chan, "vm-msgsaved"); 13595 cmd = '0'; 13596 } else if (cmd == '4') { 13597 if (flag) { 13598 ast_play_and_wait(chan, "vm-marked-urgent"); 13599 strcpy(flag, "Urgent"); 13600 } 13601 ast_play_and_wait(chan, "vm-msgsaved"); 13602 cmd = '0'; 13603 } else { 13604 ast_play_and_wait(chan, "vm-deleted"); 13605 DELETE(tempfile, -1, tempfile, vmu); 13606 cmd = '0'; 13607 } 13608 } 13609 return cmd; 13610 default: 13611 /* If the caller is an ouside caller, and the review option is enabled, 13612 allow them to review the message, but let the owner of the box review 13613 their OGM's */ 13614 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13615 return cmd; 13616 if (msg_exists) { 13617 cmd = ast_play_and_wait(chan, "vm-review"); 13618 if (!cmd && outsidecaller) { 13619 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13620 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13621 } else if (flag) { 13622 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13623 } 13624 } 13625 } else { 13626 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13627 if (!cmd) 13628 cmd = ast_waitfordigit(chan, 600); 13629 } 13630 13631 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13632 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13633 if (!cmd) 13634 cmd = ast_waitfordigit(chan, 600); 13635 } 13636 #if 0 13637 if (!cmd) 13638 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13639 #endif 13640 if (!cmd) 13641 cmd = ast_waitfordigit(chan, 6000); 13642 if (!cmd) { 13643 attempts++; 13644 } 13645 if (attempts > max_attempts) { 13646 cmd = 't'; 13647 } 13648 } 13649 } 13650 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13651 /* Hang up or timeout, so delete the recording. */ 13652 ast_filedelete(tempfile, NULL); 13653 } 13654 13655 if (cmd != 't' && outsidecaller) 13656 ast_play_and_wait(chan, "vm-goodbye"); 13657 13658 return cmd; 13659 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11435 of file app_voicemail_odbcstorage.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11436 { 11437 int new = 0, old = 0, urgent = 0; 11438 11439 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11440 11441 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11442 mwi_sub->old_urgent = urgent; 11443 mwi_sub->old_new = new; 11444 mwi_sub->old_old = old; 11445 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11446 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11447 } 11448 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11450 of file app_voicemail_odbcstorage.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
11451 { 11452 struct mwi_sub *mwi_sub; 11453 11454 AST_RWLIST_RDLOCK(&mwi_subs); 11455 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11456 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11457 poll_subscribed_mailbox(mwi_sub); 11458 } 11459 } 11460 AST_RWLIST_UNLOCK(&mwi_subs); 11461 }
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 994 of file app_voicemail_odbcstorage.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().
00995 { 00996 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00997 vmu->passwordlocation = passwordlocation; 00998 if (saydurationminfo) { 00999 vmu->saydurationm = saydurationminfo; 01000 } 01001 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01002 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01003 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01004 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01005 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01006 if (vmminsecs) { 01007 vmu->minsecs = vmminsecs; 01008 } 01009 if (vmmaxsecs) { 01010 vmu->maxsecs = vmmaxsecs; 01011 } 01012 if (maxmsg) { 01013 vmu->maxmsg = maxmsg; 01014 } 01015 if (maxdeletedmsg) { 01016 vmu->maxdeletedmsg = maxdeletedmsg; 01017 } 01018 vmu->volgain = volgain; 01019 ast_free(vmu->emailsubject); 01020 vmu->emailsubject = NULL; 01021 ast_free(vmu->emailbody); 01022 vmu->emailbody = NULL; 01023 #ifdef IMAP_STORAGE 01024 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01025 #endif 01026 }
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 4322 of file app_voicemail_odbcstorage.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
Referenced by make_email_file(), and sendpage().
04323 { 04324 char callerid[256]; 04325 char num[12]; 04326 char fromdir[256], fromfile[256]; 04327 struct ast_config *msg_cfg; 04328 const char *origcallerid, *origtime; 04329 char origcidname[80], origcidnum[80], origdate[80]; 04330 int inttime; 04331 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04332 04333 /* Prepare variables for substitution in email body and subject */ 04334 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04335 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04336 snprintf(num, sizeof(num), "%d", msgnum); 04337 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04338 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04339 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04340 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04341 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04342 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04343 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04344 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04345 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04346 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04347 04348 /* Retrieve info from VM attribute file */ 04349 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04350 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04351 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04352 strcat(fromfile, ".txt"); 04353 } 04354 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04355 if (option_debug > 0) { 04356 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04357 } 04358 return; 04359 } 04360 04361 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04362 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04363 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04364 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04365 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04366 } 04367 04368 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04369 struct timeval tv = { inttime, }; 04370 struct ast_tm tm; 04371 ast_localtime(&tv, &tm, NULL); 04372 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04373 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04374 } 04375 ast_config_destroy(msg_cfg); 04376 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7010 of file app_voicemail_odbcstorage.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().
07011 { 07012 struct ast_event *event; 07013 char *mailbox, *context; 07014 07015 /* Strip off @default */ 07016 context = mailbox = ast_strdupa(box); 07017 strsep(&context, "@"); 07018 if (ast_strlen_zero(context)) 07019 context = "default"; 07020 07021 if (!(event = ast_event_new(AST_EVENT_MWI, 07022 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07023 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07024 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07025 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07026 AST_EVENT_IE_END))) { 07027 return; 07028 } 07029 07030 ast_event_queue_and_cache(event); 07031 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12541 of file app_voicemail_odbcstorage.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), and LOG_NOTICE.
Referenced by actual_load_config(), and append_mailbox().
12541 { 12542 struct ast_config *pwconf; 12543 struct ast_flags config_flags = { 0 }; 12544 12545 pwconf = ast_config_load(secretfn, config_flags); 12546 if (pwconf) { 12547 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12548 if (val) { 12549 ast_copy_string(password, val, passwordlen); 12550 ast_config_destroy(pwconf); 12551 return; 12552 } 12553 ast_config_destroy(pwconf); 12554 } 12555 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12556 }
static int reload | ( | void | ) | [static] |
Definition at line 13071 of file app_voicemail_odbcstorage.c.
References load_config().
13072 { 13073 return load_config(1); 13074 }
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 3992 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03993 { 03994 char stxt[PATH_MAX]; 03995 char dtxt[PATH_MAX]; 03996 ast_filerename(sfn, dfn, NULL); 03997 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03998 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03999 if (ast_check_realtime("voicemail_data")) { 04000 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04001 } 04002 rename(stxt, dtxt); 04003 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6136 of file app_voicemail_odbcstorage.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().
06137 { 06138 /* we know the actual number of messages, so stop process when number is hit */ 06139 06140 int x, dest; 06141 char sfn[PATH_MAX]; 06142 char dfn[PATH_MAX]; 06143 06144 if (vm_lock_path(dir)) { 06145 return ERROR_LOCK_PATH; 06146 } 06147 06148 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06149 make_file(sfn, sizeof(sfn), dir, x); 06150 if (EXISTS(dir, x, sfn, NULL)) { 06151 06152 if (x != dest) { 06153 make_file(dfn, sizeof(dfn), dir, dest); 06154 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06155 } 06156 06157 dest++; 06158 } 06159 } 06160 ast_unlock_path(dir); 06161 06162 return dest; 06163 }
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 1464 of file app_voicemail_odbcstorage.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().
01465 { 01466 /* This function could be made to generate one from a database, too */ 01467 struct ast_vm_user *cur; 01468 int res = -1; 01469 AST_LIST_LOCK(&users); 01470 AST_LIST_TRAVERSE(&users, cur, list) { 01471 if ((!context || !strcasecmp(context, cur->context)) && 01472 (!strcasecmp(mailbox, cur->mailbox))) 01473 break; 01474 } 01475 if (cur) { 01476 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01477 res = 0; 01478 } 01479 AST_LIST_UNLOCK(&users); 01480 return res; 01481 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5507 of file app_voicemail_odbcstorage.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait_station(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, ast_smdi_mwi_message::fwd_st, inboxcount2(), and SMDI_MWI_WAIT_TIMEOUT.
Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
05508 { 05509 char arguments[255]; 05510 char ext_context[256] = ""; 05511 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05512 struct ast_smdi_mwi_message *mwi_msg; 05513 05514 if (!ast_strlen_zero(context)) 05515 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05516 else 05517 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05518 05519 if (smdi_iface) { 05520 if (ast_app_has_voicemail(ext_context, NULL)) 05521 ast_smdi_mwi_set(smdi_iface, extension); 05522 else 05523 ast_smdi_mwi_unset(smdi_iface, extension); 05524 05525 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05526 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05527 if (!strncmp(mwi_msg->cause, "INV", 3)) 05528 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05529 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05530 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05531 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05532 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05533 } else { 05534 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05535 } 05536 } 05537 05538 if (!ast_strlen_zero(externnotify)) { 05539 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05540 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05541 } else { 05542 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05543 ast_debug(1, "Executing %s\n", arguments); 05544 ast_safe_system(arguments); 05545 } 05546 } 05547 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6173 of file app_voicemail_odbcstorage.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().
06174 { 06175 #ifdef IMAP_STORAGE 06176 /* we must use mbox(x) folder names, and copy the message there */ 06177 /* simple. huh? */ 06178 char sequence[10]; 06179 char mailbox[256]; 06180 int res; 06181 06182 /* get the real IMAP message number for this message */ 06183 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06184 06185 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06186 ast_mutex_lock(&vms->lock); 06187 /* if save to Old folder, put in INBOX as read */ 06188 if (box == OLD_FOLDER) { 06189 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06190 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06191 } else if (box == NEW_FOLDER) { 06192 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06193 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06194 } 06195 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06196 ast_mutex_unlock(&vms->lock); 06197 return 0; 06198 } 06199 /* Create the folder if it don't exist */ 06200 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06201 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06202 if (mail_create(vms->mailstream, mailbox) == NIL) 06203 ast_debug(5, "Folder exists.\n"); 06204 else 06205 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06206 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06207 ast_mutex_unlock(&vms->lock); 06208 return res; 06209 #else 06210 char *dir = vms->curdir; 06211 char *username = vms->username; 06212 char *context = vmu->context; 06213 char sfn[PATH_MAX]; 06214 char dfn[PATH_MAX]; 06215 char ddir[PATH_MAX]; 06216 const char *dbox = mbox(vmu, box); 06217 int x, i; 06218 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06219 06220 if (vm_lock_path(ddir)) 06221 return ERROR_LOCK_PATH; 06222 06223 x = last_message_index(vmu, ddir) + 1; 06224 06225 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06226 x--; 06227 for (i = 1; i <= x; i++) { 06228 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06229 make_file(sfn, sizeof(sfn), ddir, i); 06230 make_file(dfn, sizeof(dfn), ddir, i - 1); 06231 if (EXISTS(ddir, i, sfn, NULL)) { 06232 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06233 } else 06234 break; 06235 } 06236 } else { 06237 if (x >= vmu->maxmsg) { 06238 ast_unlock_path(ddir); 06239 return -1; 06240 } 06241 } 06242 make_file(sfn, sizeof(sfn), dir, msg); 06243 make_file(dfn, sizeof(dfn), ddir, x); 06244 if (strcmp(sfn, dfn)) { 06245 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06246 } 06247 ast_unlock_path(ddir); 06248 #endif 06249 return 0; 06250 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6166 of file app_voicemail_odbcstorage.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().
06167 { 06168 int d; 06169 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06170 return d; 06171 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12527 of file app_voicemail_odbcstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.
Referenced by load_module(), and vmsayname_exec().
12528 { 12529 int res = -1; 12530 char dir[PATH_MAX]; 12531 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12532 ast_debug(2, "About to try retrieving name file %s\n", dir); 12533 RETRIEVE(dir, -1, mailbox, context); 12534 if (ast_fileexists(dir, NULL, NULL)) { 12535 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12536 } 12537 DISPOSE(dir, -1); 12538 return res; 12539 }
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 4837 of file app_voicemail_odbcstorage.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().
04838 { 04839 FILE *p = NULL; 04840 char tmp[80] = "/tmp/astmail-XXXXXX"; 04841 char tmp2[256]; 04842 char *stringp; 04843 04844 if (vmu && ast_strlen_zero(vmu->email)) { 04845 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04846 return(0); 04847 } 04848 04849 /* Mail only the first format */ 04850 format = ast_strdupa(format); 04851 stringp = format; 04852 strsep(&stringp, "|"); 04853 04854 if (!strcmp(format, "wav49")) 04855 format = "WAV"; 04856 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04857 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04858 command hangs */ 04859 if ((p = vm_mkftemp(tmp)) == NULL) { 04860 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04861 return -1; 04862 } else { 04863 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04864 fclose(p); 04865 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04866 ast_safe_system(tmp2); 04867 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04868 } 04869 return 0; 04870 }
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 4872 of file app_voicemail_odbcstorage.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().
04873 { 04874 char enc_cidnum[256], enc_cidname[256]; 04875 char date[256]; 04876 char host[MAXHOSTNAMELEN] = ""; 04877 char who[256]; 04878 char dur[PATH_MAX]; 04879 char tmp[80] = "/tmp/astmail-XXXXXX"; 04880 char tmp2[PATH_MAX]; 04881 struct ast_tm tm; 04882 FILE *p; 04883 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04884 04885 if (!str1 || !str2) { 04886 ast_free(str1); 04887 ast_free(str2); 04888 return -1; 04889 } 04890 04891 if (cidnum) { 04892 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04893 } 04894 if (cidname) { 04895 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04896 } 04897 04898 if ((p = vm_mkftemp(tmp)) == NULL) { 04899 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04900 ast_free(str1); 04901 ast_free(str2); 04902 return -1; 04903 } 04904 gethostname(host, sizeof(host)-1); 04905 if (strchr(srcemail, '@')) { 04906 ast_copy_string(who, srcemail, sizeof(who)); 04907 } else { 04908 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04909 } 04910 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04911 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04912 fprintf(p, "Date: %s\n", date); 04913 04914 /* Reformat for custom pager format */ 04915 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04916 04917 if (!ast_strlen_zero(pagerfromstring)) { 04918 struct ast_channel *ast; 04919 if ((ast = ast_dummy_channel_alloc())) { 04920 char *ptr; 04921 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04922 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04923 04924 if (check_mime(ast_str_buffer(str1))) { 04925 int first_line = 1; 04926 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04927 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04928 *ptr = '\0'; 04929 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04930 first_line = 0; 04931 /* Substring is smaller, so this will never grow */ 04932 ast_str_set(&str2, 0, "%s", ptr + 1); 04933 } 04934 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04935 } else { 04936 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04937 } 04938 ast = ast_channel_unref(ast); 04939 } else { 04940 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04941 } 04942 } else { 04943 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04944 } 04945 04946 if (check_mime(vmu->fullname)) { 04947 int first_line = 1; 04948 char *ptr; 04949 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04950 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04951 *ptr = '\0'; 04952 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04953 first_line = 0; 04954 /* Substring is smaller, so this will never grow */ 04955 ast_str_set(&str2, 0, "%s", ptr + 1); 04956 } 04957 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04958 } else { 04959 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04960 } 04961 04962 if (!ast_strlen_zero(pagersubject)) { 04963 struct ast_channel *ast; 04964 if ((ast = ast_dummy_channel_alloc())) { 04965 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04966 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04967 if (check_mime(ast_str_buffer(str1))) { 04968 int first_line = 1; 04969 char *ptr; 04970 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04971 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04972 *ptr = '\0'; 04973 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04974 first_line = 0; 04975 /* Substring is smaller, so this will never grow */ 04976 ast_str_set(&str2, 0, "%s", ptr + 1); 04977 } 04978 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04979 } else { 04980 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04981 } 04982 ast = ast_channel_unref(ast); 04983 } else { 04984 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04985 } 04986 } else { 04987 if (ast_strlen_zero(flag)) { 04988 fprintf(p, "Subject: New VM\n\n"); 04989 } else { 04990 fprintf(p, "Subject: New %s VM\n\n", flag); 04991 } 04992 } 04993 04994 if (pagerbody) { 04995 struct ast_channel *ast; 04996 if ((ast = ast_dummy_channel_alloc())) { 04997 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04998 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 04999 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05000 ast = ast_channel_unref(ast); 05001 } else { 05002 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05003 } 05004 } else { 05005 fprintf(p, "New %s long %s msg in box %s\n" 05006 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05007 } 05008 05009 fclose(p); 05010 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05011 ast_safe_system(tmp2); 05012 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05013 ast_free(str1); 05014 ast_free(str2); 05015 return 0; 05016 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11092 of file app_voicemail_odbcstorage.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().
11093 { 11094 struct ast_config *cfg; 11095 const char *cat = NULL; 11096 11097 if (!(cfg = ast_load_realtime_multientry("voicemail", 11098 "context", context, SENTINEL))) { 11099 return CLI_FAILURE; 11100 } 11101 11102 ast_cli(fd, 11103 "\n" 11104 "=============================================================\n" 11105 "=== Configured Voicemail Users ==============================\n" 11106 "=============================================================\n" 11107 "===\n"); 11108 11109 while ((cat = ast_category_browse(cfg, cat))) { 11110 struct ast_variable *var = NULL; 11111 ast_cli(fd, 11112 "=== Mailbox ...\n" 11113 "===\n"); 11114 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11115 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11116 ast_cli(fd, 11117 "===\n" 11118 "=== ---------------------------------------------------------\n" 11119 "===\n"); 11120 } 11121 11122 ast_cli(fd, 11123 "=============================================================\n" 11124 "\n"); 11125 11126 ast_config_destroy(cfg); 11127 11128 return CLI_SUCCESS; 11129 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11597 of file app_voicemail_odbcstorage.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().
11598 { 11599 int errcode; 11600 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11601 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11602 AST_EVENT_IE_END); 11603 11604 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11605 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11606 AST_EVENT_IE_END); 11607 11608 if (mwi_sub_sub) 11609 ast_event_report_subs(mwi_sub_sub); 11610 11611 poll_thread_run = 1; 11612 11613 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11614 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11615 } 11616 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11618 of file app_voicemail_odbcstorage.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().
11619 { 11620 poll_thread_run = 0; 11621 11622 if (mwi_sub_sub) { 11623 ast_event_unsubscribe(mwi_sub_sub); 11624 mwi_sub_sub = NULL; 11625 } 11626 11627 if (mwi_unsub_sub) { 11628 ast_event_unsubscribe(mwi_unsub_sub); 11629 mwi_unsub_sub = NULL; 11630 } 11631 11632 ast_mutex_lock(&poll_lock); 11633 ast_cond_signal(&poll_cond); 11634 ast_mutex_unlock(&poll_lock); 11635 11636 pthread_join(poll_thread, NULL); 11637 11638 poll_thread = AST_PTHREADT_NULL; 11639 }
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 964 of file app_voicemail_odbcstorage.c.
Referenced by make_email_file(), and sendpage().
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11764 of file app_voicemail_odbcstorage.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().
11765 { 11766 char *current; 11767 11768 /* Add 16 for fudge factor */ 11769 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11770 11771 ast_str_reset(str); 11772 11773 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11774 for (current = (char *) value; *current; current++) { 11775 if (*current == '\\') { 11776 current++; 11777 if (!*current) { 11778 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11779 break; 11780 } 11781 switch (*current) { 11782 case '\\': 11783 ast_str_append(&str, 0, "\\"); 11784 break; 11785 case 'r': 11786 ast_str_append(&str, 0, "\r"); 11787 break; 11788 case 'n': 11789 #ifdef IMAP_STORAGE 11790 if (!str->used || str->str[str->used - 1] != '\r') { 11791 ast_str_append(&str, 0, "\r"); 11792 } 11793 #endif 11794 ast_str_append(&str, 0, "\n"); 11795 break; 11796 case 't': 11797 ast_str_append(&str, 0, "\t"); 11798 break; 11799 default: 11800 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11801 break; 11802 } 11803 } else { 11804 ast_str_append(&str, 0, "%c", *current); 11805 } 11806 } 11807 11808 return ast_str_buffer(str); 11809 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13076 of file app_voicemail_odbcstorage.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().
13077 { 13078 int res; 13079 13080 res = ast_unregister_application(app); 13081 res |= ast_unregister_application(app2); 13082 res |= ast_unregister_application(app3); 13083 res |= ast_unregister_application(app4); 13084 res |= ast_unregister_application(sayname_app); 13085 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13086 res |= ast_manager_unregister("VoicemailUsersList"); 13087 res |= ast_data_unregister(NULL); 13088 #ifdef TEST_FRAMEWORK 13089 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13090 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13091 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13092 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13093 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13094 #endif 13095 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13096 ast_uninstall_vm_functions(); 13097 ao2_ref(inprocess_container, -1); 13098 13099 if (poll_thread != AST_PTHREADT_NULL) 13100 stop_poll_thread(); 13101 13102 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13103 ast_unload_realtime("voicemail"); 13104 ast_unload_realtime("voicemail_data"); 13105 13106 free_vm_users(); 13107 free_vm_zones(); 13108 return res; 13109 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1734 of file app_voicemail_odbcstorage.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().
01734 { 01735 01736 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01737 01738 /* remove old allocation */ 01739 if (vms->deleted) { 01740 ast_free(vms->deleted); 01741 vms->deleted = NULL; 01742 } 01743 if (vms->heard) { 01744 ast_free(vms->heard); 01745 vms->heard = NULL; 01746 } 01747 vms->dh_arraysize = 0; 01748 01749 if (arraysize > 0) { 01750 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01751 return -1; 01752 } 01753 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01754 ast_free(vms->deleted); 01755 vms->deleted = NULL; 01756 return -1; 01757 } 01758 vms->dh_arraysize = arraysize; 01759 } 01760 01761 return 0; 01762 }
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 9768 of file app_voicemail_odbcstorage.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, find_user(), ast_party_caller::id, ast_party_id::number, ast_vm_user::password, S_COR, ast_party_number::str, and ast_party_number::valid.
Referenced by vm_execmain(), and vmauthenticate().
09771 { 09772 int useadsi = 0, valid = 0, logretries = 0; 09773 char password[AST_MAX_EXTENSION]="", *passptr; 09774 struct ast_vm_user vmus, *vmu = NULL; 09775 09776 /* If ADSI is supported, setup login screen */ 09777 adsi_begin(chan, &useadsi); 09778 if (!skipuser && useadsi) 09779 adsi_login(chan); 09780 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09781 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09782 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09783 return -1; 09784 } 09785 09786 /* Authenticate them and get their mailbox/password */ 09787 09788 while (!valid && (logretries < max_logins)) { 09789 /* Prompt for, and read in the username */ 09790 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09791 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09792 return -1; 09793 } 09794 if (ast_strlen_zero(mailbox)) { 09795 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09796 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09797 } else { 09798 ast_verb(3, "Username not entered\n"); 09799 return -1; 09800 } 09801 } else if (mailbox[0] == '*') { 09802 /* user entered '*' */ 09803 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09804 if (ast_exists_extension(chan, chan->context, "a", 1, 09805 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09806 return -1; 09807 } 09808 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09809 mailbox[0] = '\0'; 09810 } 09811 09812 if (useadsi) 09813 adsi_password(chan); 09814 09815 if (!ast_strlen_zero(prefix)) { 09816 char fullusername[80] = ""; 09817 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09818 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09819 ast_copy_string(mailbox, fullusername, mailbox_size); 09820 } 09821 09822 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09823 vmu = find_user(&vmus, context, mailbox); 09824 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09825 /* saved password is blank, so don't bother asking */ 09826 password[0] = '\0'; 09827 } else { 09828 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09829 if (ast_streamfile(chan, vm_password, chan->language)) { 09830 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09831 return -1; 09832 } 09833 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09834 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09835 return -1; 09836 } else if (password[0] == '*') { 09837 /* user entered '*' */ 09838 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09839 if (ast_exists_extension(chan, chan->context, "a", 1, 09840 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09841 mailbox[0] = '*'; 09842 return -1; 09843 } 09844 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09845 mailbox[0] = '\0'; 09846 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09847 vmu = NULL; 09848 } 09849 } 09850 09851 if (vmu) { 09852 passptr = vmu->password; 09853 if (passptr[0] == '-') passptr++; 09854 } 09855 if (vmu && !strcmp(passptr, password)) 09856 valid++; 09857 else { 09858 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09859 if (!ast_strlen_zero(prefix)) 09860 mailbox[0] = '\0'; 09861 } 09862 logretries++; 09863 if (!valid) { 09864 if (skipuser || logretries >= max_logins) { 09865 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09866 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09867 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09868 return -1; 09869 } 09870 } else { 09871 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09872 if (useadsi) 09873 adsi_login(chan); 09874 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09875 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09876 return -1; 09877 } 09878 } 09879 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09880 return -1; 09881 } 09882 } 09883 if (!valid && (logretries >= max_logins)) { 09884 ast_stopstream(chan); 09885 ast_play_and_wait(chan, "vm-goodbye"); 09886 return -1; 09887 } 09888 if (vmu && !skipuser) { 09889 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09890 } 09891 return 0; 09892 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10987 of file app_voicemail_odbcstorage.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().
10988 { 10989 struct ast_vm_user svm; 10990 char *context, *box; 10991 AST_DECLARE_APP_ARGS(args, 10992 AST_APP_ARG(mbox); 10993 AST_APP_ARG(options); 10994 ); 10995 static int dep_warning = 0; 10996 10997 if (ast_strlen_zero(data)) { 10998 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10999 return -1; 11000 } 11001 11002 if (!dep_warning) { 11003 dep_warning = 1; 11004 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11005 } 11006 11007 box = ast_strdupa(data); 11008 11009 AST_STANDARD_APP_ARGS(args, box); 11010 11011 if (args.options) { 11012 } 11013 11014 if ((context = strchr(args.mbox, '@'))) { 11015 *context = '\0'; 11016 context++; 11017 } 11018 11019 if (find_user(&svm, context, args.mbox)) { 11020 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11021 } else 11022 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11023 11024 return 0; 11025 }
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 9747 of file app_voicemail_odbcstorage.c.
References vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), and vm_browse_messages_zh().
Referenced by vm_execmain().
09748 { 09749 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09750 return vm_browse_messages_es(chan, vms, vmu); 09751 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09752 return vm_browse_messages_gr(chan, vms, vmu); 09753 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09754 return vm_browse_messages_he(chan, vms, vmu); 09755 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09756 return vm_browse_messages_it(chan, vms, vmu); 09757 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09758 return vm_browse_messages_pt(chan, vms, vmu); 09759 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09760 return vm_browse_messages_vi(chan, vms, vmu); 09761 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09762 return vm_browse_messages_zh(chan, vms, vmu); 09763 } else { /* Default to English syntax */ 09764 return vm_browse_messages_en(chan, vms, vmu); 09765 } 09766 }
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 9586 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09587 { 09588 int cmd = 0; 09589 09590 if (vms->lastmsg > -1) { 09591 cmd = play_message(chan, vmu, vms); 09592 } else { 09593 cmd = ast_play_and_wait(chan, "vm-youhave"); 09594 if (!cmd) 09595 cmd = ast_play_and_wait(chan, "vm-no"); 09596 if (!cmd) { 09597 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09598 cmd = ast_play_and_wait(chan, vms->fn); 09599 } 09600 if (!cmd) 09601 cmd = ast_play_and_wait(chan, "vm-messages"); 09602 } 09603 return cmd; 09604 }
static int vm_browse_messages_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Spanish syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9640 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09641 { 09642 int cmd; 09643 09644 if (vms->lastmsg > -1) { 09645 cmd = play_message(chan, vmu, vms); 09646 } else { 09647 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09648 if (!cmd) 09649 cmd = ast_play_and_wait(chan, "vm-messages"); 09650 if (!cmd) { 09651 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09652 cmd = ast_play_and_wait(chan, vms->fn); 09653 } 09654 } 09655 return cmd; 09656 }
static int vm_browse_messages_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Greek syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9534 of file app_voicemail_odbcstorage.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().
09535 { 09536 int cmd = 0; 09537 09538 if (vms->lastmsg > -1) { 09539 cmd = play_message(chan, vmu, vms); 09540 } else { 09541 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09542 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09543 if (!cmd) { 09544 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09545 cmd = ast_play_and_wait(chan, vms->fn); 09546 } 09547 if (!cmd) 09548 cmd = ast_play_and_wait(chan, "vm-messages"); 09549 } else { 09550 if (!cmd) 09551 cmd = ast_play_and_wait(chan, "vm-messages"); 09552 if (!cmd) { 09553 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09554 cmd = ast_play_and_wait(chan, vms->fn); 09555 } 09556 } 09557 } 09558 return cmd; 09559 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9562 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09563 { 09564 int cmd = 0; 09565 09566 if (vms->lastmsg > -1) { 09567 cmd = play_message(chan, vmu, vms); 09568 } else { 09569 if (!strcasecmp(vms->fn, "INBOX")) { 09570 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09571 } else { 09572 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09573 } 09574 } 09575 return cmd; 09576 }
static int vm_browse_messages_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Italian syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9614 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09615 { 09616 int cmd; 09617 09618 if (vms->lastmsg > -1) { 09619 cmd = play_message(chan, vmu, vms); 09620 } else { 09621 cmd = ast_play_and_wait(chan, "vm-no"); 09622 if (!cmd) 09623 cmd = ast_play_and_wait(chan, "vm-message"); 09624 if (!cmd) { 09625 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09626 cmd = ast_play_and_wait(chan, vms->fn); 09627 } 09628 } 09629 return cmd; 09630 }
static int vm_browse_messages_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Portuguese syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9666 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09667 { 09668 int cmd; 09669 09670 if (vms->lastmsg > -1) { 09671 cmd = play_message(chan, vmu, vms); 09672 } else { 09673 cmd = ast_play_and_wait(chan, "vm-no"); 09674 if (!cmd) { 09675 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09676 cmd = ast_play_and_wait(chan, vms->fn); 09677 } 09678 if (!cmd) 09679 cmd = ast_play_and_wait(chan, "vm-messages"); 09680 } 09681 return cmd; 09682 }
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 9720 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09721 { 09722 int cmd = 0; 09723 09724 if (vms->lastmsg > -1) { 09725 cmd = play_message(chan, vmu, vms); 09726 } else { 09727 cmd = ast_play_and_wait(chan, "vm-no"); 09728 if (!cmd) { 09729 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09730 cmd = ast_play_and_wait(chan, vms->fn); 09731 } 09732 } 09733 return cmd; 09734 }
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 9692 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09693 { 09694 int cmd; 09695 09696 if (vms->lastmsg > -1) { 09697 cmd = play_message(chan, vmu, vms); 09698 } else { 09699 cmd = ast_play_and_wait(chan, "vm-you"); 09700 if (!cmd) 09701 cmd = ast_play_and_wait(chan, "vm-haveno"); 09702 if (!cmd) 09703 cmd = ast_play_and_wait(chan, "vm-messages"); 09704 if (!cmd) { 09705 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09706 cmd = ast_play_and_wait(chan, vms->fn); 09707 } 09708 } 09709 return cmd; 09710 }
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 1490 of file app_voicemail_odbcstorage.c.
References ast_alloca, ast_category_browse(), ast_category_get(), ast_config_load, ast_config_text_file_save(), ast_copy_string(), ast_debug, ast_free, ast_log(), AST_LOG_WARNING, ast_test_suite_event_notify, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), value, var, VOICEMAIL_CONFIG, and write_password_to_file().
Referenced by vm_newuser(), and vm_options().
01491 { 01492 struct ast_config *cfg = NULL; 01493 struct ast_variable *var = NULL; 01494 struct ast_category *cat = NULL; 01495 char *category = NULL, *value = NULL, *new = NULL; 01496 const char *tmp = NULL; 01497 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01498 char secretfn[PATH_MAX] = ""; 01499 int found = 0; 01500 01501 if (!change_password_realtime(vmu, newpassword)) 01502 return; 01503 01504 /* check if we should store the secret in the spool directory next to the messages */ 01505 switch (vmu->passwordlocation) { 01506 case OPT_PWLOC_SPOOLDIR: 01507 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01508 if (write_password_to_file(secretfn, newpassword) == 0) { 01509 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01510 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01511 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01512 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01513 break; 01514 } else { 01515 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01516 } 01517 /* Fall-through */ 01518 case OPT_PWLOC_VOICEMAILCONF: 01519 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01520 while ((category = ast_category_browse(cfg, category))) { 01521 if (!strcasecmp(category, vmu->context)) { 01522 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01523 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01524 break; 01525 } 01526 value = strstr(tmp, ","); 01527 if (!value) { 01528 new = ast_alloca(strlen(newpassword)+1); 01529 sprintf(new, "%s", newpassword); 01530 } else { 01531 new = ast_alloca((strlen(value) + strlen(newpassword) + 1)); 01532 sprintf(new, "%s%s", newpassword, value); 01533 } 01534 if (!(cat = ast_category_get(cfg, category))) { 01535 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01536 break; 01537 } 01538 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01539 found = 1; 01540 } 01541 } 01542 /* save the results */ 01543 if (found) { 01544 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01545 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01546 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01547 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01548 break; 01549 } 01550 } 01551 /* Fall-through */ 01552 case OPT_PWLOC_USERSCONF: 01553 /* check users.conf and update the password stored for the mailbox */ 01554 /* if no vmsecret entry exists create one. */ 01555 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01556 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01557 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01558 ast_debug(4, "users.conf: %s\n", category); 01559 if (!strcasecmp(category, vmu->mailbox)) { 01560 if (!ast_variable_retrieve(cfg, category, "vmsecret")) { 01561 ast_debug(3, "looks like we need to make vmsecret!\n"); 01562 var = ast_variable_new("vmsecret", newpassword, ""); 01563 } else { 01564 var = NULL; 01565 } 01566 new = ast_alloca(strlen(newpassword) + 1); 01567 sprintf(new, "%s", newpassword); 01568 if (!(cat = ast_category_get(cfg, category))) { 01569 ast_debug(4, "failed to get category!\n"); 01570 ast_free(var); 01571 break; 01572 } 01573 if (!var) { 01574 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01575 } else { 01576 ast_variable_append(cat, var); 01577 } 01578 found = 1; 01579 break; 01580 } 01581 } 01582 /* save the results and clean things up */ 01583 if (found) { 01584 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01585 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01586 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01587 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01588 } 01589 } 01590 } 01591 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1593 of file app_voicemail_odbcstorage.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().
01594 { 01595 char buf[255]; 01596 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01597 ast_debug(1, "External password: %s\n",buf); 01598 if (!ast_safe_system(buf)) { 01599 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01600 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01601 /* Reset the password in memory, too */ 01602 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01603 } 01604 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1161 of file app_voicemail_odbcstorage.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().
01162 { 01163 int fds[2], pid = 0; 01164 01165 memset(buf, 0, len); 01166 01167 if (pipe(fds)) { 01168 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01169 } else { 01170 /* good to go*/ 01171 pid = ast_safe_fork(0); 01172 01173 if (pid < 0) { 01174 /* ok maybe not */ 01175 close(fds[0]); 01176 close(fds[1]); 01177 snprintf(buf, len, "FAILURE: Fork failed"); 01178 } else if (pid) { 01179 /* parent */ 01180 close(fds[1]); 01181 if (read(fds[0], buf, len) < 0) { 01182 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01183 } 01184 close(fds[0]); 01185 } else { 01186 /* child */ 01187 AST_DECLARE_APP_ARGS(arg, 01188 AST_APP_ARG(v)[20]; 01189 ); 01190 char *mycmd = ast_strdupa(command); 01191 01192 close(fds[0]); 01193 dup2(fds[1], STDOUT_FILENO); 01194 close(fds[1]); 01195 ast_close_fds_above_n(STDOUT_FILENO); 01196 01197 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01198 01199 execv(arg.v[0], arg.v); 01200 printf("FAILURE: %s", strerror(errno)); 01201 _exit(0); 01202 } 01203 } 01204 return buf; 01205 }
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 4176 of file app_voicemail_odbcstorage.c.
References ast_alloca, ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
Referenced by copy_message(), and notify_new_message().
04177 { 04178 char *txt; 04179 int txtsize = 0; 04180 04181 txtsize = (strlen(file) + 5)*sizeof(char); 04182 txt = ast_alloca(txtsize); 04183 /* Sprintf here would safe because we alloca'd exactly the right length, 04184 * but trying to eliminate all sprintf's anyhow 04185 */ 04186 if (ast_check_realtime("voicemail_data")) { 04187 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04188 } 04189 snprintf(txt, txtsize, "%s.txt", file); 04190 unlink(txt); 04191 return ast_filedelete(file, NULL); 04192 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10646 of file app_voicemail_odbcstorage.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().
10647 { 10648 int res = 0; 10649 char *tmp; 10650 struct leave_vm_options leave_options; 10651 struct ast_flags flags = { 0 }; 10652 char *opts[OPT_ARG_ARRAY_SIZE]; 10653 AST_DECLARE_APP_ARGS(args, 10654 AST_APP_ARG(argv0); 10655 AST_APP_ARG(argv1); 10656 ); 10657 10658 memset(&leave_options, 0, sizeof(leave_options)); 10659 10660 if (chan->_state != AST_STATE_UP) 10661 ast_answer(chan); 10662 10663 if (!ast_strlen_zero(data)) { 10664 tmp = ast_strdupa(data); 10665 AST_STANDARD_APP_ARGS(args, tmp); 10666 if (args.argc == 2) { 10667 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10668 return -1; 10669 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10670 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10671 int gain; 10672 10673 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10674 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10675 return -1; 10676 } else { 10677 leave_options.record_gain = (signed char) gain; 10678 } 10679 } 10680 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10681 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10682 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10683 } 10684 } 10685 } else { 10686 char temp[256]; 10687 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10688 if (res < 0) 10689 return res; 10690 if (ast_strlen_zero(temp)) 10691 return 0; 10692 args.argv0 = ast_strdupa(temp); 10693 } 10694 10695 res = leave_voicemail(chan, args.argv0, &leave_options); 10696 if (res == 't') { 10697 ast_play_and_wait(chan, "vm-goodbye"); 10698 res = 0; 10699 } 10700 10701 if (res == OPERATOR_EXIT) { 10702 res = 0; 10703 } 10704 10705 if (res == ERROR_LOCK_PATH) { 10706 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10707 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10708 res = 0; 10709 } 10710 10711 return res; 10712 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9894 of file app_voicemail_odbcstorage.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().
09895 { 09896 /* XXX This is, admittedly, some pretty horrendous code. For some 09897 reason it just seemed a lot easier to do with GOTO's. I feel 09898 like I'm back in my GWBASIC days. XXX */ 09899 int res = -1; 09900 int cmd = 0; 09901 int valid = 0; 09902 char prefixstr[80] =""; 09903 char ext_context[256]=""; 09904 int box; 09905 int useadsi = 0; 09906 int skipuser = 0; 09907 struct vm_state vms; 09908 struct ast_vm_user *vmu = NULL, vmus; 09909 char *context = NULL; 09910 int silentexit = 0; 09911 struct ast_flags flags = { 0 }; 09912 signed char record_gain = 0; 09913 int play_auto = 0; 09914 int play_folder = 0; 09915 int in_urgent = 0; 09916 #ifdef IMAP_STORAGE 09917 int deleted = 0; 09918 #endif 09919 09920 /* Add the vm_state to the active list and keep it active */ 09921 memset(&vms, 0, sizeof(vms)); 09922 09923 vms.lastmsg = -1; 09924 09925 memset(&vmus, 0, sizeof(vmus)); 09926 09927 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09928 if (chan->_state != AST_STATE_UP) { 09929 ast_debug(1, "Before ast_answer\n"); 09930 ast_answer(chan); 09931 } 09932 09933 if (!ast_strlen_zero(data)) { 09934 char *opts[OPT_ARG_ARRAY_SIZE]; 09935 char *parse; 09936 AST_DECLARE_APP_ARGS(args, 09937 AST_APP_ARG(argv0); 09938 AST_APP_ARG(argv1); 09939 ); 09940 09941 parse = ast_strdupa(data); 09942 09943 AST_STANDARD_APP_ARGS(args, parse); 09944 09945 if (args.argc == 2) { 09946 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09947 return -1; 09948 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09949 int gain; 09950 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09951 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09952 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09953 return -1; 09954 } else { 09955 record_gain = (signed char) gain; 09956 } 09957 } else { 09958 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09959 } 09960 } 09961 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09962 play_auto = 1; 09963 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09964 /* See if it is a folder name first */ 09965 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09966 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09967 play_folder = -1; 09968 } 09969 } else { 09970 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09971 } 09972 } else { 09973 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09974 } 09975 if (play_folder > 9 || play_folder < 0) { 09976 ast_log(AST_LOG_WARNING, 09977 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09978 opts[OPT_ARG_PLAYFOLDER]); 09979 play_folder = 0; 09980 } 09981 } 09982 } else { 09983 /* old style options parsing */ 09984 while (*(args.argv0)) { 09985 if (*(args.argv0) == 's') 09986 ast_set_flag(&flags, OPT_SILENT); 09987 else if (*(args.argv0) == 'p') 09988 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09989 else 09990 break; 09991 (args.argv0)++; 09992 } 09993 09994 } 09995 09996 valid = ast_test_flag(&flags, OPT_SILENT); 09997 09998 if ((context = strchr(args.argv0, '@'))) 09999 *context++ = '\0'; 10000 10001 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10002 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10003 else 10004 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10005 10006 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10007 skipuser++; 10008 else 10009 valid = 0; 10010 } 10011 10012 if (!valid) 10013 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10014 10015 ast_debug(1, "After vm_authenticate\n"); 10016 10017 if (vms.username[0] == '*') { 10018 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10019 10020 /* user entered '*' */ 10021 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10022 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10023 res = 0; /* prevent hangup */ 10024 goto out; 10025 } 10026 } 10027 10028 if (!res) { 10029 valid = 1; 10030 if (!skipuser) 10031 vmu = &vmus; 10032 } else { 10033 res = 0; 10034 } 10035 10036 /* If ADSI is supported, setup login screen */ 10037 adsi_begin(chan, &useadsi); 10038 10039 ast_test_suite_assert(valid); 10040 if (!valid) { 10041 goto out; 10042 } 10043 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10044 10045 #ifdef IMAP_STORAGE 10046 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10047 pthread_setspecific(ts_vmstate.key, &vms); 10048 10049 vms.interactive = 1; 10050 vms.updated = 1; 10051 if (vmu) 10052 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10053 vmstate_insert(&vms); 10054 init_vm_state(&vms); 10055 #endif 10056 10057 /* Set language from config to override channel language */ 10058 if (!ast_strlen_zero(vmu->language)) 10059 ast_string_field_set(chan, language, vmu->language); 10060 10061 /* Retrieve urgent, old and new message counts */ 10062 ast_debug(1, "Before open_mailbox\n"); 10063 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10064 if (res < 0) 10065 goto out; 10066 vms.oldmessages = vms.lastmsg + 1; 10067 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10068 /* check INBOX */ 10069 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10070 if (res < 0) 10071 goto out; 10072 vms.newmessages = vms.lastmsg + 1; 10073 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10074 /* Start in Urgent */ 10075 in_urgent = 1; 10076 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10077 if (res < 0) 10078 goto out; 10079 vms.urgentmessages = vms.lastmsg + 1; 10080 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10081 10082 /* Select proper mailbox FIRST!! */ 10083 if (play_auto) { 10084 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10085 if (vms.urgentmessages) { 10086 in_urgent = 1; 10087 res = open_mailbox(&vms, vmu, 11); 10088 } else { 10089 in_urgent = 0; 10090 res = open_mailbox(&vms, vmu, play_folder); 10091 } 10092 if (res < 0) 10093 goto out; 10094 10095 /* If there are no new messages, inform the user and hangup */ 10096 if (vms.lastmsg == -1) { 10097 in_urgent = 0; 10098 cmd = vm_browse_messages(chan, &vms, vmu); 10099 res = 0; 10100 goto out; 10101 } 10102 } else { 10103 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10104 /* If we only have old messages start here */ 10105 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10106 in_urgent = 0; 10107 play_folder = 1; 10108 if (res < 0) 10109 goto out; 10110 } else if (!vms.urgentmessages && vms.newmessages) { 10111 /* If we have new messages but none are urgent */ 10112 in_urgent = 0; 10113 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10114 if (res < 0) 10115 goto out; 10116 } 10117 } 10118 10119 if (useadsi) 10120 adsi_status(chan, &vms); 10121 res = 0; 10122 10123 /* Check to see if this is a new user */ 10124 if (!strcasecmp(vmu->mailbox, vmu->password) && 10125 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10126 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10127 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10128 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10129 if ((cmd == 't') || (cmd == '#')) { 10130 /* Timeout */ 10131 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10132 res = 0; 10133 goto out; 10134 } else if (cmd < 0) { 10135 /* Hangup */ 10136 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10137 res = -1; 10138 goto out; 10139 } 10140 } 10141 #ifdef IMAP_STORAGE 10142 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10143 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10144 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10145 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10146 } 10147 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10148 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10149 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10150 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10151 } 10152 #endif 10153 10154 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10155 if (play_auto) { 10156 cmd = '1'; 10157 } else { 10158 cmd = vm_intro(chan, vmu, &vms); 10159 } 10160 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10161 10162 vms.repeats = 0; 10163 vms.starting = 1; 10164 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10165 /* Run main menu */ 10166 switch (cmd) { 10167 case '1': /* First message */ 10168 vms.curmsg = 0; 10169 /* Fall through */ 10170 case '5': /* Play current message */ 10171 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10172 cmd = vm_browse_messages(chan, &vms, vmu); 10173 break; 10174 case '2': /* Change folders */ 10175 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10176 if (useadsi) 10177 adsi_folders(chan, 0, "Change to folder..."); 10178 10179 cmd = get_folder2(chan, "vm-changeto", 0); 10180 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10181 if (cmd == '#') { 10182 cmd = 0; 10183 } else if (cmd > 0) { 10184 cmd = cmd - '0'; 10185 res = close_mailbox(&vms, vmu); 10186 if (res == ERROR_LOCK_PATH) 10187 goto out; 10188 /* If folder is not urgent, set in_urgent to zero! */ 10189 if (cmd != 11) in_urgent = 0; 10190 res = open_mailbox(&vms, vmu, cmd); 10191 if (res < 0) 10192 goto out; 10193 play_folder = cmd; 10194 cmd = 0; 10195 } 10196 if (useadsi) 10197 adsi_status2(chan, &vms); 10198 10199 if (!cmd) { 10200 cmd = vm_play_folder_name(chan, vms.vmbox); 10201 } 10202 10203 vms.starting = 1; 10204 vms.curmsg = 0; 10205 break; 10206 case '3': /* Advanced options */ 10207 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10208 cmd = 0; 10209 vms.repeats = 0; 10210 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10211 switch (cmd) { 10212 case '1': /* Reply */ 10213 if (vms.lastmsg > -1 && !vms.starting) { 10214 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10215 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10216 res = cmd; 10217 goto out; 10218 } 10219 } else { 10220 cmd = ast_play_and_wait(chan, "vm-sorry"); 10221 } 10222 cmd = 't'; 10223 break; 10224 case '2': /* Callback */ 10225 if (!vms.starting) 10226 ast_verb(3, "Callback Requested\n"); 10227 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10228 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10229 if (cmd == 9) { 10230 silentexit = 1; 10231 goto out; 10232 } else if (cmd == ERROR_LOCK_PATH) { 10233 res = cmd; 10234 goto out; 10235 } 10236 } else { 10237 cmd = ast_play_and_wait(chan, "vm-sorry"); 10238 } 10239 cmd = 't'; 10240 break; 10241 case '3': /* Envelope */ 10242 if (vms.lastmsg > -1 && !vms.starting) { 10243 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10244 if (cmd == ERROR_LOCK_PATH) { 10245 res = cmd; 10246 goto out; 10247 } 10248 } else { 10249 cmd = ast_play_and_wait(chan, "vm-sorry"); 10250 } 10251 cmd = 't'; 10252 break; 10253 case '4': /* Dialout */ 10254 if (!ast_strlen_zero(vmu->dialout)) { 10255 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10256 if (cmd == 9) { 10257 silentexit = 1; 10258 goto out; 10259 } 10260 } else { 10261 cmd = ast_play_and_wait(chan, "vm-sorry"); 10262 } 10263 cmd = 't'; 10264 break; 10265 10266 case '5': /* Leave VoiceMail */ 10267 if (ast_test_flag(vmu, VM_SVMAIL)) { 10268 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10269 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10270 res = cmd; 10271 goto out; 10272 } 10273 } else { 10274 cmd = ast_play_and_wait(chan, "vm-sorry"); 10275 } 10276 cmd = 't'; 10277 break; 10278 10279 case '*': /* Return to main menu */ 10280 cmd = 't'; 10281 break; 10282 10283 default: 10284 cmd = 0; 10285 if (!vms.starting) { 10286 cmd = ast_play_and_wait(chan, "vm-toreply"); 10287 } 10288 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10289 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10290 } 10291 if (!cmd && !vms.starting) { 10292 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10293 } 10294 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10295 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10296 } 10297 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10298 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10299 } 10300 if (!cmd) { 10301 cmd = ast_play_and_wait(chan, "vm-starmain"); 10302 } 10303 if (!cmd) { 10304 cmd = ast_waitfordigit(chan, 6000); 10305 } 10306 if (!cmd) { 10307 vms.repeats++; 10308 } 10309 if (vms.repeats > 3) { 10310 cmd = 't'; 10311 } 10312 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10313 } 10314 } 10315 if (cmd == 't') { 10316 cmd = 0; 10317 vms.repeats = 0; 10318 } 10319 break; 10320 case '4': /* Go to the previous message */ 10321 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10322 if (vms.curmsg > 0) { 10323 vms.curmsg--; 10324 cmd = play_message(chan, vmu, &vms); 10325 } else { 10326 /* Check if we were listening to new 10327 messages. If so, go to Urgent messages 10328 instead of saying "no more messages" 10329 */ 10330 if (in_urgent == 0 && vms.urgentmessages > 0) { 10331 /* Check for Urgent messages */ 10332 in_urgent = 1; 10333 res = close_mailbox(&vms, vmu); 10334 if (res == ERROR_LOCK_PATH) 10335 goto out; 10336 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10337 if (res < 0) 10338 goto out; 10339 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10340 vms.curmsg = vms.lastmsg; 10341 if (vms.lastmsg < 0) { 10342 cmd = ast_play_and_wait(chan, "vm-nomore"); 10343 } 10344 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10345 vms.curmsg = vms.lastmsg; 10346 cmd = play_message(chan, vmu, &vms); 10347 } else { 10348 cmd = ast_play_and_wait(chan, "vm-nomore"); 10349 } 10350 } 10351 break; 10352 case '6': /* Go to the next message */ 10353 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10354 if (vms.curmsg < vms.lastmsg) { 10355 vms.curmsg++; 10356 cmd = play_message(chan, vmu, &vms); 10357 } else { 10358 if (in_urgent && vms.newmessages > 0) { 10359 /* Check if we were listening to urgent 10360 * messages. If so, go to regular new messages 10361 * instead of saying "no more messages" 10362 */ 10363 in_urgent = 0; 10364 res = close_mailbox(&vms, vmu); 10365 if (res == ERROR_LOCK_PATH) 10366 goto out; 10367 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10368 if (res < 0) 10369 goto out; 10370 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10371 vms.curmsg = -1; 10372 if (vms.lastmsg < 0) { 10373 cmd = ast_play_and_wait(chan, "vm-nomore"); 10374 } 10375 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10376 vms.curmsg = 0; 10377 cmd = play_message(chan, vmu, &vms); 10378 } else { 10379 cmd = ast_play_and_wait(chan, "vm-nomore"); 10380 } 10381 } 10382 break; 10383 case '7': /* Delete the current message */ 10384 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10385 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10386 if (useadsi) 10387 adsi_delete(chan, &vms); 10388 if (vms.deleted[vms.curmsg]) { 10389 if (play_folder == 0) { 10390 if (in_urgent) { 10391 vms.urgentmessages--; 10392 } else { 10393 vms.newmessages--; 10394 } 10395 } 10396 else if (play_folder == 1) 10397 vms.oldmessages--; 10398 cmd = ast_play_and_wait(chan, "vm-deleted"); 10399 } else { 10400 if (play_folder == 0) { 10401 if (in_urgent) { 10402 vms.urgentmessages++; 10403 } else { 10404 vms.newmessages++; 10405 } 10406 } 10407 else if (play_folder == 1) 10408 vms.oldmessages++; 10409 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10410 } 10411 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10412 if (vms.curmsg < vms.lastmsg) { 10413 vms.curmsg++; 10414 cmd = play_message(chan, vmu, &vms); 10415 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10416 vms.curmsg = 0; 10417 cmd = play_message(chan, vmu, &vms); 10418 } else { 10419 /* Check if we were listening to urgent 10420 messages. If so, go to regular new messages 10421 instead of saying "no more messages" 10422 */ 10423 if (in_urgent == 1) { 10424 /* Check for new messages */ 10425 in_urgent = 0; 10426 res = close_mailbox(&vms, vmu); 10427 if (res == ERROR_LOCK_PATH) 10428 goto out; 10429 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10430 if (res < 0) 10431 goto out; 10432 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10433 vms.curmsg = -1; 10434 if (vms.lastmsg < 0) { 10435 cmd = ast_play_and_wait(chan, "vm-nomore"); 10436 } 10437 } else { 10438 cmd = ast_play_and_wait(chan, "vm-nomore"); 10439 } 10440 } 10441 } 10442 } else /* Delete not valid if we haven't selected a message */ 10443 cmd = 0; 10444 #ifdef IMAP_STORAGE 10445 deleted = 1; 10446 #endif 10447 break; 10448 10449 case '8': /* Forward the current message */ 10450 if (vms.lastmsg > -1) { 10451 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10452 if (cmd == ERROR_LOCK_PATH) { 10453 res = cmd; 10454 goto out; 10455 } 10456 } else { 10457 /* Check if we were listening to urgent 10458 messages. If so, go to regular new messages 10459 instead of saying "no more messages" 10460 */ 10461 if (in_urgent == 1 && vms.newmessages > 0) { 10462 /* Check for new messages */ 10463 in_urgent = 0; 10464 res = close_mailbox(&vms, vmu); 10465 if (res == ERROR_LOCK_PATH) 10466 goto out; 10467 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10468 if (res < 0) 10469 goto out; 10470 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10471 vms.curmsg = -1; 10472 if (vms.lastmsg < 0) { 10473 cmd = ast_play_and_wait(chan, "vm-nomore"); 10474 } 10475 } else { 10476 cmd = ast_play_and_wait(chan, "vm-nomore"); 10477 } 10478 } 10479 break; 10480 case '9': /* Save message to folder */ 10481 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10482 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10483 /* No message selected */ 10484 cmd = 0; 10485 break; 10486 } 10487 if (useadsi) 10488 adsi_folders(chan, 1, "Save to folder..."); 10489 cmd = get_folder2(chan, "vm-savefolder", 1); 10490 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10491 box = 0; /* Shut up compiler */ 10492 if (cmd == '#') { 10493 cmd = 0; 10494 break; 10495 } else if (cmd > 0) { 10496 box = cmd = cmd - '0'; 10497 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10498 if (cmd == ERROR_LOCK_PATH) { 10499 res = cmd; 10500 goto out; 10501 #ifndef IMAP_STORAGE 10502 } else if (!cmd) { 10503 vms.deleted[vms.curmsg] = 1; 10504 #endif 10505 } else { 10506 vms.deleted[vms.curmsg] = 0; 10507 vms.heard[vms.curmsg] = 0; 10508 } 10509 } 10510 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10511 if (useadsi) 10512 adsi_message(chan, &vms); 10513 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10514 if (!cmd) { 10515 cmd = ast_play_and_wait(chan, "vm-message"); 10516 if (!cmd) 10517 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10518 if (!cmd) 10519 cmd = ast_play_and_wait(chan, "vm-savedto"); 10520 if (!cmd) 10521 cmd = vm_play_folder_name(chan, vms.fn); 10522 } else { 10523 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10524 } 10525 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10526 if (vms.curmsg < vms.lastmsg) { 10527 vms.curmsg++; 10528 cmd = play_message(chan, vmu, &vms); 10529 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10530 vms.curmsg = 0; 10531 cmd = play_message(chan, vmu, &vms); 10532 } else { 10533 /* Check if we were listening to urgent 10534 messages. If so, go to regular new messages 10535 instead of saying "no more messages" 10536 */ 10537 if (in_urgent == 1 && vms.newmessages > 0) { 10538 /* Check for new messages */ 10539 in_urgent = 0; 10540 res = close_mailbox(&vms, vmu); 10541 if (res == ERROR_LOCK_PATH) 10542 goto out; 10543 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10544 if (res < 0) 10545 goto out; 10546 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10547 vms.curmsg = -1; 10548 if (vms.lastmsg < 0) { 10549 cmd = ast_play_and_wait(chan, "vm-nomore"); 10550 } 10551 } else { 10552 cmd = ast_play_and_wait(chan, "vm-nomore"); 10553 } 10554 } 10555 } 10556 break; 10557 case '*': /* Help */ 10558 if (!vms.starting) { 10559 cmd = ast_play_and_wait(chan, "vm-onefor"); 10560 if (!strncasecmp(chan->language, "he", 2)) { 10561 cmd = ast_play_and_wait(chan, "vm-for"); 10562 } 10563 if (!cmd) 10564 cmd = vm_play_folder_name(chan, vms.vmbox); 10565 if (!cmd) 10566 cmd = ast_play_and_wait(chan, "vm-opts"); 10567 if (!cmd) 10568 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10569 } else 10570 cmd = 0; 10571 break; 10572 case '0': /* Mailbox options */ 10573 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10574 if (useadsi) 10575 adsi_status(chan, &vms); 10576 break; 10577 default: /* Nothing */ 10578 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10579 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10580 break; 10581 } 10582 } 10583 if ((cmd == 't') || (cmd == '#')) { 10584 /* Timeout */ 10585 res = 0; 10586 } else { 10587 /* Hangup */ 10588 res = -1; 10589 } 10590 10591 out: 10592 if (res > -1) { 10593 ast_stopstream(chan); 10594 adsi_goodbye(chan); 10595 if (valid && res != OPERATOR_EXIT) { 10596 if (silentexit) 10597 res = ast_play_and_wait(chan, "vm-dialout"); 10598 else 10599 res = ast_play_and_wait(chan, "vm-goodbye"); 10600 } 10601 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10602 res = 0; 10603 } 10604 if (useadsi) 10605 ast_adsi_unload_session(chan); 10606 } 10607 if (vmu) 10608 close_mailbox(&vms, vmu); 10609 if (valid) { 10610 int new = 0, old = 0, urgent = 0; 10611 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10612 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10613 /* Urgent flag not passwd to externnotify here */ 10614 run_externnotify(vmu->context, vmu->mailbox, NULL); 10615 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10616 queue_mwi_event(ext_context, urgent, new, old); 10617 } 10618 #ifdef IMAP_STORAGE 10619 /* expunge message - use UID Expunge if supported on IMAP server*/ 10620 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10621 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10622 ast_mutex_lock(&vms.lock); 10623 #ifdef HAVE_IMAP_TK2006 10624 if (LEVELUIDPLUS (vms.mailstream)) { 10625 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10626 } else 10627 #endif 10628 mail_expunge(vms.mailstream); 10629 ast_mutex_unlock(&vms.lock); 10630 } 10631 /* before we delete the state, we should copy pertinent info 10632 * back to the persistent model */ 10633 if (vmu) { 10634 vmstate_delete(&vms); 10635 } 10636 #endif 10637 if (vmu) 10638 free_user(vmu); 10639 10640 #ifdef IMAP_STORAGE 10641 pthread_setspecific(ts_vmstate.key, NULL); 10642 #endif 10643 return res; 10644 }
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 6854 of file app_voicemail_odbcstorage.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, and play_record_review().
Referenced by forward_message().
06856 { 06857 int cmd = 0; 06858 int retries = 0, prepend_duration = 0, already_recorded = 0; 06859 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06860 char textfile[PATH_MAX]; 06861 struct ast_config *msg_cfg; 06862 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06863 #ifndef IMAP_STORAGE 06864 signed char zero_gain = 0; 06865 #endif 06866 const char *duration_str; 06867 06868 /* Must always populate duration correctly */ 06869 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06870 strcpy(textfile, msgfile); 06871 strcpy(backup, msgfile); 06872 strcpy(backup_textfile, msgfile); 06873 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06874 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06875 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06876 06877 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06878 *duration = atoi(duration_str); 06879 } else { 06880 *duration = 0; 06881 } 06882 06883 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06884 if (cmd) 06885 retries = 0; 06886 switch (cmd) { 06887 case '1': 06888 06889 #ifdef IMAP_STORAGE 06890 /* Record new intro file */ 06891 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06892 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06893 ast_play_and_wait(chan, INTRO); 06894 ast_play_and_wait(chan, "beep"); 06895 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06896 if (cmd == -1) { 06897 break; 06898 } 06899 cmd = 't'; 06900 #else 06901 06902 /* prepend a message to the current message, update the metadata and return */ 06903 06904 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06905 strcpy(textfile, msgfile); 06906 strncat(textfile, ".txt", sizeof(textfile) - 1); 06907 *duration = 0; 06908 06909 /* if we can't read the message metadata, stop now */ 06910 if (!msg_cfg) { 06911 cmd = 0; 06912 break; 06913 } 06914 06915 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06916 #ifndef IMAP_STORAGE 06917 if (already_recorded) { 06918 ast_filecopy(backup, msgfile, NULL); 06919 copy(backup_textfile, textfile); 06920 } 06921 else { 06922 ast_filecopy(msgfile, backup, NULL); 06923 copy(textfile, backup_textfile); 06924 } 06925 #endif 06926 already_recorded = 1; 06927 06928 if (record_gain) 06929 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06930 06931 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06932 06933 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06934 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06935 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06936 ast_filerename(backup, msgfile, NULL); 06937 } 06938 06939 if (record_gain) 06940 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06941 06942 06943 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06944 *duration = atoi(duration_str); 06945 06946 if (prepend_duration) { 06947 struct ast_category *msg_cat; 06948 /* need enough space for a maximum-length message duration */ 06949 char duration_buf[12]; 06950 06951 *duration += prepend_duration; 06952 msg_cat = ast_category_get(msg_cfg, "message"); 06953 snprintf(duration_buf, 11, "%ld", *duration); 06954 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06955 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06956 } 06957 } 06958 06959 #endif 06960 break; 06961 case '2': 06962 /* NULL out introfile so we know there is no intro! */ 06963 #ifdef IMAP_STORAGE 06964 *vms->introfn = '\0'; 06965 #endif 06966 cmd = 't'; 06967 break; 06968 case '*': 06969 cmd = '*'; 06970 break; 06971 default: 06972 /* If time_out and return to menu, reset already_recorded */ 06973 already_recorded = 0; 06974 06975 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06976 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06977 if (!cmd) { 06978 cmd = ast_play_and_wait(chan, "vm-starmain"); 06979 /* "press star to return to the main menu" */ 06980 } 06981 if (!cmd) { 06982 cmd = ast_waitfordigit(chan, 6000); 06983 } 06984 if (!cmd) { 06985 retries++; 06986 } 06987 if (retries > 3) { 06988 cmd = '*'; /* Let's cancel this beast */ 06989 } 06990 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 06991 } 06992 } 06993 06994 if (msg_cfg) 06995 ast_config_destroy(msg_cfg); 06996 if (prepend_duration) 06997 *duration = prepend_duration; 06998 06999 if (already_recorded && cmd == -1) { 07000 /* restore original message if prepention cancelled */ 07001 ast_filerename(backup, msgfile, NULL); 07002 rename(backup_textfile, textfile); 07003 } 07004 07005 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07006 cmd = 0; 07007 return cmd; 07008 }
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 9209 of file app_voicemail_odbcstorage.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09210 { 09211 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09212 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09213 } else { /* Default to ENGLISH */ 09214 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09215 } 09216 }
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 9097 of file app_voicemail_odbcstorage.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().
09098 { 09099 int res = 0; 09100 /* Play instructions and wait for new command */ 09101 while (!res) { 09102 if (vms->starting) { 09103 if (vms->lastmsg > -1) { 09104 if (skipadvanced) 09105 res = ast_play_and_wait(chan, "vm-onefor-full"); 09106 else 09107 res = ast_play_and_wait(chan, "vm-onefor"); 09108 if (!res) 09109 res = vm_play_folder_name(chan, vms->vmbox); 09110 } 09111 if (!res) { 09112 if (skipadvanced) 09113 res = ast_play_and_wait(chan, "vm-opts-full"); 09114 else 09115 res = ast_play_and_wait(chan, "vm-opts"); 09116 } 09117 } else { 09118 /* Added for additional help */ 09119 if (skipadvanced) { 09120 res = ast_play_and_wait(chan, "vm-onefor-full"); 09121 if (!res) 09122 res = vm_play_folder_name(chan, vms->vmbox); 09123 res = ast_play_and_wait(chan, "vm-opts-full"); 09124 } 09125 /* Logic: 09126 * If the current message is not the first OR 09127 * if we're listening to the first new message and there are 09128 * also urgent messages, then prompt for navigation to the 09129 * previous message 09130 */ 09131 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09132 res = ast_play_and_wait(chan, "vm-prev"); 09133 } 09134 if (!res && !skipadvanced) 09135 res = ast_play_and_wait(chan, "vm-advopts"); 09136 if (!res) 09137 res = ast_play_and_wait(chan, "vm-repeat"); 09138 /* Logic: 09139 * If we're not listening to the last message OR 09140 * we're listening to the last urgent message and there are 09141 * also new non-urgent messages, then prompt for navigation 09142 * to the next message 09143 */ 09144 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09145 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09146 res = ast_play_and_wait(chan, "vm-next"); 09147 } 09148 if (!res) { 09149 int curmsg_deleted; 09150 #ifdef IMAP_STORAGE 09151 ast_mutex_lock(&vms->lock); 09152 #endif 09153 curmsg_deleted = vms->deleted[vms->curmsg]; 09154 #ifdef IMAP_STORAGE 09155 ast_mutex_unlock(&vms->lock); 09156 #endif 09157 if (!curmsg_deleted) { 09158 res = ast_play_and_wait(chan, "vm-delete"); 09159 } else { 09160 res = ast_play_and_wait(chan, "vm-undelete"); 09161 } 09162 if (!res) { 09163 res = ast_play_and_wait(chan, "vm-toforward"); 09164 } 09165 if (!res) { 09166 res = ast_play_and_wait(chan, "vm-savemessage"); 09167 } 09168 } 09169 } 09170 if (!res) { 09171 res = ast_play_and_wait(chan, "vm-helpexit"); 09172 } 09173 if (!res) 09174 res = ast_waitfordigit(chan, 6000); 09175 if (!res) { 09176 vms->repeats++; 09177 if (vms->repeats > 2) { 09178 res = 't'; 09179 } 09180 } 09181 } 09182 return res; 09183 }
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 9185 of file app_voicemail_odbcstorage.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().
09186 { 09187 int res = 0; 09188 /* Play instructions and wait for new command */ 09189 while (!res) { 09190 if (vms->lastmsg > -1) { 09191 res = ast_play_and_wait(chan, "vm-listen"); 09192 if (!res) 09193 res = vm_play_folder_name(chan, vms->vmbox); 09194 if (!res) 09195 res = ast_play_and_wait(chan, "press"); 09196 if (!res) 09197 res = ast_play_and_wait(chan, "digits/1"); 09198 } 09199 if (!res) 09200 res = ast_play_and_wait(chan, "vm-opts"); 09201 if (!res) { 09202 vms->starting = 0; 09203 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09204 } 09205 } 09206 return res; 09207 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9035 of file app_voicemail_odbcstorage.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().
09036 { 09037 char prefile[256]; 09038 09039 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09040 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09041 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09042 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09043 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09044 ast_play_and_wait(chan, "vm-tempgreetactive"); 09045 } 09046 DISPOSE(prefile, -1); 09047 } 09048 09049 /* Play voicemail intro - syntax is different for different languages */ 09050 if (0) { 09051 return 0; 09052 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09053 return vm_intro_cs(chan, vms); 09054 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09055 static int deprecation_warning = 0; 09056 if (deprecation_warning++ % 10 == 0) { 09057 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09058 } 09059 return vm_intro_cs(chan, vms); 09060 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09061 return vm_intro_de(chan, vms); 09062 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09063 return vm_intro_es(chan, vms); 09064 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09065 return vm_intro_fr(chan, vms); 09066 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09067 return vm_intro_gr(chan, vms); 09068 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09069 return vm_intro_he(chan, vms); 09070 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09071 return vm_intro_it(chan, vms); 09072 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09073 return vm_intro_nl(chan, vms); 09074 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09075 return vm_intro_no(chan, vms); 09076 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09077 return vm_intro_pl(chan, vms); 09078 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09079 return vm_intro_pt_BR(chan, vms); 09080 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09081 return vm_intro_pt(chan, vms); 09082 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09083 return vm_intro_multilang(chan, vms, "n"); 09084 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09085 return vm_intro_se(chan, vms); 09086 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09087 return vm_intro_multilang(chan, vms, "n"); 09088 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09089 return vm_intro_vi(chan, vms); 09090 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09091 return vm_intro_zh(chan, vms); 09092 } else { /* Default to ENGLISH */ 09093 return vm_intro_en(chan, vms); 09094 } 09095 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8905 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08906 { 08907 int res; 08908 res = ast_play_and_wait(chan, "vm-youhave"); 08909 if (!res) { 08910 if (vms->newmessages) { 08911 if (vms->newmessages == 1) { 08912 res = ast_play_and_wait(chan, "digits/jednu"); 08913 } else { 08914 res = say_and_wait(chan, vms->newmessages, chan->language); 08915 } 08916 if (!res) { 08917 if ((vms->newmessages == 1)) 08918 res = ast_play_and_wait(chan, "vm-novou"); 08919 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08920 res = ast_play_and_wait(chan, "vm-nove"); 08921 if (vms->newmessages > 4) 08922 res = ast_play_and_wait(chan, "vm-novych"); 08923 } 08924 if (vms->oldmessages && !res) 08925 res = ast_play_and_wait(chan, "vm-and"); 08926 else if (!res) { 08927 if ((vms->newmessages == 1)) 08928 res = ast_play_and_wait(chan, "vm-zpravu"); 08929 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08930 res = ast_play_and_wait(chan, "vm-zpravy"); 08931 if (vms->newmessages > 4) 08932 res = ast_play_and_wait(chan, "vm-zprav"); 08933 } 08934 } 08935 if (!res && vms->oldmessages) { 08936 res = say_and_wait(chan, vms->oldmessages, chan->language); 08937 if (!res) { 08938 if ((vms->oldmessages == 1)) 08939 res = ast_play_and_wait(chan, "vm-starou"); 08940 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08941 res = ast_play_and_wait(chan, "vm-stare"); 08942 if (vms->oldmessages > 4) 08943 res = ast_play_and_wait(chan, "vm-starych"); 08944 } 08945 if (!res) { 08946 if ((vms->oldmessages == 1)) 08947 res = ast_play_and_wait(chan, "vm-zpravu"); 08948 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08949 res = ast_play_and_wait(chan, "vm-zpravy"); 08950 if (vms->oldmessages > 4) 08951 res = ast_play_and_wait(chan, "vm-zprav"); 08952 } 08953 } 08954 if (!res) { 08955 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08956 res = ast_play_and_wait(chan, "vm-no"); 08957 if (!res) 08958 res = ast_play_and_wait(chan, "vm-zpravy"); 08959 } 08960 } 08961 } 08962 return res; 08963 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8601 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08602 { 08603 /* Introduce messages they have */ 08604 int res; 08605 res = ast_play_and_wait(chan, "vm-youhave"); 08606 if (!res) { 08607 if (vms->newmessages) { 08608 if ((vms->newmessages == 1)) 08609 res = ast_play_and_wait(chan, "digits/1F"); 08610 else 08611 res = say_and_wait(chan, vms->newmessages, chan->language); 08612 if (!res) 08613 res = ast_play_and_wait(chan, "vm-INBOX"); 08614 if (vms->oldmessages && !res) 08615 res = ast_play_and_wait(chan, "vm-and"); 08616 else if (!res) { 08617 if ((vms->newmessages == 1)) 08618 res = ast_play_and_wait(chan, "vm-message"); 08619 else 08620 res = ast_play_and_wait(chan, "vm-messages"); 08621 } 08622 08623 } 08624 if (!res && vms->oldmessages) { 08625 if (vms->oldmessages == 1) 08626 res = ast_play_and_wait(chan, "digits/1F"); 08627 else 08628 res = say_and_wait(chan, vms->oldmessages, chan->language); 08629 if (!res) 08630 res = ast_play_and_wait(chan, "vm-Old"); 08631 if (!res) { 08632 if (vms->oldmessages == 1) 08633 res = ast_play_and_wait(chan, "vm-message"); 08634 else 08635 res = ast_play_and_wait(chan, "vm-messages"); 08636 } 08637 } 08638 if (!res) { 08639 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08640 res = ast_play_and_wait(chan, "vm-no"); 08641 if (!res) 08642 res = ast_play_and_wait(chan, "vm-messages"); 08643 } 08644 } 08645 } 08646 return res; 08647 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8350 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08351 { 08352 int res; 08353 08354 /* Introduce messages they have */ 08355 res = ast_play_and_wait(chan, "vm-youhave"); 08356 if (!res) { 08357 if (vms->urgentmessages) { 08358 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08359 if (!res) 08360 res = ast_play_and_wait(chan, "vm-Urgent"); 08361 if ((vms->oldmessages || vms->newmessages) && !res) { 08362 res = ast_play_and_wait(chan, "vm-and"); 08363 } else if (!res) { 08364 if ((vms->urgentmessages == 1)) 08365 res = ast_play_and_wait(chan, "vm-message"); 08366 else 08367 res = ast_play_and_wait(chan, "vm-messages"); 08368 } 08369 } 08370 if (vms->newmessages) { 08371 res = say_and_wait(chan, vms->newmessages, chan->language); 08372 if (!res) 08373 res = ast_play_and_wait(chan, "vm-INBOX"); 08374 if (vms->oldmessages && !res) 08375 res = ast_play_and_wait(chan, "vm-and"); 08376 else if (!res) { 08377 if ((vms->newmessages == 1)) 08378 res = ast_play_and_wait(chan, "vm-message"); 08379 else 08380 res = ast_play_and_wait(chan, "vm-messages"); 08381 } 08382 08383 } 08384 if (!res && vms->oldmessages) { 08385 res = say_and_wait(chan, vms->oldmessages, chan->language); 08386 if (!res) 08387 res = ast_play_and_wait(chan, "vm-Old"); 08388 if (!res) { 08389 if (vms->oldmessages == 1) 08390 res = ast_play_and_wait(chan, "vm-message"); 08391 else 08392 res = ast_play_and_wait(chan, "vm-messages"); 08393 } 08394 } 08395 if (!res) { 08396 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08397 res = ast_play_and_wait(chan, "vm-no"); 08398 if (!res) 08399 res = ast_play_and_wait(chan, "vm-messages"); 08400 } 08401 } 08402 } 08403 return res; 08404 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8650 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08651 { 08652 /* Introduce messages they have */ 08653 int res; 08654 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08655 res = ast_play_and_wait(chan, "vm-youhaveno"); 08656 if (!res) 08657 res = ast_play_and_wait(chan, "vm-messages"); 08658 } else { 08659 res = ast_play_and_wait(chan, "vm-youhave"); 08660 } 08661 if (!res) { 08662 if (vms->newmessages) { 08663 if (!res) { 08664 if ((vms->newmessages == 1)) { 08665 res = ast_play_and_wait(chan, "digits/1M"); 08666 if (!res) 08667 res = ast_play_and_wait(chan, "vm-message"); 08668 if (!res) 08669 res = ast_play_and_wait(chan, "vm-INBOXs"); 08670 } else { 08671 res = say_and_wait(chan, vms->newmessages, chan->language); 08672 if (!res) 08673 res = ast_play_and_wait(chan, "vm-messages"); 08674 if (!res) 08675 res = ast_play_and_wait(chan, "vm-INBOX"); 08676 } 08677 } 08678 if (vms->oldmessages && !res) 08679 res = ast_play_and_wait(chan, "vm-and"); 08680 } 08681 if (vms->oldmessages) { 08682 if (!res) { 08683 if (vms->oldmessages == 1) { 08684 res = ast_play_and_wait(chan, "digits/1M"); 08685 if (!res) 08686 res = ast_play_and_wait(chan, "vm-message"); 08687 if (!res) 08688 res = ast_play_and_wait(chan, "vm-Olds"); 08689 } else { 08690 res = say_and_wait(chan, vms->oldmessages, chan->language); 08691 if (!res) 08692 res = ast_play_and_wait(chan, "vm-messages"); 08693 if (!res) 08694 res = ast_play_and_wait(chan, "vm-Old"); 08695 } 08696 } 08697 } 08698 } 08699 return res; 08700 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8748 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08749 { 08750 /* Introduce messages they have */ 08751 int res; 08752 res = ast_play_and_wait(chan, "vm-youhave"); 08753 if (!res) { 08754 if (vms->newmessages) { 08755 res = say_and_wait(chan, vms->newmessages, chan->language); 08756 if (!res) 08757 res = ast_play_and_wait(chan, "vm-INBOX"); 08758 if (vms->oldmessages && !res) 08759 res = ast_play_and_wait(chan, "vm-and"); 08760 else if (!res) { 08761 if ((vms->newmessages == 1)) 08762 res = ast_play_and_wait(chan, "vm-message"); 08763 else 08764 res = ast_play_and_wait(chan, "vm-messages"); 08765 } 08766 08767 } 08768 if (!res && vms->oldmessages) { 08769 res = say_and_wait(chan, vms->oldmessages, chan->language); 08770 if (!res) 08771 res = ast_play_and_wait(chan, "vm-Old"); 08772 if (!res) { 08773 if (vms->oldmessages == 1) 08774 res = ast_play_and_wait(chan, "vm-message"); 08775 else 08776 res = ast_play_and_wait(chan, "vm-messages"); 08777 } 08778 } 08779 if (!res) { 08780 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08781 res = ast_play_and_wait(chan, "vm-no"); 08782 if (!res) 08783 res = ast_play_and_wait(chan, "vm-messages"); 08784 } 08785 } 08786 } 08787 return res; 08788 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8149 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08150 { 08151 int res = 0; 08152 08153 if (vms->newmessages) { 08154 res = ast_play_and_wait(chan, "vm-youhave"); 08155 if (!res) 08156 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08157 if (!res) { 08158 if ((vms->newmessages == 1)) { 08159 res = ast_play_and_wait(chan, "vm-INBOX"); 08160 if (!res) 08161 res = ast_play_and_wait(chan, "vm-message"); 08162 } else { 08163 res = ast_play_and_wait(chan, "vm-INBOXs"); 08164 if (!res) 08165 res = ast_play_and_wait(chan, "vm-messages"); 08166 } 08167 } 08168 } else if (vms->oldmessages){ 08169 res = ast_play_and_wait(chan, "vm-youhave"); 08170 if (!res) 08171 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08172 if ((vms->oldmessages == 1)){ 08173 res = ast_play_and_wait(chan, "vm-Old"); 08174 if (!res) 08175 res = ast_play_and_wait(chan, "vm-message"); 08176 } else { 08177 res = ast_play_and_wait(chan, "vm-Olds"); 08178 if (!res) 08179 res = ast_play_and_wait(chan, "vm-messages"); 08180 } 08181 } else if (!vms->oldmessages && !vms->newmessages) 08182 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08183 return res; 08184 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8283 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
08284 { 08285 int res = 0; 08286 08287 /* Introduce messages they have */ 08288 if (!res) { 08289 if ((vms->newmessages) || (vms->oldmessages)) { 08290 res = ast_play_and_wait(chan, "vm-youhave"); 08291 } 08292 /* 08293 * The word "shtei" refers to the number 2 in hebrew when performing a count 08294 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08295 * an element, this is one of them. 08296 */ 08297 if (vms->newmessages) { 08298 if (!res) { 08299 if (vms->newmessages == 1) { 08300 res = ast_play_and_wait(chan, "vm-INBOX1"); 08301 } else { 08302 if (vms->newmessages == 2) { 08303 res = ast_play_and_wait(chan, "vm-shtei"); 08304 } else { 08305 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08306 } 08307 res = ast_play_and_wait(chan, "vm-INBOX"); 08308 } 08309 } 08310 if (vms->oldmessages && !res) { 08311 res = ast_play_and_wait(chan, "vm-and"); 08312 if (vms->oldmessages == 1) { 08313 res = ast_play_and_wait(chan, "vm-Old1"); 08314 } else { 08315 if (vms->oldmessages == 2) { 08316 res = ast_play_and_wait(chan, "vm-shtei"); 08317 } else { 08318 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08319 } 08320 res = ast_play_and_wait(chan, "vm-Old"); 08321 } 08322 } 08323 } 08324 if (!res && vms->oldmessages && !vms->newmessages) { 08325 if (!res) { 08326 if (vms->oldmessages == 1) { 08327 res = ast_play_and_wait(chan, "vm-Old1"); 08328 } else { 08329 if (vms->oldmessages == 2) { 08330 res = ast_play_and_wait(chan, "vm-shtei"); 08331 } else { 08332 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08333 } 08334 res = ast_play_and_wait(chan, "vm-Old"); 08335 } 08336 } 08337 } 08338 if (!res) { 08339 if (!vms->oldmessages && !vms->newmessages) { 08340 if (!res) { 08341 res = ast_play_and_wait(chan, "vm-nomessages"); 08342 } 08343 } 08344 } 08345 } 08346 return res; 08347 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8407 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08408 { 08409 /* Introduce messages they have */ 08410 int res; 08411 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08412 res = ast_play_and_wait(chan, "vm-no") || 08413 ast_play_and_wait(chan, "vm-message"); 08414 else 08415 res = ast_play_and_wait(chan, "vm-youhave"); 08416 if (!res && vms->newmessages) { 08417 res = (vms->newmessages == 1) ? 08418 ast_play_and_wait(chan, "digits/un") || 08419 ast_play_and_wait(chan, "vm-nuovo") || 08420 ast_play_and_wait(chan, "vm-message") : 08421 /* 2 or more new messages */ 08422 say_and_wait(chan, vms->newmessages, chan->language) || 08423 ast_play_and_wait(chan, "vm-nuovi") || 08424 ast_play_and_wait(chan, "vm-messages"); 08425 if (!res && vms->oldmessages) 08426 res = ast_play_and_wait(chan, "vm-and"); 08427 } 08428 if (!res && vms->oldmessages) { 08429 res = (vms->oldmessages == 1) ? 08430 ast_play_and_wait(chan, "digits/un") || 08431 ast_play_and_wait(chan, "vm-vecchio") || 08432 ast_play_and_wait(chan, "vm-message") : 08433 /* 2 or more old messages */ 08434 say_and_wait(chan, vms->oldmessages, chan->language) || 08435 ast_play_and_wait(chan, "vm-vecchi") || 08436 ast_play_and_wait(chan, "vm-messages"); 08437 } 08438 return res; 08439 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8243 of file app_voicemail_odbcstorage.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().
08244 { 08245 int res; 08246 int lastnum = 0; 08247 08248 res = ast_play_and_wait(chan, "vm-youhave"); 08249 08250 if (!res && vms->newmessages) { 08251 lastnum = vms->newmessages; 08252 08253 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08254 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08255 } 08256 08257 if (!res && vms->oldmessages) { 08258 res = ast_play_and_wait(chan, "vm-and"); 08259 } 08260 } 08261 08262 if (!res && vms->oldmessages) { 08263 lastnum = vms->oldmessages; 08264 08265 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08266 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08267 } 08268 } 08269 08270 if (!res) { 08271 if (lastnum == 0) { 08272 res = ast_play_and_wait(chan, "vm-no"); 08273 } 08274 if (!res) { 08275 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08276 } 08277 } 08278 08279 return res; 08280 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8791 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08792 { 08793 /* Introduce messages they have */ 08794 int res; 08795 res = ast_play_and_wait(chan, "vm-youhave"); 08796 if (!res) { 08797 if (vms->newmessages) { 08798 res = say_and_wait(chan, vms->newmessages, chan->language); 08799 if (!res) { 08800 if (vms->newmessages == 1) 08801 res = ast_play_and_wait(chan, "vm-INBOXs"); 08802 else 08803 res = ast_play_and_wait(chan, "vm-INBOX"); 08804 } 08805 if (vms->oldmessages && !res) 08806 res = ast_play_and_wait(chan, "vm-and"); 08807 else if (!res) { 08808 if ((vms->newmessages == 1)) 08809 res = ast_play_and_wait(chan, "vm-message"); 08810 else 08811 res = ast_play_and_wait(chan, "vm-messages"); 08812 } 08813 08814 } 08815 if (!res && vms->oldmessages) { 08816 res = say_and_wait(chan, vms->oldmessages, chan->language); 08817 if (!res) { 08818 if (vms->oldmessages == 1) 08819 res = ast_play_and_wait(chan, "vm-Olds"); 08820 else 08821 res = ast_play_and_wait(chan, "vm-Old"); 08822 } 08823 if (!res) { 08824 if (vms->oldmessages == 1) 08825 res = ast_play_and_wait(chan, "vm-message"); 08826 else 08827 res = ast_play_and_wait(chan, "vm-messages"); 08828 } 08829 } 08830 if (!res) { 08831 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08832 res = ast_play_and_wait(chan, "vm-no"); 08833 if (!res) 08834 res = ast_play_and_wait(chan, "vm-messages"); 08835 } 08836 } 08837 } 08838 return res; 08839 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8557 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08558 { 08559 /* Introduce messages they have */ 08560 int res; 08561 08562 res = ast_play_and_wait(chan, "vm-youhave"); 08563 if (res) 08564 return res; 08565 08566 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08567 res = ast_play_and_wait(chan, "vm-no"); 08568 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08569 return res; 08570 } 08571 08572 if (vms->newmessages) { 08573 if ((vms->newmessages == 1)) { 08574 res = ast_play_and_wait(chan, "digits/1"); 08575 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08576 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08577 } else { 08578 res = say_and_wait(chan, vms->newmessages, chan->language); 08579 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08580 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08581 } 08582 if (!res && vms->oldmessages) 08583 res = ast_play_and_wait(chan, "vm-and"); 08584 } 08585 if (!res && vms->oldmessages) { 08586 if (vms->oldmessages == 1) { 08587 res = ast_play_and_wait(chan, "digits/1"); 08588 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08589 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08590 } else { 08591 res = say_and_wait(chan, vms->oldmessages, chan->language); 08592 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08593 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08594 } 08595 } 08596 08597 return res; 08598 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8442 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08443 { 08444 /* Introduce messages they have */ 08445 int res; 08446 div_t num; 08447 08448 if (!vms->oldmessages && !vms->newmessages) { 08449 res = ast_play_and_wait(chan, "vm-no"); 08450 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08451 return res; 08452 } else { 08453 res = ast_play_and_wait(chan, "vm-youhave"); 08454 } 08455 08456 if (vms->newmessages) { 08457 num = div(vms->newmessages, 10); 08458 if (vms->newmessages == 1) { 08459 res = ast_play_and_wait(chan, "digits/1-a"); 08460 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08461 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08462 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08463 if (num.rem == 2) { 08464 if (!num.quot) { 08465 res = ast_play_and_wait(chan, "digits/2-ie"); 08466 } else { 08467 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08468 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08469 } 08470 } else { 08471 res = say_and_wait(chan, vms->newmessages, chan->language); 08472 } 08473 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08474 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08475 } else { 08476 res = say_and_wait(chan, vms->newmessages, chan->language); 08477 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08478 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08479 } 08480 if (!res && vms->oldmessages) 08481 res = ast_play_and_wait(chan, "vm-and"); 08482 } 08483 if (!res && vms->oldmessages) { 08484 num = div(vms->oldmessages, 10); 08485 if (vms->oldmessages == 1) { 08486 res = ast_play_and_wait(chan, "digits/1-a"); 08487 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08488 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08489 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08490 if (num.rem == 2) { 08491 if (!num.quot) { 08492 res = ast_play_and_wait(chan, "digits/2-ie"); 08493 } else { 08494 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08495 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08496 } 08497 } else { 08498 res = say_and_wait(chan, vms->oldmessages, chan->language); 08499 } 08500 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08501 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08502 } else { 08503 res = say_and_wait(chan, vms->oldmessages, chan->language); 08504 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08505 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08506 } 08507 } 08508 08509 return res; 08510 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8842 of file app_voicemail_odbcstorage.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().
08843 { 08844 /* Introduce messages they have */ 08845 int res; 08846 res = ast_play_and_wait(chan, "vm-youhave"); 08847 if (!res) { 08848 if (vms->newmessages) { 08849 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08850 if (!res) { 08851 if ((vms->newmessages == 1)) { 08852 res = ast_play_and_wait(chan, "vm-message"); 08853 if (!res) 08854 res = ast_play_and_wait(chan, "vm-INBOXs"); 08855 } else { 08856 res = ast_play_and_wait(chan, "vm-messages"); 08857 if (!res) 08858 res = ast_play_and_wait(chan, "vm-INBOX"); 08859 } 08860 } 08861 if (vms->oldmessages && !res) 08862 res = ast_play_and_wait(chan, "vm-and"); 08863 } 08864 if (!res && vms->oldmessages) { 08865 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08866 if (!res) { 08867 if (vms->oldmessages == 1) { 08868 res = ast_play_and_wait(chan, "vm-message"); 08869 if (!res) 08870 res = ast_play_and_wait(chan, "vm-Olds"); 08871 } else { 08872 res = ast_play_and_wait(chan, "vm-messages"); 08873 if (!res) 08874 res = ast_play_and_wait(chan, "vm-Old"); 08875 } 08876 } 08877 } 08878 if (!res) { 08879 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08880 res = ast_play_and_wait(chan, "vm-no"); 08881 if (!res) 08882 res = ast_play_and_wait(chan, "vm-messages"); 08883 } 08884 } 08885 } 08886 return res; 08887 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8703 of file app_voicemail_odbcstorage.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().
08703 { 08704 /* Introduce messages they have */ 08705 int res; 08706 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08707 res = ast_play_and_wait(chan, "vm-nomessages"); 08708 return res; 08709 } else { 08710 res = ast_play_and_wait(chan, "vm-youhave"); 08711 } 08712 if (vms->newmessages) { 08713 if (!res) 08714 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08715 if ((vms->newmessages == 1)) { 08716 if (!res) 08717 res = ast_play_and_wait(chan, "vm-message"); 08718 if (!res) 08719 res = ast_play_and_wait(chan, "vm-INBOXs"); 08720 } else { 08721 if (!res) 08722 res = ast_play_and_wait(chan, "vm-messages"); 08723 if (!res) 08724 res = ast_play_and_wait(chan, "vm-INBOX"); 08725 } 08726 if (vms->oldmessages && !res) 08727 res = ast_play_and_wait(chan, "vm-and"); 08728 } 08729 if (vms->oldmessages) { 08730 if (!res) 08731 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08732 if (vms->oldmessages == 1) { 08733 if (!res) 08734 res = ast_play_and_wait(chan, "vm-message"); 08735 if (!res) 08736 res = ast_play_and_wait(chan, "vm-Olds"); 08737 } else { 08738 if (!res) 08739 res = ast_play_and_wait(chan, "vm-messages"); 08740 if (!res) 08741 res = ast_play_and_wait(chan, "vm-Old"); 08742 } 08743 } 08744 return res; 08745 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8513 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08514 { 08515 /* Introduce messages they have */ 08516 int res; 08517 08518 res = ast_play_and_wait(chan, "vm-youhave"); 08519 if (res) 08520 return res; 08521 08522 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08523 res = ast_play_and_wait(chan, "vm-no"); 08524 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08525 return res; 08526 } 08527 08528 if (vms->newmessages) { 08529 if ((vms->newmessages == 1)) { 08530 res = ast_play_and_wait(chan, "digits/ett"); 08531 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08532 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08533 } else { 08534 res = say_and_wait(chan, vms->newmessages, chan->language); 08535 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08536 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08537 } 08538 if (!res && vms->oldmessages) 08539 res = ast_play_and_wait(chan, "vm-and"); 08540 } 08541 if (!res && vms->oldmessages) { 08542 if (vms->oldmessages == 1) { 08543 res = ast_play_and_wait(chan, "digits/ett"); 08544 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08545 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08546 } else { 08547 res = say_and_wait(chan, vms->oldmessages, chan->language); 08548 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08549 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08550 } 08551 } 08552 08553 return res; 08554 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9005 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
09006 { 09007 int res; 09008 09009 /* Introduce messages they have */ 09010 res = ast_play_and_wait(chan, "vm-youhave"); 09011 if (!res) { 09012 if (vms->newmessages) { 09013 res = say_and_wait(chan, vms->newmessages, chan->language); 09014 if (!res) 09015 res = ast_play_and_wait(chan, "vm-INBOX"); 09016 if (vms->oldmessages && !res) 09017 res = ast_play_and_wait(chan, "vm-and"); 09018 } 09019 if (!res && vms->oldmessages) { 09020 res = say_and_wait(chan, vms->oldmessages, chan->language); 09021 if (!res) 09022 res = ast_play_and_wait(chan, "vm-Old"); 09023 } 09024 if (!res) { 09025 if (!vms->oldmessages && !vms->newmessages) { 09026 res = ast_play_and_wait(chan, "vm-no"); 09027 if (!res) 09028 res = ast_play_and_wait(chan, "vm-message"); 09029 } 09030 } 09031 } 09032 return res; 09033 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8966 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08967 { 08968 int res; 08969 /* Introduce messages they have */ 08970 res = ast_play_and_wait(chan, "vm-you"); 08971 08972 if (!res && vms->newmessages) { 08973 res = ast_play_and_wait(chan, "vm-have"); 08974 if (!res) 08975 res = say_and_wait(chan, vms->newmessages, chan->language); 08976 if (!res) 08977 res = ast_play_and_wait(chan, "vm-tong"); 08978 if (!res) 08979 res = ast_play_and_wait(chan, "vm-INBOX"); 08980 if (vms->oldmessages && !res) 08981 res = ast_play_and_wait(chan, "vm-and"); 08982 else if (!res) 08983 res = ast_play_and_wait(chan, "vm-messages"); 08984 } 08985 if (!res && vms->oldmessages) { 08986 res = ast_play_and_wait(chan, "vm-have"); 08987 if (!res) 08988 res = say_and_wait(chan, vms->oldmessages, chan->language); 08989 if (!res) 08990 res = ast_play_and_wait(chan, "vm-tong"); 08991 if (!res) 08992 res = ast_play_and_wait(chan, "vm-Old"); 08993 if (!res) 08994 res = ast_play_and_wait(chan, "vm-messages"); 08995 } 08996 if (!res && !vms->oldmessages && !vms->newmessages) { 08997 res = ast_play_and_wait(chan, "vm-haveno"); 08998 if (!res) 08999 res = ast_play_and_wait(chan, "vm-messages"); 09000 } 09001 return res; 09002 }
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 3251 of file app_voicemail_odbcstorage.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().
03252 { 03253 switch (ast_lock_path(path)) { 03254 case AST_LOCK_TIMEOUT: 03255 return -1; 03256 default: 03257 return 0; 03258 } 03259 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1642 of file app_voicemail_odbcstorage.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01643 { 01644 FILE *p = NULL; 01645 int pfd = mkstemp(template); 01646 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01647 if (pfd > -1) { 01648 p = fdopen(pfd, "w+"); 01649 if (!p) { 01650 close(pfd); 01651 pfd = -1; 01652 } 01653 } 01654 return p; 01655 }
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 9219 of file app_voicemail_odbcstorage.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().
09220 { 09221 int cmd = 0; 09222 int duration = 0; 09223 int tries = 0; 09224 char newpassword[80] = ""; 09225 char newpassword2[80] = ""; 09226 char prefile[PATH_MAX] = ""; 09227 unsigned char buf[256]; 09228 int bytes = 0; 09229 09230 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09231 if (ast_adsi_available(chan)) { 09232 bytes += adsi_logo(buf + bytes); 09233 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09234 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09235 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09236 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09237 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09238 } 09239 09240 /* If forcename is set, have the user record their name */ 09241 if (ast_test_flag(vmu, VM_FORCENAME)) { 09242 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09243 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09244 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09245 if (cmd < 0 || cmd == 't' || cmd == '#') 09246 return cmd; 09247 } 09248 } 09249 09250 /* If forcegreetings is set, have the user record their greetings */ 09251 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09252 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09253 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09254 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09255 if (cmd < 0 || cmd == 't' || cmd == '#') 09256 return cmd; 09257 } 09258 09259 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09260 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09261 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09262 if (cmd < 0 || cmd == 't' || cmd == '#') 09263 return cmd; 09264 } 09265 } 09266 09267 /* 09268 * Change the password last since new users will be able to skip over any steps this one comes before 09269 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09270 */ 09271 for (;;) { 09272 newpassword[1] = '\0'; 09273 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09274 if (cmd == '#') 09275 newpassword[0] = '\0'; 09276 if (cmd < 0 || cmd == 't' || cmd == '#') 09277 return cmd; 09278 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09279 if (cmd < 0 || cmd == 't' || cmd == '#') 09280 return cmd; 09281 cmd = check_password(vmu, newpassword); /* perform password validation */ 09282 if (cmd != 0) { 09283 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09284 cmd = ast_play_and_wait(chan, vm_invalid_password); 09285 } else { 09286 newpassword2[1] = '\0'; 09287 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09288 if (cmd == '#') 09289 newpassword2[0] = '\0'; 09290 if (cmd < 0 || cmd == 't' || cmd == '#') 09291 return cmd; 09292 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09293 if (cmd < 0 || cmd == 't' || cmd == '#') 09294 return cmd; 09295 if (!strcmp(newpassword, newpassword2)) 09296 break; 09297 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09298 cmd = ast_play_and_wait(chan, vm_mismatch); 09299 } 09300 if (++tries == 3) 09301 return -1; 09302 if (cmd != 0) { 09303 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09304 } 09305 } 09306 if (pwdchange & PWDCHANGE_INTERNAL) 09307 vm_change_password(vmu, newpassword); 09308 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09309 vm_change_password_shell(vmu, newpassword); 09310 09311 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09312 cmd = ast_play_and_wait(chan, vm_passchanged); 09313 09314 return cmd; 09315 }
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 9317 of file app_voicemail_odbcstorage.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().
09318 { 09319 int cmd = 0; 09320 int retries = 0; 09321 int duration = 0; 09322 char newpassword[80] = ""; 09323 char newpassword2[80] = ""; 09324 char prefile[PATH_MAX] = ""; 09325 unsigned char buf[256]; 09326 int bytes = 0; 09327 09328 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09329 if (ast_adsi_available(chan)) { 09330 bytes += adsi_logo(buf + bytes); 09331 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09332 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09333 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09334 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09335 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09336 } 09337 while ((cmd >= 0) && (cmd != 't')) { 09338 if (cmd) 09339 retries = 0; 09340 switch (cmd) { 09341 case '1': /* Record your unavailable message */ 09342 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09343 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09344 break; 09345 case '2': /* Record your busy message */ 09346 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09347 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09348 break; 09349 case '3': /* Record greeting */ 09350 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09351 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09352 break; 09353 case '4': /* manage the temporary greeting */ 09354 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09355 break; 09356 case '5': /* change password */ 09357 if (vmu->password[0] == '-') { 09358 cmd = ast_play_and_wait(chan, "vm-no"); 09359 break; 09360 } 09361 newpassword[1] = '\0'; 09362 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09363 if (cmd == '#') 09364 newpassword[0] = '\0'; 09365 else { 09366 if (cmd < 0) 09367 break; 09368 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09369 break; 09370 } 09371 } 09372 cmd = check_password(vmu, newpassword); /* perform password validation */ 09373 if (cmd != 0) { 09374 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09375 cmd = ast_play_and_wait(chan, vm_invalid_password); 09376 if (!cmd) { 09377 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09378 } 09379 break; 09380 } 09381 newpassword2[1] = '\0'; 09382 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09383 if (cmd == '#') 09384 newpassword2[0] = '\0'; 09385 else { 09386 if (cmd < 0) 09387 break; 09388 09389 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09390 break; 09391 } 09392 } 09393 if (strcmp(newpassword, newpassword2)) { 09394 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09395 cmd = ast_play_and_wait(chan, vm_mismatch); 09396 if (!cmd) { 09397 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09398 } 09399 break; 09400 } 09401 09402 if (pwdchange & PWDCHANGE_INTERNAL) { 09403 vm_change_password(vmu, newpassword); 09404 } 09405 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09406 vm_change_password_shell(vmu, newpassword); 09407 } 09408 09409 ast_debug(1, "User %s set password to %s of length %d\n", 09410 vms->username, newpassword, (int) strlen(newpassword)); 09411 cmd = ast_play_and_wait(chan, vm_passchanged); 09412 break; 09413 case '*': 09414 cmd = 't'; 09415 break; 09416 default: 09417 cmd = 0; 09418 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09419 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09420 if (ast_fileexists(prefile, NULL, NULL)) { 09421 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09422 } 09423 DISPOSE(prefile, -1); 09424 if (!cmd) { 09425 cmd = ast_play_and_wait(chan, "vm-options"); 09426 } 09427 if (!cmd) { 09428 cmd = ast_waitfordigit(chan, 6000); 09429 } 09430 if (!cmd) { 09431 retries++; 09432 } 09433 if (retries > 3) { 09434 cmd = 't'; 09435 } 09436 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09437 } 09438 } 09439 if (cmd == 't') 09440 cmd = 0; 09441 return cmd; 09442 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8112 of file app_voicemail_odbcstorage.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().
08113 { 08114 int cmd; 08115 08116 if ( !strncasecmp(chan->language, "it", 2) || 08117 !strncasecmp(chan->language, "es", 2) || 08118 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08119 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08120 return cmd ? cmd : ast_play_and_wait(chan, box); 08121 } else if (!strncasecmp(chan->language, "gr", 2)) { 08122 return vm_play_folder_name_gr(chan, box); 08123 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08124 return ast_play_and_wait(chan, box); 08125 } else if (!strncasecmp(chan->language, "pl", 2)) { 08126 return vm_play_folder_name_pl(chan, box); 08127 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08128 return vm_play_folder_name_ua(chan, box); 08129 } else if (!strncasecmp(chan->language, "vi", 2)) { 08130 return ast_play_and_wait(chan, box); 08131 } else { /* Default English */ 08132 cmd = ast_play_and_wait(chan, box); 08133 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08134 } 08135 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8065 of file app_voicemail_odbcstorage.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08066 { 08067 int cmd; 08068 char *buf; 08069 08070 buf = ast_alloca(strlen(box) + 2); 08071 strcpy(buf, box); 08072 strcat(buf, "s"); 08073 08074 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08075 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08076 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08077 } else { 08078 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08079 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08080 } 08081 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8083 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08084 { 08085 int cmd; 08086 08087 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08088 if (!strcasecmp(box, "vm-INBOX")) 08089 cmd = ast_play_and_wait(chan, "vm-new-e"); 08090 else 08091 cmd = ast_play_and_wait(chan, "vm-old-e"); 08092 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08093 } else { 08094 cmd = ast_play_and_wait(chan, "vm-messages"); 08095 return cmd ? cmd : ast_play_and_wait(chan, box); 08096 } 08097 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8099 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08100 { 08101 int cmd; 08102 08103 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08104 cmd = ast_play_and_wait(chan, "vm-messages"); 08105 return cmd ? cmd : ast_play_and_wait(chan, box); 08106 } else { 08107 cmd = ast_play_and_wait(chan, box); 08108 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08109 } 08110 }
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 9460 of file app_voicemail_odbcstorage.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().
09461 { 09462 int cmd = 0; 09463 int retries = 0; 09464 int duration = 0; 09465 char prefile[PATH_MAX] = ""; 09466 unsigned char buf[256]; 09467 int bytes = 0; 09468 09469 if (ast_adsi_available(chan)) { 09470 bytes += adsi_logo(buf + bytes); 09471 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09472 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09473 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09474 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09475 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09476 } 09477 09478 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09479 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09480 while ((cmd >= 0) && (cmd != 't')) { 09481 if (cmd) 09482 retries = 0; 09483 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09484 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09485 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09486 if (cmd == -1) { 09487 break; 09488 } 09489 cmd = 't'; 09490 } else { 09491 switch (cmd) { 09492 case '1': 09493 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09494 break; 09495 case '2': 09496 DELETE(prefile, -1, prefile, vmu); 09497 ast_play_and_wait(chan, "vm-tempremoved"); 09498 cmd = 't'; 09499 break; 09500 case '*': 09501 cmd = 't'; 09502 break; 09503 default: 09504 cmd = ast_play_and_wait(chan, 09505 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09506 "vm-tempgreeting2" : "vm-tempgreeting"); 09507 if (!cmd) { 09508 cmd = ast_waitfordigit(chan, 6000); 09509 } 09510 if (!cmd) { 09511 retries++; 09512 } 09513 if (retries > 3) { 09514 cmd = 't'; 09515 } 09516 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09517 } 09518 } 09519 DISPOSE(prefile, -1); 09520 } 09521 if (cmd == 't') 09522 cmd = 0; 09523 return cmd; 09524 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11412 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11414 { 11415 struct ast_vm_user *user; 11416 11417 AST_LIST_LOCK(&users); 11418 AST_LIST_TRAVERSE(&users, user, list) { 11419 vm_users_data_provider_get_helper(search, data_root, user); 11420 } 11421 AST_LIST_UNLOCK(&users); 11422 11423 return 0; 11424 }
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 11365 of file app_voicemail_odbcstorage.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().
11367 { 11368 struct ast_data *data_user, *data_zone; 11369 struct ast_data *data_state; 11370 struct vm_zone *zone = NULL; 11371 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11372 char ext_context[256] = ""; 11373 11374 data_user = ast_data_add_node(data_root, "user"); 11375 if (!data_user) { 11376 return -1; 11377 } 11378 11379 ast_data_add_structure(ast_vm_user, data_user, user); 11380 11381 AST_LIST_LOCK(&zones); 11382 AST_LIST_TRAVERSE(&zones, zone, list) { 11383 if (!strcmp(zone->name, user->zonetag)) { 11384 break; 11385 } 11386 } 11387 AST_LIST_UNLOCK(&zones); 11388 11389 /* state */ 11390 data_state = ast_data_add_node(data_user, "state"); 11391 if (!data_state) { 11392 return -1; 11393 } 11394 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11395 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11396 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11397 ast_data_add_int(data_state, "newmsg", newmsg); 11398 ast_data_add_int(data_state, "oldmsg", oldmsg); 11399 11400 if (zone) { 11401 data_zone = ast_data_add_node(data_user, "zone"); 11402 ast_data_add_structure(vm_zone, data_zone, zone); 11403 } 11404 11405 if (!ast_data_search_match(search, data_user)) { 11406 ast_data_remove_node(data_root, data_user); 11407 } 11408 11409 return 0; 11410 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11051 of file app_voicemail_odbcstorage.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().
11052 { 11053 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11054 struct ast_vm_user vmus; 11055 char *options = NULL; 11056 int silent = 0, skipuser = 0; 11057 int res = -1; 11058 11059 if (data) { 11060 s = ast_strdupa(data); 11061 user = strsep(&s, ","); 11062 options = strsep(&s, ","); 11063 if (user) { 11064 s = user; 11065 user = strsep(&s, "@"); 11066 context = strsep(&s, ""); 11067 if (!ast_strlen_zero(user)) 11068 skipuser++; 11069 ast_copy_string(mailbox, user, sizeof(mailbox)); 11070 } 11071 } 11072 11073 if (options) { 11074 silent = (strchr(options, 's')) != NULL; 11075 } 11076 11077 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11078 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11079 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11080 ast_play_and_wait(chan, "auth-thankyou"); 11081 res = 0; 11082 } else if (mailbox[0] == '*') { 11083 /* user entered '*' */ 11084 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11085 res = 0; /* prevent hangup */ 11086 } 11087 } 11088 11089 return res; 11090 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12591 of file app_voicemail_odbcstorage.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().
12592 { 12593 char *context; 12594 char *args_copy; 12595 int res; 12596 12597 if (ast_strlen_zero(data)) { 12598 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12599 return -1; 12600 } 12601 12602 args_copy = ast_strdupa(data); 12603 if ((context = strchr(args_copy, '@'))) { 12604 *context++ = '\0'; 12605 } else { 12606 context = "default"; 12607 } 12608 12609 if ((res = sayname(chan, args_copy, context) < 0)) { 12610 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12611 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12612 if (!res) { 12613 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12614 } 12615 } 12616 12617 return res; 12618 }
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 4408 of file app_voicemail_odbcstorage.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().
04409 { 04410 const struct vm_zone *z = NULL; 04411 struct timeval t = ast_tvnow(); 04412 04413 /* Does this user have a timezone specified? */ 04414 if (!ast_strlen_zero(vmu->zonetag)) { 04415 /* Find the zone in the list */ 04416 AST_LIST_LOCK(&zones); 04417 AST_LIST_TRAVERSE(&zones, z, list) { 04418 if (!strcmp(z->name, vmu->zonetag)) 04419 break; 04420 } 04421 AST_LIST_UNLOCK(&zones); 04422 } 04423 ast_localtime(&t, tm, z ? z->timezone : NULL); 04424 return tm; 04425 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7461 of file app_voicemail_odbcstorage.c.
References ast_control_streamfile(), and ast_test_suite_event_notify.
Referenced by advanced_options(), and play_message().
07462 { 07463 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07464 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); 07465 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7453 of file app_voicemail_odbcstorage.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().
07454 { 07455 int res; 07456 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07457 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07458 return res; 07459 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12558 of file app_voicemail_odbcstorage.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().
12558 { 12559 struct ast_config *conf; 12560 struct ast_category *cat; 12561 struct ast_variable *var; 12562 int res = -1; 12563 12564 if (!(conf = ast_config_new())) { 12565 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12566 return res; 12567 } 12568 if (!(cat = ast_category_new("general", "", 1))) { 12569 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12570 ast_config_destroy(conf); 12571 return res; 12572 } 12573 if (!(var = ast_variable_new("password", password, ""))) { 12574 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12575 ast_config_destroy(conf); 12576 ast_category_destroy(cat); 12577 return res; 12578 } 12579 ast_category_append(conf, cat); 12580 ast_variable_append(cat, var); 12581 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12582 res = 0; 12583 } else { 12584 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12585 } 12586 12587 ast_config_destroy(conf); 12588 return res; 12589 }
char* addesc = "Comedian Mail" [static] |
Definition at line 749 of file app_voicemail_odbcstorage.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 876 of file app_voicemail_odbcstorage.c.
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 877 of file app_voicemail_odbcstorage.c.
int adsiver = 1 [static] |
Definition at line 878 of file app_voicemail_odbcstorage.c.
char* app = "VoiceMail" [static] |
Definition at line 752 of file app_voicemail_odbcstorage.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 755 of file app_voicemail_odbcstorage.c.
char* app3 = "MailboxExists" [static] |
Definition at line 757 of file app_voicemail_odbcstorage.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 758 of file app_voicemail_odbcstorage.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 862 of file app_voicemail_odbcstorage.c.
char charset[32] = "ISO-8859-1" [static] |
Definition at line 874 of file app_voicemail_odbcstorage.c.
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 865 of file app_voicemail_odbcstorage.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 11290 of file app_voicemail_odbcstorage.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 861 of file app_voicemail_odbcstorage.c.
char* emailbody = NULL [static] |
Definition at line 868 of file app_voicemail_odbcstorage.c.
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 879 of file app_voicemail_odbcstorage.c.
char* emailsubject = NULL [static] |
Definition at line 869 of file app_voicemail_odbcstorage.c.
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 863 of file app_voicemail_odbcstorage.c.
char ext_pass_check_cmd[128] [static] |
Definition at line 729 of file app_voicemail_odbcstorage.c.
char ext_pass_cmd[128] [static] |
Definition at line 728 of file app_voicemail_odbcstorage.c.
char externnotify[160] [static] |
Definition at line 772 of file app_voicemail_odbcstorage.c.
char fromstring[100] [static] |
Definition at line 872 of file app_voicemail_odbcstorage.c.
struct ast_flags globalflags = {0} [static] |
Definition at line 857 of file app_voicemail_odbcstorage.c.
struct ao2_container* inprocess_container |
Definition at line 901 of file app_voicemail_odbcstorage.c.
char listen_control_forward_key[12] [static] |
Definition at line 830 of file app_voicemail_odbcstorage.c.
char listen_control_pause_key[12] [static] |
Definition at line 832 of file app_voicemail_odbcstorage.c.
char listen_control_restart_key[12] [static] |
Definition at line 833 of file app_voicemail_odbcstorage.c.
char listen_control_reverse_key[12] [static] |
Definition at line 831 of file app_voicemail_odbcstorage.c.
char listen_control_stop_key[12] [static] |
Definition at line 834 of file app_voicemail_odbcstorage.c.
char locale[20] [static] |
Definition at line 765 of file app_voicemail_odbcstorage.c.
struct ast_custom_function mailbox_exists_acf [static] |
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11046 of file app_voicemail_odbcstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1678 of file app_voicemail_odbcstorage.c.
char mailcmd[160] [static] |
Definition at line 771 of file app_voicemail_odbcstorage.c.
int maxdeletedmsg [static] |
Definition at line 768 of file app_voicemail_odbcstorage.c.
int maxgreet [static] |
Definition at line 778 of file app_voicemail_odbcstorage.c.
int maxlogins [static] |
Definition at line 780 of file app_voicemail_odbcstorage.c.
int maxmsg [static] |
Definition at line 767 of file app_voicemail_odbcstorage.c.
int maxsilence [static] |
Definition at line 766 of file app_voicemail_odbcstorage.c.
int minpassword [static] |
Definition at line 781 of file app_voicemail_odbcstorage.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 799 of file app_voicemail_odbcstorage.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 825 of file app_voicemail_odbcstorage.c.
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 801 of file app_voicemail_odbcstorage.c.
int my_umask [static] |
Definition at line 731 of file app_voicemail_odbcstorage.c.
char* pagerbody = NULL [static] |
Definition at line 870 of file app_voicemail_odbcstorage.c.
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 880 of file app_voicemail_odbcstorage.c.
char pagerfromstring[100] [static] |
Definition at line 873 of file app_voicemail_odbcstorage.c.
char* pagersubject = NULL [static] |
Definition at line 871 of file app_voicemail_odbcstorage.c.
int passwordlocation [static] |
Definition at line 782 of file app_voicemail_odbcstorage.c.
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 794 of file app_voicemail_odbcstorage.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 789 of file app_voicemail_odbcstorage.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 786 of file app_voicemail_odbcstorage.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 795 of file app_voicemail_odbcstorage.c.
unsigned char poll_thread_run [static] |
Definition at line 796 of file app_voicemail_odbcstorage.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 735 of file app_voicemail_odbcstorage.c.
int saydurationminfo [static] |
Definition at line 859 of file app_voicemail_odbcstorage.c.
char* sayname_app = "VMSayName" [static] |
Definition at line 760 of file app_voicemail_odbcstorage.c.
char serveremail[80] [static] |
Definition at line 770 of file app_voicemail_odbcstorage.c.
int silencethreshold = 128 [static] |
Definition at line 769 of file app_voicemail_odbcstorage.c.
int skipms [static] |
Definition at line 779 of file app_voicemail_odbcstorage.c.
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 773 of file app_voicemail_odbcstorage.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 747 of file app_voicemail_odbcstorage.c.
struct ast_data_entry vm_data_providers[] [static] |
{ }
Definition at line 11431 of file app_voicemail_odbcstorage.c.
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 842 of file app_voicemail_odbcstorage.c.
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 841 of file app_voicemail_odbcstorage.c.
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 838 of file app_voicemail_odbcstorage.c.
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 839 of file app_voicemail_odbcstorage.c.
char vm_password[80] = "vm-password" [static] |
Definition at line 837 of file app_voicemail_odbcstorage.c.
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 843 of file app_voicemail_odbcstorage.c.
char vm_prepend_timeout[80] = "vm-then-pound" [static] |
Definition at line 855 of file app_voicemail_odbcstorage.c.
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 840 of file app_voicemail_odbcstorage.c.
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 726 of file app_voicemail_odbcstorage.c.
struct ast_data_handler vm_users_data_provider [static] |
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11426 of file app_voicemail_odbcstorage.c.
char vmfmts[80] [static] |
Definition at line 774 of file app_voicemail_odbcstorage.c.
int vmmaxsecs [static] |
Definition at line 777 of file app_voicemail_odbcstorage.c.
int vmminsecs [static] |
Definition at line 776 of file app_voicemail_odbcstorage.c.
double volgain [static] |
Definition at line 775 of file app_voicemail_odbcstorage.c.
char zonetag[80] [static] |
Definition at line 764 of file app_voicemail_odbcstorage.c.