Comedian Mail - Voicemail System. More...
#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj2.h"
#include "asterisk/event.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
Go to the source code of this file.
Data Structures | |
struct | ast_vm_user |
struct | baseio |
struct | inprocess |
struct | leave_vm_options |
Options for leaving voicemail with the voicemail() application. More... | |
struct | mwi_sub |
An MWI subscription. More... | |
struct | mwi_sub_task |
struct | vm_state |
struct | vm_zone |
Defines | |
#define | ASTERISK_USERNAME "asterisk" |
#define | BASELINELEN 72 |
#define | BASEMAXINLINE 256 |
#define | CHUNKSIZE 65536 |
#define | COMMAND_TIMEOUT 5000 |
#define | COPY(a, b, c, d, e, f, g, h) (copy_plain_file(g,h)); |
#define | DATA_EXPORT_VM_USERS(USER) |
#define | DATA_EXPORT_VM_ZONES(ZONE) |
#define | DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
#define | DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
#define | DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
#define | DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
#define | DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
#define | DEFAULT_POLL_FREQ 30 |
#define | DELETE(a, b, c, d) (vm_delete(c)) |
#define | DISPOSE(a, b) |
#define | ENDL "\n" |
#define | ERROR_LOCK_PATH -100 |
#define | EXISTS(a, b, c, d) (ast_fileexists(c,NULL,d) > 0) |
#define | HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define | HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define | INTRO "vm-intro" |
#define | MAX_DATETIME_FORMAT 512 |
#define | MAX_NUM_CID_CONTEXTS 10 |
#define | MAXMSG 100 |
#define | MAXMSGLIMIT 9999 |
#define | MINPASSWORD 0 |
#define | OPERATOR_EXIT 300 |
#define | PWDCHANGE_EXTERNAL (1 << 2) |
#define | PWDCHANGE_INTERNAL (1 << 1) |
#define | RENAME(a, b, c, d, e, f, g, h) (rename_file(g,h)); |
#define | RETRIEVE(a, b, c, d) |
#define | SENDMAIL "/usr/sbin/sendmail -t" |
#define | SMDI_MWI_WAIT_TIMEOUT 1000 |
#define | STORE(a, b, c, d, e, f, g, h, i, j) |
#define | tdesc "Comedian Mail (Voicemail System)" |
#define | VALID_DTMF "1234567890*#" |
#define | VM_ALLOCED (1 << 13) |
#define | VM_ATTACH (1 << 11) |
#define | VM_DELETE (1 << 12) |
#define | VM_DIRECFORWARD (1 << 10) |
#define | VM_ENVELOPE (1 << 4) |
#define | VM_FORCEGREET (1 << 8) |
#define | VM_FORCENAME (1 << 7) |
#define | VM_FWDURGAUTO (1 << 18) |
#define | VM_MESSAGEWRAP (1 << 17) |
#define | VM_MOVEHEARD (1 << 16) |
#define | VM_OPERATOR (1 << 1) |
#define | VM_PBXSKIP (1 << 9) |
#define | VM_REVIEW (1 << 0) |
#define | VM_SAYCID (1 << 2) |
#define | VM_SAYDURATION (1 << 5) |
#define | VM_SEARCH (1 << 14) |
#define | VM_SKIPAFTERCMD (1 << 6) |
#define | VM_SVMAIL (1 << 3) |
#define | VM_TEMPGREETWARN (1 << 15) |
#define | VMSTATE_MAX_MSG_ARRAY 256 |
#define | VOICEMAIL_CONFIG "voicemail.conf" |
#define | VOICEMAIL_DIR_MODE 0777 |
#define | VOICEMAIL_FILE_MODE 0666 |
Enumerations | |
enum | vm_box { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER } |
enum | vm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3, OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
enum | vm_option_flags { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9) } |
enum | vm_passwordlocation { OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2 } |
Functions | |
static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
static int | acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len) |
static int | actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg) |
static int | add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum) |
static void | adsi_begin (struct ast_channel *chan, int *useadsi) |
static void | adsi_delete (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_folders (struct ast_channel *chan, int start, char *label) |
static void | adsi_goodbye (struct ast_channel *chan) |
static int | adsi_load_vmail (struct ast_channel *chan, int *useadsi) |
static void | adsi_login (struct ast_channel *chan) |
static int | adsi_logo (unsigned char *buf) |
static void | adsi_message (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_password (struct ast_channel *chan) |
static void | adsi_status (struct ast_channel *chan, struct vm_state *vms) |
static void | adsi_status2 (struct ast_channel *chan, struct vm_state *vms) |
static int | advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain) |
The advanced options within a message. | |
static int | append_mailbox (const char *context, const char *box, const char *data) |
static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
Sets a a specific property value. | |
static void | apply_options (struct ast_vm_user *vmu, const char *options) |
Destructively Parse options and apply. | |
static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
Loads the options specific to a voicemail user. | |
AST_APP_OPTIONS (vm_app_options,{AST_APP_OPTION('s', OPT_SILENT), AST_APP_OPTION('b', OPT_BUSY_GREETING), AST_APP_OPTION('u', OPT_UNAVAIL_GREETING), AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN), AST_APP_OPTION_ARG('d', OPT_DTMFEXIT, OPT_ARG_DTMFEXIT), AST_APP_OPTION('p', OPT_PREPEND_MAILBOX), AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER), AST_APP_OPTION('U', OPT_MESSAGE_Urgent),}) | |
AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
static | AST_LIST_HEAD_STATIC (zones, vm_zone) |
static | AST_LIST_HEAD_STATIC (users, ast_vm_user) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, tdesc,.load=load_module,.unload=unload_module,.reload=reload,.nonoptreq="res_adsi,res_smdi",) | |
AST_MUTEX_DEFINE_STATIC (poll_lock) | |
static | AST_RWLIST_HEAD_STATIC (mwi_subs, mwi_sub) |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble) |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. | |
static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
AST_TEST_DEFINE (test_voicemail_vmuser) | |
static int | base_encode (char *filename, FILE *so) |
Performs a base 64 encode algorithm on the contents of a File. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
static int | check_mime (const char *str) |
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. | |
static int | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
static int | close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu) |
static char * | complete_voicemail_show_users (const char *line, const char *word, int pos, int state) |
static int | copy (char *infile, char *outfile) |
Utility function to copy a file. | |
static int | copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag) |
Copies a message from one mailbox to another. | |
static void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
static int | count_messages (struct ast_vm_user *vmu, char *dir) |
Find all .txt files - even if they are not in sequence from 0000. | |
static int | create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder) |
basically mkdir -p $dest/$context/$ext/$folder | |
static int | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the users file or the realtime engine. | |
static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the realtime engine. | |
static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent) |
Sends a voicemail message to a mailbox recipient. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
static void | free_zone (struct vm_zone *z) |
static int | get_date (char *s, int len) |
Gets the current date and time, as formatted string. | |
static int | get_folder (struct ast_channel *chan, int start) |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
plays a prompt and waits for a keypress. | |
static int | get_folder_by_name (const char *name) |
static int | handle_subscribe (void *datap) |
static int | handle_unsubscribe (void *datap) |
static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload voicemail configuration from the CLI. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
static int | inbuf (struct baseio *bio, FILE *fi) |
utility used by inchar(), for base_encode() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
static int | inprocess_count (const char *context, const char *mailbox, int delta) |
static int | inprocess_hash_fn (const void *obj, const int flags) |
static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
static int | is_valid_dtmf (const char *key) |
Determines if a DTMF key entered is valid. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
static int | load_config (int reload) |
static int | load_module (void) |
static int | make_dir (char *dest, int len, const char *context, const char *ext, const char *folder) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static int | make_file (char *dest, const int len, const char *dir, const int num) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
static void * | mb_poll_thread (void *data) |
static const char * | mbox (struct ast_vm_user *vmu, int id) |
static int | messagecount (const char *context, const char *mailbox, const char *folder) |
static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
Sends email notification that a user has a new voicemail waiting for them. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback) |
static int | play_message_category (struct ast_channel *chan, const char *category) |
static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag) |
static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
static void | poll_subscribed_mailboxes (void) |
static void | populate_defaults (struct ast_vm_user *vmu) |
Sets default voicemail system options to a voicemail user. | |
static void | prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | valid_config (const struct ast_config *cfg) |
Check if configuration file is valid. | |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
static FILE * | vm_mkftemp (char *template) |
static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
static int | vm_play_folder_name_gr (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static char * | addesc = "Comedian Mail" |
static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
static int | adsiver = 1 |
static char * | app = "VoiceMail" |
static char * | app2 = "VoiceMailMain" |
static char * | app3 = "MailboxExists" |
static char * | app4 = "VMAuthenticate" |
static char | callcontext [AST_MAX_CONTEXT] = "" |
static char | charset [32] = "ISO-8859-1" |
static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
static struct ast_cli_entry | cli_voicemail [] |
static char | dialcontext [AST_MAX_CONTEXT] = "" |
static char * | emailbody = NULL |
static char | emaildateformat [32] = "%A, %B %d, %Y at %r" |
static char * | emailsubject = NULL |
static char | exitcontext [AST_MAX_CONTEXT] = "" |
static char | ext_pass_check_cmd [128] |
static char | ext_pass_cmd [128] |
static char | externnotify [160] |
static char | fromstring [100] |
static struct ast_flags | globalflags = {0} |
struct ao2_container * | inprocess_container |
static char | listen_control_forward_key [12] |
static char | listen_control_pause_key [12] |
static char | listen_control_restart_key [12] |
static char | listen_control_reverse_key [12] |
static char | listen_control_stop_key [12] |
static char | locale [20] |
static struct ast_custom_function | mailbox_exists_acf |
static const char *const | mailbox_folders [] |
static char | mailcmd [160] |
static int | maxdeletedmsg |
static int | maxgreet |
static int | maxlogins |
static int | maxmsg |
static int | maxsilence |
static int | minpassword |
static struct ast_event_sub * | mwi_sub_sub |
static struct ast_taskprocessor * | mwi_subscription_tps |
static struct ast_event_sub * | mwi_unsub_sub |
static int | my_umask |
static char * | pagerbody = NULL |
static char | pagerdateformat [32] = "%A, %B %d, %Y at %r" |
static char | pagerfromstring [100] |
static char * | pagersubject = NULL |
static int | passwordlocation |
static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
static unsigned int | poll_freq |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char * | sayname_app = "VMSayName" |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static struct ast_data_entry | vm_data_providers [] |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
static char | vm_passchanged [80] = "vm-passchanged" |
static char | vm_password [80] = "vm-password" |
static char | vm_pls_try_again [80] = "vm-pls-try-again" |
static char | vm_prepend_timeout [80] = "vm-then-pound" |
static char | vm_reenterpassword [80] = "vm-reenterpassword" |
static char | VM_SPOOL_DIR [PATH_MAX] |
static struct ast_data_handler | vm_users_data_provider |
static char | vmfmts [80] |
static int | vmmaxsecs |
static int | vmminsecs |
static double | volgain |
static char | zonetag [80] |
Comedian Mail - Voicemail System.
Definition in file app_voicemail_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 722 of file app_voicemail_odbcstorage.c.
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11356 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 11383 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 792 of file app_voicemail_odbcstorage.c.
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 723 of file app_voicemail_odbcstorage.c.
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 718 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 720 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 735 of file app_voicemail_odbcstorage.c.
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 734 of file app_voicemail_odbcstorage.c.
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 721 of file app_voicemail_odbcstorage.c.
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 717 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 719 of file app_voicemail_odbcstorage.c.
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 744 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 5403 of file app_voicemail_odbcstorage.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05404 { 05405 DIR *dir; 05406 struct dirent *de; 05407 char fn[256]; 05408 int ret = 0; 05409 05410 /* If no mailbox, return immediately */ 05411 if (ast_strlen_zero(mailbox)) 05412 return 0; 05413 05414 if (ast_strlen_zero(folder)) 05415 folder = "INBOX"; 05416 if (ast_strlen_zero(context)) 05417 context = "default"; 05418 05419 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05420 05421 if (!(dir = opendir(fn))) 05422 return 0; 05423 05424 while ((de = readdir(dir))) { 05425 if (!strncasecmp(de->d_name, "msg", 3)) { 05426 if (shortcircuit) { 05427 ret = 1; 05428 break; 05429 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05430 ret++; 05431 } 05432 } 05433 } 05434 05435 closedir(dir); 05436 05437 return ret; 05438 }
static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | args, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 11059 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().
11060 { 11061 struct ast_vm_user svm; 11062 AST_DECLARE_APP_ARGS(arg, 11063 AST_APP_ARG(mbox); 11064 AST_APP_ARG(context); 11065 ); 11066 11067 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11068 11069 if (ast_strlen_zero(arg.mbox)) { 11070 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11071 return -1; 11072 } 11073 11074 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11075 return 0; 11076 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11893 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().
11894 { 11895 struct ast_vm_user *current; 11896 char *cat; 11897 struct ast_variable *var; 11898 const char *val; 11899 char *q, *stringp, *tmp; 11900 int x; 11901 unsigned int tmpadsi[4]; 11902 char secretfn[PATH_MAX] = ""; 11903 11904 #ifdef IMAP_STORAGE 11905 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11906 #endif 11907 /* set audio control prompts */ 11908 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11909 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11910 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11911 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11912 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11913 11914 /* Free all the users structure */ 11915 free_vm_users(); 11916 11917 /* Free all the zones structure */ 11918 free_vm_zones(); 11919 11920 AST_LIST_LOCK(&users); 11921 11922 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11923 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11924 11925 if (cfg) { 11926 /* General settings */ 11927 11928 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11929 val = "default"; 11930 ast_copy_string(userscontext, val, sizeof(userscontext)); 11931 /* Attach voice message to mail message ? */ 11932 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11933 val = "yes"; 11934 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11935 11936 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11937 val = "no"; 11938 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11939 11940 volgain = 0.0; 11941 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11942 sscanf(val, "%30lf", &volgain); 11943 11944 #ifdef ODBC_STORAGE 11945 strcpy(odbc_database, "asterisk"); 11946 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11947 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11948 } 11949 strcpy(odbc_table, "voicemessages"); 11950 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11951 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11952 } 11953 #endif 11954 /* Mail command */ 11955 strcpy(mailcmd, SENDMAIL); 11956 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11957 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11958 11959 maxsilence = 0; 11960 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11961 maxsilence = atoi(val); 11962 if (maxsilence > 0) 11963 maxsilence *= 1000; 11964 } 11965 11966 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11967 maxmsg = MAXMSG; 11968 } else { 11969 maxmsg = atoi(val); 11970 if (maxmsg < 0) { 11971 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11972 maxmsg = MAXMSG; 11973 } else if (maxmsg > MAXMSGLIMIT) { 11974 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11975 maxmsg = MAXMSGLIMIT; 11976 } 11977 } 11978 11979 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11980 maxdeletedmsg = 0; 11981 } else { 11982 if (sscanf(val, "%30d", &x) == 1) 11983 maxdeletedmsg = x; 11984 else if (ast_true(val)) 11985 maxdeletedmsg = MAXMSG; 11986 else 11987 maxdeletedmsg = 0; 11988 11989 if (maxdeletedmsg < 0) { 11990 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11991 maxdeletedmsg = MAXMSG; 11992 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11993 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11994 maxdeletedmsg = MAXMSGLIMIT; 11995 } 11996 } 11997 11998 /* Load date format config for voicemail mail */ 11999 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 12000 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 12001 } 12002 12003 /* Load date format config for voicemail pager mail */ 12004 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 12005 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 12006 } 12007 12008 /* External password changing command */ 12009 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 12010 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12011 pwdchange = PWDCHANGE_EXTERNAL; 12012 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 12013 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12014 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12015 } 12016 12017 /* External password validation command */ 12018 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12019 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12020 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12021 } 12022 12023 #ifdef IMAP_STORAGE 12024 /* IMAP server address */ 12025 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12026 ast_copy_string(imapserver, val, sizeof(imapserver)); 12027 } else { 12028 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12029 } 12030 /* IMAP server port */ 12031 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12032 ast_copy_string(imapport, val, sizeof(imapport)); 12033 } else { 12034 ast_copy_string(imapport, "143", sizeof(imapport)); 12035 } 12036 /* IMAP server flags */ 12037 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12038 ast_copy_string(imapflags, val, sizeof(imapflags)); 12039 } 12040 /* IMAP server master username */ 12041 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12042 ast_copy_string(authuser, val, sizeof(authuser)); 12043 } 12044 /* IMAP server master password */ 12045 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12046 ast_copy_string(authpassword, val, sizeof(authpassword)); 12047 } 12048 /* Expunge on exit */ 12049 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12050 if (ast_false(val)) 12051 expungeonhangup = 0; 12052 else 12053 expungeonhangup = 1; 12054 } else { 12055 expungeonhangup = 1; 12056 } 12057 /* IMAP voicemail folder */ 12058 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12059 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12060 } else { 12061 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12062 } 12063 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12064 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12065 } 12066 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12067 imapgreetings = ast_true(val); 12068 } else { 12069 imapgreetings = 0; 12070 } 12071 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12072 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12073 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12074 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12075 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12076 } else { 12077 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12078 } 12079 12080 /* There is some very unorthodox casting done here. This is due 12081 * to the way c-client handles the argument passed in. It expects a 12082 * void pointer and casts the pointer directly to a long without 12083 * first dereferencing it. */ 12084 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12085 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12086 } else { 12087 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12088 } 12089 12090 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12091 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12092 } else { 12093 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12094 } 12095 12096 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12097 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12098 } else { 12099 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12100 } 12101 12102 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12103 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12104 } else { 12105 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12106 } 12107 12108 /* Increment configuration version */ 12109 imapversion++; 12110 #endif 12111 /* External voicemail notify application */ 12112 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12113 ast_copy_string(externnotify, val, sizeof(externnotify)); 12114 ast_debug(1, "found externnotify: %s\n", externnotify); 12115 } else { 12116 externnotify[0] = '\0'; 12117 } 12118 12119 /* SMDI voicemail notification */ 12120 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12121 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12122 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12123 smdi_iface = ast_smdi_interface_find(val); 12124 } else { 12125 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12126 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12127 } 12128 if (!smdi_iface) { 12129 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12130 } 12131 } 12132 12133 /* Silence treshold */ 12134 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12135 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12136 silencethreshold = atoi(val); 12137 12138 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12139 val = ASTERISK_USERNAME; 12140 ast_copy_string(serveremail, val, sizeof(serveremail)); 12141 12142 vmmaxsecs = 0; 12143 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12144 if (sscanf(val, "%30d", &x) == 1) { 12145 vmmaxsecs = x; 12146 } else { 12147 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12148 } 12149 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12150 static int maxmessage_deprecate = 0; 12151 if (maxmessage_deprecate == 0) { 12152 maxmessage_deprecate = 1; 12153 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12154 } 12155 if (sscanf(val, "%30d", &x) == 1) { 12156 vmmaxsecs = x; 12157 } else { 12158 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12159 } 12160 } 12161 12162 vmminsecs = 0; 12163 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12164 if (sscanf(val, "%30d", &x) == 1) { 12165 vmminsecs = x; 12166 if (maxsilence / 1000 >= vmminsecs) { 12167 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12168 } 12169 } else { 12170 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12171 } 12172 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12173 static int maxmessage_deprecate = 0; 12174 if (maxmessage_deprecate == 0) { 12175 maxmessage_deprecate = 1; 12176 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12177 } 12178 if (sscanf(val, "%30d", &x) == 1) { 12179 vmminsecs = x; 12180 if (maxsilence / 1000 >= vmminsecs) { 12181 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12182 } 12183 } else { 12184 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12185 } 12186 } 12187 12188 val = ast_variable_retrieve(cfg, "general", "format"); 12189 if (!val) { 12190 val = "wav"; 12191 } else { 12192 tmp = ast_strdupa(val); 12193 val = ast_format_str_reduce(tmp); 12194 if (!val) { 12195 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12196 val = "wav"; 12197 } 12198 } 12199 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12200 12201 skipms = 3000; 12202 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12203 if (sscanf(val, "%30d", &x) == 1) { 12204 maxgreet = x; 12205 } else { 12206 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12207 } 12208 } 12209 12210 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12211 if (sscanf(val, "%30d", &x) == 1) { 12212 skipms = x; 12213 } else { 12214 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12215 } 12216 } 12217 12218 maxlogins = 3; 12219 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12220 if (sscanf(val, "%30d", &x) == 1) { 12221 maxlogins = x; 12222 } else { 12223 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12224 } 12225 } 12226 12227 minpassword = MINPASSWORD; 12228 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12229 if (sscanf(val, "%30d", &x) == 1) { 12230 minpassword = x; 12231 } else { 12232 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12233 } 12234 } 12235 12236 /* Force new user to record name ? */ 12237 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12238 val = "no"; 12239 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12240 12241 /* Force new user to record greetings ? */ 12242 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12243 val = "no"; 12244 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12245 12246 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12247 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12248 stringp = ast_strdupa(val); 12249 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12250 if (!ast_strlen_zero(stringp)) { 12251 q = strsep(&stringp, ","); 12252 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12253 q++; 12254 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12255 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12256 } else { 12257 cidinternalcontexts[x][0] = '\0'; 12258 } 12259 } 12260 } 12261 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12262 ast_debug(1, "VM Review Option disabled globally\n"); 12263 val = "no"; 12264 } 12265 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12266 12267 /* Temporary greeting reminder */ 12268 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12269 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12270 val = "no"; 12271 } else { 12272 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12273 } 12274 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12275 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12276 ast_debug(1, "VM next message wrap disabled globally\n"); 12277 val = "no"; 12278 } 12279 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12280 12281 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12282 ast_debug(1, "VM Operator break disabled globally\n"); 12283 val = "no"; 12284 } 12285 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12286 12287 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12288 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12289 val = "no"; 12290 } 12291 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12292 12293 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12294 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12295 val = "no"; 12296 } 12297 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12298 12299 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12300 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12301 val = "yes"; 12302 } 12303 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12304 12305 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12306 ast_debug(1, "Move Heard enabled globally\n"); 12307 val = "yes"; 12308 } 12309 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12310 12311 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12312 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12313 val = "no"; 12314 } 12315 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12316 12317 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12318 ast_debug(1, "Duration info before msg enabled globally\n"); 12319 val = "yes"; 12320 } 12321 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12322 12323 saydurationminfo = 2; 12324 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12325 if (sscanf(val, "%30d", &x) == 1) { 12326 saydurationminfo = x; 12327 } else { 12328 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12329 } 12330 } 12331 12332 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12333 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12334 val = "no"; 12335 } 12336 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12337 12338 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12339 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12340 ast_debug(1, "found dialout context: %s\n", dialcontext); 12341 } else { 12342 dialcontext[0] = '\0'; 12343 } 12344 12345 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12346 ast_copy_string(callcontext, val, sizeof(callcontext)); 12347 ast_debug(1, "found callback context: %s\n", callcontext); 12348 } else { 12349 callcontext[0] = '\0'; 12350 } 12351 12352 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12353 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12354 ast_debug(1, "found operator context: %s\n", exitcontext); 12355 } else { 12356 exitcontext[0] = '\0'; 12357 } 12358 12359 /* load password sounds configuration */ 12360 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12361 ast_copy_string(vm_password, val, sizeof(vm_password)); 12362 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12363 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12364 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12365 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12366 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12367 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12368 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12369 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12370 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12371 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12372 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12373 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12374 } 12375 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12376 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12377 } 12378 /* load configurable audio prompts */ 12379 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12380 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12381 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12382 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12383 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12384 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12385 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12386 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12387 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12388 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12389 12390 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12391 val = "no"; 12392 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12393 12394 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12395 val = "voicemail.conf"; 12396 } 12397 if (!(strcmp(val, "spooldir"))) { 12398 passwordlocation = OPT_PWLOC_SPOOLDIR; 12399 } else { 12400 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12401 } 12402 12403 poll_freq = DEFAULT_POLL_FREQ; 12404 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12405 if (sscanf(val, "%30u", &poll_freq) != 1) { 12406 poll_freq = DEFAULT_POLL_FREQ; 12407 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12408 } 12409 } 12410 12411 poll_mailboxes = 0; 12412 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12413 poll_mailboxes = ast_true(val); 12414 12415 memset(fromstring, 0, sizeof(fromstring)); 12416 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12417 strcpy(charset, "ISO-8859-1"); 12418 if (emailbody) { 12419 ast_free(emailbody); 12420 emailbody = NULL; 12421 } 12422 if (emailsubject) { 12423 ast_free(emailsubject); 12424 emailsubject = NULL; 12425 } 12426 if (pagerbody) { 12427 ast_free(pagerbody); 12428 pagerbody = NULL; 12429 } 12430 if (pagersubject) { 12431 ast_free(pagersubject); 12432 pagersubject = NULL; 12433 } 12434 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12435 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12436 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12437 ast_copy_string(fromstring, val, sizeof(fromstring)); 12438 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12439 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12440 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12441 ast_copy_string(charset, val, sizeof(charset)); 12442 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12443 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12444 for (x = 0; x < 4; x++) { 12445 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12446 } 12447 } 12448 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12449 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12450 for (x = 0; x < 4; x++) { 12451 memcpy(&adsisec[x], &tmpadsi[x], 1); 12452 } 12453 } 12454 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12455 if (atoi(val)) { 12456 adsiver = atoi(val); 12457 } 12458 } 12459 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12460 ast_copy_string(zonetag, val, sizeof(zonetag)); 12461 } 12462 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12463 ast_copy_string(locale, val, sizeof(locale)); 12464 } 12465 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12466 emailsubject = ast_strdup(substitute_escapes(val)); 12467 } 12468 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12469 emailbody = ast_strdup(substitute_escapes(val)); 12470 } 12471 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12472 pagersubject = ast_strdup(substitute_escapes(val)); 12473 } 12474 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12475 pagerbody = ast_strdup(substitute_escapes(val)); 12476 } 12477 12478 /* load mailboxes from users.conf */ 12479 if (ucfg) { 12480 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12481 if (!strcasecmp(cat, "general")) { 12482 continue; 12483 } 12484 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12485 continue; 12486 if ((current = find_or_create(userscontext, cat))) { 12487 populate_defaults(current); 12488 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12489 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12490 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12491 current->passwordlocation = OPT_PWLOC_USERSCONF; 12492 } 12493 12494 switch (current->passwordlocation) { 12495 case OPT_PWLOC_SPOOLDIR: 12496 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12497 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12498 } 12499 } 12500 } 12501 } 12502 12503 /* load mailboxes from voicemail.conf */ 12504 cat = ast_category_browse(cfg, NULL); 12505 while (cat) { 12506 if (strcasecmp(cat, "general")) { 12507 var = ast_variable_browse(cfg, cat); 12508 if (strcasecmp(cat, "zonemessages")) { 12509 /* Process mailboxes in this context */ 12510 while (var) { 12511 append_mailbox(cat, var->name, var->value); 12512 var = var->next; 12513 } 12514 } else { 12515 /* Timezones in this context */ 12516 while (var) { 12517 struct vm_zone *z; 12518 if ((z = ast_malloc(sizeof(*z)))) { 12519 char *msg_format, *tzone; 12520 msg_format = ast_strdupa(var->value); 12521 tzone = strsep(&msg_format, "|,"); 12522 if (msg_format) { 12523 ast_copy_string(z->name, var->name, sizeof(z->name)); 12524 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12525 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12526 AST_LIST_LOCK(&zones); 12527 AST_LIST_INSERT_HEAD(&zones, z, list); 12528 AST_LIST_UNLOCK(&zones); 12529 } else { 12530 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12531 ast_free(z); 12532 } 12533 } else { 12534 AST_LIST_UNLOCK(&users); 12535 return -1; 12536 } 12537 var = var->next; 12538 } 12539 } 12540 } 12541 cat = ast_category_browse(cfg, cat); 12542 } 12543 12544 AST_LIST_UNLOCK(&users); 12545 12546 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12547 start_poll_thread(); 12548 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12549 stop_poll_thread();; 12550 12551 return 0; 12552 } else { 12553 AST_LIST_UNLOCK(&users); 12554 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12555 return 0; 12556 } 12557 }
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 4817 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().
04818 { 04819 char tmpdir[256], newtmp[256]; 04820 char fname[256]; 04821 char tmpcmd[256]; 04822 int tmpfd = -1; 04823 int soxstatus = 0; 04824 04825 /* Eww. We want formats to tell us their own MIME type */ 04826 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04827 04828 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04829 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04830 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04831 tmpfd = mkstemp(newtmp); 04832 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04833 ast_debug(3, "newtmp: %s\n", newtmp); 04834 if (tmpfd > -1) { 04835 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04836 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04837 attach = newtmp; 04838 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04839 } else { 04840 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04841 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04842 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04843 } 04844 } 04845 } 04846 fprintf(p, "--%s" ENDL, bound); 04847 if (msgnum > -1) 04848 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04849 else 04850 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04851 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04852 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04853 if (msgnum > -1) 04854 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04855 else 04856 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04857 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04858 base_encode(fname, p); 04859 if (last) 04860 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04861 if (tmpfd > -1) { 04862 if (soxstatus == 0) { 04863 unlink(fname); 04864 } 04865 close(tmpfd); 04866 unlink(newtmp); 04867 } 04868 return 0; 04869 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6426 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().
06427 { 06428 int x; 06429 if (!ast_adsi_available(chan)) 06430 return; 06431 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06432 if (x < 0) 06433 return; 06434 if (!x) { 06435 if (adsi_load_vmail(chan, useadsi)) { 06436 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06437 return; 06438 } 06439 } else 06440 *useadsi = 1; 06441 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6621 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().
06622 { 06623 int bytes = 0; 06624 unsigned char buf[256]; 06625 unsigned char keys[8]; 06626 06627 int x; 06628 06629 if (!ast_adsi_available(chan)) 06630 return; 06631 06632 /* New meaning for keys */ 06633 for (x = 0; x < 5; x++) 06634 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06635 06636 keys[6] = 0x0; 06637 keys[7] = 0x0; 06638 06639 if (!vms->curmsg) { 06640 /* No prev key, provide "Folder" instead */ 06641 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06642 } 06643 if (vms->curmsg >= vms->lastmsg) { 06644 /* If last message ... */ 06645 if (vms->curmsg) { 06646 /* but not only message, provide "Folder" instead */ 06647 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06648 } else { 06649 /* Otherwise if only message, leave blank */ 06650 keys[3] = 1; 06651 } 06652 } 06653 06654 /* If deleted, show "undeleted" */ 06655 #ifdef IMAP_STORAGE 06656 ast_mutex_lock(&vms->lock); 06657 #endif 06658 if (vms->deleted[vms->curmsg]) { 06659 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06660 } 06661 #ifdef IMAP_STORAGE 06662 ast_mutex_unlock(&vms->lock); 06663 #endif 06664 06665 /* Except "Exit" */ 06666 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06667 bytes += ast_adsi_set_keys(buf + bytes, keys); 06668 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06669 06670 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06671 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6491 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().
06492 { 06493 unsigned char buf[256]; 06494 int bytes = 0; 06495 unsigned char keys[8]; 06496 int x, y; 06497 06498 if (!ast_adsi_available(chan)) 06499 return; 06500 06501 for (x = 0; x < 5; x++) { 06502 y = ADSI_KEY_APPS + 12 + start + x; 06503 if (y > ADSI_KEY_APPS + 12 + 4) 06504 y = 0; 06505 keys[x] = ADSI_KEY_SKT | y; 06506 } 06507 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06508 keys[6] = 0; 06509 keys[7] = 0; 06510 06511 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06512 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06513 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06514 bytes += ast_adsi_set_keys(buf + bytes, keys); 06515 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06516 06517 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06518 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6776 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().
06777 { 06778 unsigned char buf[256]; 06779 int bytes = 0; 06780 06781 if (!ast_adsi_available(chan)) 06782 return; 06783 bytes += adsi_logo(buf + bytes); 06784 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06785 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06786 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06787 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06788 06789 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06790 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6297 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().
06298 { 06299 unsigned char buf[256]; 06300 int bytes = 0; 06301 int x; 06302 char num[5]; 06303 06304 *useadsi = 0; 06305 bytes += ast_adsi_data_mode(buf + bytes); 06306 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06307 06308 bytes = 0; 06309 bytes += adsi_logo(buf); 06310 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06311 #ifdef DISPLAY 06312 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06313 #endif 06314 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06315 bytes += ast_adsi_data_mode(buf + bytes); 06316 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06317 06318 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06319 bytes = 0; 06320 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06321 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06322 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06323 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06324 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06325 return 0; 06326 } 06327 06328 #ifdef DISPLAY 06329 /* Add a dot */ 06330 bytes = 0; 06331 bytes += ast_adsi_logo(buf); 06332 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06333 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06334 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06335 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06336 #endif 06337 bytes = 0; 06338 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06339 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06340 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06341 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06342 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06343 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06344 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06345 06346 #ifdef DISPLAY 06347 /* Add another dot */ 06348 bytes = 0; 06349 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06350 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06351 06352 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06353 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06354 #endif 06355 06356 bytes = 0; 06357 /* These buttons we load but don't use yet */ 06358 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06359 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06360 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06361 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06362 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06363 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06364 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06365 06366 #ifdef DISPLAY 06367 /* Add another dot */ 06368 bytes = 0; 06369 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06370 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06371 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06372 #endif 06373 06374 bytes = 0; 06375 for (x = 0; x < 5; x++) { 06376 snprintf(num, sizeof(num), "%d", x); 06377 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06378 } 06379 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06380 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06381 06382 #ifdef DISPLAY 06383 /* Add another dot */ 06384 bytes = 0; 06385 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06386 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06387 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06388 #endif 06389 06390 if (ast_adsi_end_download(chan)) { 06391 bytes = 0; 06392 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06393 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06394 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06395 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06396 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06397 return 0; 06398 } 06399 bytes = 0; 06400 bytes += ast_adsi_download_disconnect(buf + bytes); 06401 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06402 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06403 06404 ast_debug(1, "Done downloading scripts...\n"); 06405 06406 #ifdef DISPLAY 06407 /* Add last dot */ 06408 bytes = 0; 06409 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06410 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06411 #endif 06412 ast_debug(1, "Restarting session...\n"); 06413 06414 bytes = 0; 06415 /* Load the session now */ 06416 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06417 *useadsi = 1; 06418 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06419 } else 06420 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06421 06422 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06423 return 0; 06424 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6443 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().
06444 { 06445 unsigned char buf[256]; 06446 int bytes = 0; 06447 unsigned char keys[8]; 06448 int x; 06449 if (!ast_adsi_available(chan)) 06450 return; 06451 06452 for (x = 0; x < 8; x++) 06453 keys[x] = 0; 06454 /* Set one key for next */ 06455 keys[3] = ADSI_KEY_APPS + 3; 06456 06457 bytes += adsi_logo(buf + bytes); 06458 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06459 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06460 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06461 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06462 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06463 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06464 bytes += ast_adsi_set_keys(buf + bytes, keys); 06465 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06466 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06467 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6289 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().
06290 { 06291 int bytes = 0; 06292 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06293 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06294 return bytes; 06295 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6520 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().
06521 { 06522 int bytes = 0; 06523 unsigned char buf[256]; 06524 char buf1[256], buf2[256]; 06525 char fn2[PATH_MAX]; 06526 06527 char cid[256] = ""; 06528 char *val; 06529 char *name, *num; 06530 char datetime[21] = ""; 06531 FILE *f; 06532 06533 unsigned char keys[8]; 06534 06535 int x; 06536 06537 if (!ast_adsi_available(chan)) 06538 return; 06539 06540 /* Retrieve important info */ 06541 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06542 f = fopen(fn2, "r"); 06543 if (f) { 06544 while (!feof(f)) { 06545 if (!fgets((char *) buf, sizeof(buf), f)) { 06546 continue; 06547 } 06548 if (!feof(f)) { 06549 char *stringp = NULL; 06550 stringp = (char *) buf; 06551 strsep(&stringp, "="); 06552 val = strsep(&stringp, "="); 06553 if (!ast_strlen_zero(val)) { 06554 if (!strcmp((char *) buf, "callerid")) 06555 ast_copy_string(cid, val, sizeof(cid)); 06556 if (!strcmp((char *) buf, "origdate")) 06557 ast_copy_string(datetime, val, sizeof(datetime)); 06558 } 06559 } 06560 } 06561 fclose(f); 06562 } 06563 /* New meaning for keys */ 06564 for (x = 0; x < 5; x++) 06565 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06566 keys[6] = 0x0; 06567 keys[7] = 0x0; 06568 06569 if (!vms->curmsg) { 06570 /* No prev key, provide "Folder" instead */ 06571 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06572 } 06573 if (vms->curmsg >= vms->lastmsg) { 06574 /* If last message ... */ 06575 if (vms->curmsg) { 06576 /* but not only message, provide "Folder" instead */ 06577 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06578 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06579 06580 } else { 06581 /* Otherwise if only message, leave blank */ 06582 keys[3] = 1; 06583 } 06584 } 06585 06586 if (!ast_strlen_zero(cid)) { 06587 ast_callerid_parse(cid, &name, &num); 06588 if (!name) 06589 name = num; 06590 } else 06591 name = "Unknown Caller"; 06592 06593 /* If deleted, show "undeleted" */ 06594 #ifdef IMAP_STORAGE 06595 ast_mutex_lock(&vms->lock); 06596 #endif 06597 if (vms->deleted[vms->curmsg]) { 06598 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06599 } 06600 #ifdef IMAP_STORAGE 06601 ast_mutex_unlock(&vms->lock); 06602 #endif 06603 06604 /* Except "Exit" */ 06605 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06606 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06607 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06608 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06609 06610 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06611 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06612 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06613 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06614 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06615 bytes += ast_adsi_set_keys(buf + bytes, keys); 06616 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06617 06618 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06619 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6469 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().
06470 { 06471 unsigned char buf[256]; 06472 int bytes = 0; 06473 unsigned char keys[8]; 06474 int x; 06475 if (!ast_adsi_available(chan)) 06476 return; 06477 06478 for (x = 0; x < 8; x++) 06479 keys[x] = 0; 06480 /* Set one key for next */ 06481 keys[3] = ADSI_KEY_APPS + 3; 06482 06483 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06484 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06485 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06486 bytes += ast_adsi_set_keys(buf + bytes, keys); 06487 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06488 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06489 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6673 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().
06674 { 06675 unsigned char buf[256] = ""; 06676 char buf1[256] = "", buf2[256] = ""; 06677 int bytes = 0; 06678 unsigned char keys[8]; 06679 int x; 06680 06681 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06682 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06683 if (!ast_adsi_available(chan)) 06684 return; 06685 if (vms->newmessages) { 06686 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06687 if (vms->oldmessages) { 06688 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06689 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06690 } else { 06691 snprintf(buf2, sizeof(buf2), "%s.", newm); 06692 } 06693 } else if (vms->oldmessages) { 06694 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06695 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06696 } else { 06697 strcpy(buf1, "You have no messages."); 06698 buf2[0] = ' '; 06699 buf2[1] = '\0'; 06700 } 06701 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06702 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06703 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06704 06705 for (x = 0; x < 6; x++) 06706 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06707 keys[6] = 0; 06708 keys[7] = 0; 06709 06710 /* Don't let them listen if there are none */ 06711 if (vms->lastmsg < 0) 06712 keys[0] = 1; 06713 bytes += ast_adsi_set_keys(buf + bytes, keys); 06714 06715 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06716 06717 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06718 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6720 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().
06721 { 06722 unsigned char buf[256] = ""; 06723 char buf1[256] = "", buf2[256] = ""; 06724 int bytes = 0; 06725 unsigned char keys[8]; 06726 int x; 06727 06728 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06729 06730 if (!ast_adsi_available(chan)) 06731 return; 06732 06733 /* Original command keys */ 06734 for (x = 0; x < 6; x++) 06735 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06736 06737 keys[6] = 0; 06738 keys[7] = 0; 06739 06740 if ((vms->lastmsg + 1) < 1) 06741 keys[0] = 0; 06742 06743 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06744 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06745 06746 if (vms->lastmsg + 1) 06747 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06748 else 06749 strcpy(buf2, "no messages."); 06750 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06751 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06752 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06753 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06754 bytes += ast_adsi_set_keys(buf + bytes, keys); 06755 06756 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06757 06758 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06759 06760 }
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 13265 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, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, valid_config(), and wait_file().
Referenced by vm_execmain().
13266 { 13267 int res = 0; 13268 char filename[PATH_MAX]; 13269 struct ast_config *msg_cfg = NULL; 13270 const char *origtime, *context; 13271 char *name, *num; 13272 int retries = 0; 13273 char *cid; 13274 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13275 13276 vms->starting = 0; 13277 13278 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13279 13280 /* Retrieve info from VM attribute file */ 13281 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13282 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13283 msg_cfg = ast_config_load(filename, config_flags); 13284 DISPOSE(vms->curdir, vms->curmsg); 13285 if (!valid_config(msg_cfg)) { 13286 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13287 return 0; 13288 } 13289 13290 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13291 ast_config_destroy(msg_cfg); 13292 return 0; 13293 } 13294 13295 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13296 13297 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13298 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13299 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13300 switch (option) { 13301 case 3: /* Play message envelope */ 13302 if (!res) 13303 res = play_message_datetime(chan, vmu, origtime, filename); 13304 if (!res) 13305 res = play_message_callerid(chan, vms, cid, context, 0); 13306 13307 res = 't'; 13308 break; 13309 13310 case 2: /* Call back */ 13311 13312 if (ast_strlen_zero(cid)) 13313 break; 13314 13315 ast_callerid_parse(cid, &name, &num); 13316 while ((res > -1) && (res != 't')) { 13317 switch (res) { 13318 case '1': 13319 if (num) { 13320 /* Dial the CID number */ 13321 res = dialout(chan, vmu, num, vmu->callback); 13322 if (res) { 13323 ast_config_destroy(msg_cfg); 13324 return 9; 13325 } 13326 } else { 13327 res = '2'; 13328 } 13329 break; 13330 13331 case '2': 13332 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13333 if (!ast_strlen_zero(vmu->dialout)) { 13334 res = dialout(chan, vmu, NULL, vmu->dialout); 13335 if (res) { 13336 ast_config_destroy(msg_cfg); 13337 return 9; 13338 } 13339 } else { 13340 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13341 res = ast_play_and_wait(chan, "vm-sorry"); 13342 } 13343 ast_config_destroy(msg_cfg); 13344 return res; 13345 case '*': 13346 res = 't'; 13347 break; 13348 case '3': 13349 case '4': 13350 case '5': 13351 case '6': 13352 case '7': 13353 case '8': 13354 case '9': 13355 case '0': 13356 13357 res = ast_play_and_wait(chan, "vm-sorry"); 13358 retries++; 13359 break; 13360 default: 13361 if (num) { 13362 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13363 res = ast_play_and_wait(chan, "vm-num-i-have"); 13364 if (!res) 13365 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13366 if (!res) 13367 res = ast_play_and_wait(chan, "vm-tocallnum"); 13368 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13369 if (!ast_strlen_zero(vmu->dialout)) { 13370 if (!res) 13371 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13372 } 13373 } else { 13374 res = ast_play_and_wait(chan, "vm-nonumber"); 13375 if (!ast_strlen_zero(vmu->dialout)) { 13376 if (!res) 13377 res = ast_play_and_wait(chan, "vm-toenternumber"); 13378 } 13379 } 13380 if (!res) { 13381 res = ast_play_and_wait(chan, "vm-star-cancel"); 13382 } 13383 if (!res) { 13384 res = ast_waitfordigit(chan, 6000); 13385 } 13386 if (!res) { 13387 retries++; 13388 if (retries > 3) { 13389 res = 't'; 13390 } 13391 } 13392 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13393 break; 13394 13395 } 13396 if (res == 't') 13397 res = 0; 13398 else if (res == '*') 13399 res = -1; 13400 } 13401 break; 13402 13403 case 1: /* Reply */ 13404 /* Send reply directly to sender */ 13405 if (ast_strlen_zero(cid)) 13406 break; 13407 13408 ast_callerid_parse(cid, &name, &num); 13409 if (!num) { 13410 ast_verb(3, "No CID number available, no reply sent\n"); 13411 if (!res) 13412 res = ast_play_and_wait(chan, "vm-nonumber"); 13413 ast_config_destroy(msg_cfg); 13414 return res; 13415 } else { 13416 struct ast_vm_user vmu2; 13417 if (find_user(&vmu2, vmu->context, num)) { 13418 struct leave_vm_options leave_options; 13419 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13420 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13421 13422 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13423 13424 memset(&leave_options, 0, sizeof(leave_options)); 13425 leave_options.record_gain = record_gain; 13426 res = leave_voicemail(chan, mailbox, &leave_options); 13427 if (!res) 13428 res = 't'; 13429 ast_config_destroy(msg_cfg); 13430 return res; 13431 } else { 13432 /* Sender has no mailbox, can't reply */ 13433 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13434 ast_play_and_wait(chan, "vm-nobox"); 13435 res = 't'; 13436 ast_config_destroy(msg_cfg); 13437 return res; 13438 } 13439 } 13440 res = 0; 13441 13442 break; 13443 } 13444 13445 ast_config_destroy(msg_cfg); 13446 13447 #ifndef IMAP_STORAGE 13448 if (!res) { 13449 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13450 vms->heard[msg] = 1; 13451 res = wait_file(chan, vms, vms->fn); 13452 } 13453 #endif 13454 return res; 13455 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10786 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().
10787 { 10788 /* Assumes lock is already held */ 10789 char *tmp; 10790 char *stringp; 10791 char *s; 10792 struct ast_vm_user *vmu; 10793 char *mailbox_full; 10794 int new = 0, old = 0, urgent = 0; 10795 char secretfn[PATH_MAX] = ""; 10796 10797 tmp = ast_strdupa(data); 10798 10799 if (!(vmu = find_or_create(context, box))) 10800 return -1; 10801 10802 populate_defaults(vmu); 10803 10804 stringp = tmp; 10805 if ((s = strsep(&stringp, ","))) { 10806 if (!ast_strlen_zero(s) && s[0] == '*') { 10807 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10808 "\n\tmust be reset in voicemail.conf.\n", box); 10809 } 10810 /* assign password regardless of validity to prevent NULL password from being assigned */ 10811 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10812 } 10813 if (stringp && (s = strsep(&stringp, ","))) { 10814 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10815 } 10816 if (stringp && (s = strsep(&stringp, ","))) { 10817 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10818 } 10819 if (stringp && (s = strsep(&stringp, ","))) { 10820 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10821 } 10822 if (stringp && (s = strsep(&stringp, ","))) { 10823 apply_options(vmu, s); 10824 } 10825 10826 switch (vmu->passwordlocation) { 10827 case OPT_PWLOC_SPOOLDIR: 10828 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10829 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10830 } 10831 10832 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 10833 strcpy(mailbox_full, box); 10834 strcat(mailbox_full, "@"); 10835 strcat(mailbox_full, context); 10836 10837 inboxcount2(mailbox_full, &urgent, &new, &old); 10838 queue_mwi_event(mailbox_full, urgent, new, old); 10839 10840 return 0; 10841 }
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 1037 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().
01038 { 01039 int x; 01040 if (!strcasecmp(var, "attach")) { 01041 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01042 } else if (!strcasecmp(var, "attachfmt")) { 01043 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01044 } else if (!strcasecmp(var, "serveremail")) { 01045 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01046 } else if (!strcasecmp(var, "emailbody")) { 01047 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01048 } else if (!strcasecmp(var, "emailsubject")) { 01049 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01050 } else if (!strcasecmp(var, "language")) { 01051 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01052 } else if (!strcasecmp(var, "tz")) { 01053 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01054 } else if (!strcasecmp(var, "locale")) { 01055 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01056 #ifdef IMAP_STORAGE 01057 } else if (!strcasecmp(var, "imapuser")) { 01058 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01059 vmu->imapversion = imapversion; 01060 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01061 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01062 vmu->imapversion = imapversion; 01063 } else if (!strcasecmp(var, "imapfolder")) { 01064 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01065 } else if (!strcasecmp(var, "imapvmshareid")) { 01066 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01067 vmu->imapversion = imapversion; 01068 #endif 01069 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01070 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01071 } else if (!strcasecmp(var, "saycid")){ 01072 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01073 } else if (!strcasecmp(var, "sendvoicemail")){ 01074 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01075 } else if (!strcasecmp(var, "review")){ 01076 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01077 } else if (!strcasecmp(var, "tempgreetwarn")){ 01078 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01079 } else if (!strcasecmp(var, "messagewrap")){ 01080 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01081 } else if (!strcasecmp(var, "operator")) { 01082 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01083 } else if (!strcasecmp(var, "envelope")){ 01084 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01085 } else if (!strcasecmp(var, "moveheard")){ 01086 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01087 } else if (!strcasecmp(var, "sayduration")){ 01088 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01089 } else if (!strcasecmp(var, "saydurationm")){ 01090 if (sscanf(value, "%30d", &x) == 1) { 01091 vmu->saydurationm = x; 01092 } else { 01093 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01094 } 01095 } else if (!strcasecmp(var, "forcename")){ 01096 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01097 } else if (!strcasecmp(var, "forcegreetings")){ 01098 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01099 } else if (!strcasecmp(var, "callback")) { 01100 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01101 } else if (!strcasecmp(var, "dialout")) { 01102 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01103 } else if (!strcasecmp(var, "exitcontext")) { 01104 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01105 } else if (!strcasecmp(var, "minsecs")) { 01106 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01107 vmu->minsecs = x; 01108 } else { 01109 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01110 vmu->minsecs = vmminsecs; 01111 } 01112 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01113 vmu->maxsecs = atoi(value); 01114 if (vmu->maxsecs <= 0) { 01115 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01116 vmu->maxsecs = vmmaxsecs; 01117 } else { 01118 vmu->maxsecs = atoi(value); 01119 } 01120 if (!strcasecmp(var, "maxmessage")) 01121 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01122 } else if (!strcasecmp(var, "maxmsg")) { 01123 vmu->maxmsg = atoi(value); 01124 /* Accept maxmsg=0 (Greetings only voicemail) */ 01125 if (vmu->maxmsg < 0) { 01126 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01127 vmu->maxmsg = MAXMSG; 01128 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01129 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01130 vmu->maxmsg = MAXMSGLIMIT; 01131 } 01132 } else if (!strcasecmp(var, "nextaftercmd")) { 01133 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01134 } else if (!strcasecmp(var, "backupdeleted")) { 01135 if (sscanf(value, "%30d", &x) == 1) 01136 vmu->maxdeletedmsg = x; 01137 else if (ast_true(value)) 01138 vmu->maxdeletedmsg = MAXMSG; 01139 else 01140 vmu->maxdeletedmsg = 0; 01141 01142 if (vmu->maxdeletedmsg < 0) { 01143 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01144 vmu->maxdeletedmsg = MAXMSG; 01145 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01146 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01147 vmu->maxdeletedmsg = MAXMSGLIMIT; 01148 } 01149 } else if (!strcasecmp(var, "volgain")) { 01150 sscanf(value, "%30lf", &vmu->volgain); 01151 } else if (!strcasecmp(var, "passwordlocation")) { 01152 if (!strcasecmp(value, "spooldir")) { 01153 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01154 } else { 01155 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01156 } 01157 } else if (!strcasecmp(var, "options")) { 01158 apply_options(vmu, value); 01159 } 01160 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1278 of file app_voicemail_odbcstorage.c.
References apply_option(), ast_strdupa, value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01279 { 01280 char *stringp; 01281 char *s; 01282 char *var, *value; 01283 stringp = ast_strdupa(options); 01284 while ((s = strsep(&stringp, "|"))) { 01285 value = s; 01286 if ((var = strsep(&value, "=")) && value) { 01287 apply_option(vmu, var, value); 01288 } 01289 } 01290 }
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 1297 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().
01298 { 01299 for (; var; var = var->next) { 01300 if (!strcasecmp(var->name, "vmsecret")) { 01301 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01302 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01303 if (ast_strlen_zero(retval->password)) { 01304 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01305 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01306 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01307 } else { 01308 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01309 } 01310 } 01311 } else if (!strcasecmp(var->name, "uniqueid")) { 01312 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01313 } else if (!strcasecmp(var->name, "pager")) { 01314 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01315 } else if (!strcasecmp(var->name, "email")) { 01316 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01317 } else if (!strcasecmp(var->name, "fullname")) { 01318 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01319 } else if (!strcasecmp(var->name, "context")) { 01320 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01321 } else if (!strcasecmp(var->name, "emailsubject")) { 01322 ast_free(retval->emailsubject); 01323 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01324 } else if (!strcasecmp(var->name, "emailbody")) { 01325 ast_free(retval->emailbody); 01326 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01327 #ifdef IMAP_STORAGE 01328 } else if (!strcasecmp(var->name, "imapuser")) { 01329 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01330 retval->imapversion = imapversion; 01331 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01332 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01333 retval->imapversion = imapversion; 01334 } else if (!strcasecmp(var->name, "imapfolder")) { 01335 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01336 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01337 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01338 retval->imapversion = imapversion; 01339 #endif 01340 } else 01341 apply_option(retval, var->name, var->value); 01342 } 01343 }
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 4492 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().
04493 { 04494 struct ast_str *tmp = ast_str_alloca(80); 04495 int first_section = 1; 04496 04497 ast_str_reset(*end); 04498 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04499 for (; *start; start++) { 04500 int need_encoding = 0; 04501 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04502 need_encoding = 1; 04503 } 04504 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04505 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04506 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04507 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04508 /* Start new line */ 04509 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04510 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04511 first_section = 0; 04512 } 04513 if (need_encoding && *start == ' ') { 04514 ast_str_append(&tmp, -1, "_"); 04515 } else if (need_encoding) { 04516 ast_str_append(&tmp, -1, "=%hhX", *start); 04517 } else { 04518 ast_str_append(&tmp, -1, "%c", *start); 04519 } 04520 } 04521 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04522 return ast_str_buffer(*end); 04523 }
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 4420 of file app_voicemail_odbcstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), and sendpage().
04421 { 04422 const char *ptr; 04423 04424 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04425 ast_str_set(buf, maxlen, "\""); 04426 for (ptr = from; *ptr; ptr++) { 04427 if (*ptr == '"' || *ptr == '\\') { 04428 ast_str_append(buf, maxlen, "\\%c", *ptr); 04429 } else { 04430 ast_str_append(buf, maxlen, "%c", *ptr); 04431 } 04432 } 04433 ast_str_append(buf, maxlen, "\""); 04434 04435 return ast_str_buffer(*buf); 04436 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10843 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.
10844 { 10845 int res = 0; 10846 struct ast_vm_user *vmu; 10847 /* language parameter seems to only be used for display in manager action */ 10848 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10849 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10850 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10851 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10852 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10853 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10854 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10855 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10856 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10857 #ifdef IMAP_STORAGE 10858 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10859 "imapfolder=INBOX|imapvmshareid=6000"; 10860 #endif 10861 10862 switch (cmd) { 10863 case TEST_INIT: 10864 info->name = "vmuser"; 10865 info->category = "/apps/app_voicemail/"; 10866 info->summary = "Vmuser unit test"; 10867 info->description = 10868 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10869 return AST_TEST_NOT_RUN; 10870 case TEST_EXECUTE: 10871 break; 10872 } 10873 10874 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10875 return AST_TEST_NOT_RUN; 10876 } 10877 populate_defaults(vmu); 10878 ast_set_flag(vmu, VM_ALLOCED); 10879 10880 apply_options(vmu, options_string); 10881 10882 if (!ast_test_flag(vmu, VM_ATTACH)) { 10883 ast_test_status_update(test, "Parse failure for attach option\n"); 10884 res = 1; 10885 } 10886 if (strcasecmp(vmu->attachfmt, "wav49")) { 10887 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10888 res = 1; 10889 } 10890 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10891 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10892 res = 1; 10893 } 10894 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10895 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10896 res = 1; 10897 } 10898 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10899 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10900 res = 1; 10901 } 10902 if (strcasecmp(vmu->zonetag, "central")) { 10903 ast_test_status_update(test, "Parse failure for tz option\n"); 10904 res = 1; 10905 } 10906 if (!ast_test_flag(vmu, VM_DELETE)) { 10907 ast_test_status_update(test, "Parse failure for delete option\n"); 10908 res = 1; 10909 } 10910 if (!ast_test_flag(vmu, VM_SAYCID)) { 10911 ast_test_status_update(test, "Parse failure for saycid option\n"); 10912 res = 1; 10913 } 10914 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10915 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10916 res = 1; 10917 } 10918 if (!ast_test_flag(vmu, VM_REVIEW)) { 10919 ast_test_status_update(test, "Parse failure for review option\n"); 10920 res = 1; 10921 } 10922 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10923 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10924 res = 1; 10925 } 10926 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10927 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10928 res = 1; 10929 } 10930 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10931 ast_test_status_update(test, "Parse failure for operator option\n"); 10932 res = 1; 10933 } 10934 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10935 ast_test_status_update(test, "Parse failure for envelope option\n"); 10936 res = 1; 10937 } 10938 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10939 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10940 res = 1; 10941 } 10942 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10943 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10944 res = 1; 10945 } 10946 if (vmu->saydurationm != 5) { 10947 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10948 res = 1; 10949 } 10950 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10951 ast_test_status_update(test, "Parse failure for forcename option\n"); 10952 res = 1; 10953 } 10954 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10955 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10956 res = 1; 10957 } 10958 if (strcasecmp(vmu->callback, "somecontext")) { 10959 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10960 res = 1; 10961 } 10962 if (strcasecmp(vmu->dialout, "somecontext2")) { 10963 ast_test_status_update(test, "Parse failure for dialout option\n"); 10964 res = 1; 10965 } 10966 if (strcasecmp(vmu->exit, "somecontext3")) { 10967 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10968 res = 1; 10969 } 10970 if (vmu->minsecs != 10) { 10971 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10972 res = 1; 10973 } 10974 if (vmu->maxsecs != 100) { 10975 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10976 res = 1; 10977 } 10978 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10979 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10980 res = 1; 10981 } 10982 if (vmu->maxdeletedmsg != 50) { 10983 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10984 res = 1; 10985 } 10986 if (vmu->volgain != 1.3) { 10987 ast_test_status_update(test, "Parse failure for volgain option\n"); 10988 res = 1; 10989 } 10990 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10991 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10992 res = 1; 10993 } 10994 #ifdef IMAP_STORAGE 10995 apply_options(vmu, option_string2); 10996 10997 if (strcasecmp(vmu->imapuser, "imapuser")) { 10998 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10999 res = 1; 11000 } 11001 if (strcasecmp(vmu->imappassword, "imappasswd")) { 11002 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11003 res = 1; 11004 } 11005 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11006 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 11007 res = 1; 11008 } 11009 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11010 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11011 res = 1; 11012 } 11013 #endif 11014 11015 free_user(vmu); 11016 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11017 }
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 4296 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().
04297 { 04298 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04299 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04300 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04301 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04302 int i, hiteof = 0; 04303 FILE *fi; 04304 struct baseio bio; 04305 04306 memset(&bio, 0, sizeof(bio)); 04307 bio.iocp = BASEMAXINLINE; 04308 04309 if (!(fi = fopen(filename, "rb"))) { 04310 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04311 return -1; 04312 } 04313 04314 while (!hiteof){ 04315 unsigned char igroup[3], ogroup[4]; 04316 int c, n; 04317 04318 memset(igroup, 0, sizeof(igroup)); 04319 04320 for (n = 0; n < 3; n++) { 04321 if ((c = inchar(&bio, fi)) == EOF) { 04322 hiteof = 1; 04323 break; 04324 } 04325 04326 igroup[n] = (unsigned char) c; 04327 } 04328 04329 if (n > 0) { 04330 ogroup[0]= dtable[igroup[0] >> 2]; 04331 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04332 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04333 ogroup[3]= dtable[igroup[2] & 0x3F]; 04334 04335 if (n < 3) { 04336 ogroup[3] = '='; 04337 04338 if (n < 2) 04339 ogroup[2] = '='; 04340 } 04341 04342 for (i = 0; i < 4; i++) 04343 ochar(&bio, ogroup[i], so); 04344 } 04345 } 04346 04347 fclose(fi); 04348 04349 if (fputs(ENDL, so) == EOF) { 04350 return 0; 04351 } 04352 04353 return 1; 04354 }
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 1256 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().
01257 { 01258 int res = -1; 01259 if (!strcmp(vmu->password, password)) { 01260 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01261 return 0; 01262 } 01263 01264 if (strlen(password) > 10) { 01265 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01266 } 01267 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01268 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01269 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01270 res = 0; 01271 } 01272 return res; 01273 }
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 4465 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 1215 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().
01216 { 01217 /* check minimum length */ 01218 if (strlen(password) < minpassword) 01219 return 1; 01220 /* check that password does not contain '*' character */ 01221 if (!ast_strlen_zero(password) && password[0] == '*') 01222 return 1; 01223 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01224 char cmd[255], buf[255]; 01225 01226 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01227 01228 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01229 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01230 ast_debug(5, "Result: %s\n", buf); 01231 if (!strncasecmp(buf, "VALID", 5)) { 01232 ast_debug(3, "Passed password check: '%s'\n", buf); 01233 return 0; 01234 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01235 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01236 return 0; 01237 } else { 01238 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01239 return 1; 01240 } 01241 } 01242 } 01243 return 0; 01244 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7985 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().
07986 { 07987 int x = 0; 07988 int last_msg_idx = 0; 07989 07990 #ifndef IMAP_STORAGE 07991 int res = 0, nummsg; 07992 char fn2[PATH_MAX]; 07993 #endif 07994 07995 if (vms->lastmsg <= -1) { 07996 goto done; 07997 } 07998 07999 vms->curmsg = -1; 08000 #ifndef IMAP_STORAGE 08001 /* Get the deleted messages fixed */ 08002 if (vm_lock_path(vms->curdir)) { 08003 return ERROR_LOCK_PATH; 08004 } 08005 08006 /* update count as message may have arrived while we've got mailbox open */ 08007 last_msg_idx = last_message_index(vmu, vms->curdir); 08008 if (last_msg_idx != vms->lastmsg) { 08009 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08010 } 08011 08012 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08013 for (x = 0; x < last_msg_idx + 1; x++) { 08014 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08015 /* Save this message. It's not in INBOX or hasn't been heard */ 08016 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08017 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08018 break; 08019 } 08020 vms->curmsg++; 08021 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08022 if (strcmp(vms->fn, fn2)) { 08023 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08024 } 08025 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08026 /* Move to old folder before deleting */ 08027 res = save_to_folder(vmu, vms, x, 1); 08028 if (res == ERROR_LOCK_PATH) { 08029 /* If save failed do not delete the message */ 08030 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08031 vms->deleted[x] = 0; 08032 vms->heard[x] = 0; 08033 --x; 08034 } 08035 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08036 /* Move to deleted folder */ 08037 res = save_to_folder(vmu, vms, x, 10); 08038 if (res == ERROR_LOCK_PATH) { 08039 /* If save failed do not delete the message */ 08040 vms->deleted[x] = 0; 08041 vms->heard[x] = 0; 08042 --x; 08043 } 08044 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08045 /* If realtime storage enabled - we should explicitly delete this message, 08046 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08047 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08048 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08049 DELETE(vms->curdir, x, vms->fn, vmu); 08050 } 08051 } 08052 } 08053 08054 /* Delete ALL remaining messages */ 08055 nummsg = x - 1; 08056 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08057 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08058 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08059 DELETE(vms->curdir, x, vms->fn, vmu); 08060 } 08061 } 08062 ast_unlock_path(vms->curdir); 08063 #else /* defined(IMAP_STORAGE) */ 08064 ast_mutex_lock(&vms->lock); 08065 if (vms->deleted) { 08066 /* Since we now expunge after each delete, deleting in reverse order 08067 * ensures that no reordering occurs between each step. */ 08068 last_msg_idx = vms->dh_arraysize; 08069 for (x = last_msg_idx - 1; x >= 0; x--) { 08070 if (vms->deleted[x]) { 08071 ast_debug(3, "IMAP delete of %d\n", x); 08072 DELETE(vms->curdir, x, vms->fn, vmu); 08073 } 08074 } 08075 } 08076 #endif 08077 08078 done: 08079 if (vms->deleted) { 08080 ast_free(vms->deleted); 08081 vms->deleted = NULL; 08082 } 08083 if (vms->heard) { 08084 ast_free(vms->heard); 08085 vms->heard = NULL; 08086 } 08087 vms->dh_arraysize = 0; 08088 #ifdef IMAP_STORAGE 08089 ast_mutex_unlock(&vms->lock); 08090 #endif 08091 08092 return 0; 08093 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11163 of file app_voicemail_odbcstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
11164 { 11165 int which = 0; 11166 int wordlen; 11167 struct ast_vm_user *vmu; 11168 const char *context = ""; 11169 11170 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11171 if (pos > 4) 11172 return NULL; 11173 if (pos == 3) 11174 return (state == 0) ? ast_strdup("for") : NULL; 11175 wordlen = strlen(word); 11176 AST_LIST_TRAVERSE(&users, vmu, list) { 11177 if (!strncasecmp(word, vmu->context, wordlen)) { 11178 if (context && strcmp(context, vmu->context) && ++which > state) 11179 return ast_strdup(vmu->context); 11180 /* ignore repeated contexts ? */ 11181 context = vmu->context; 11182 } 11183 } 11184 return NULL; 11185 }
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 4101 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().
04102 { 04103 int ifd; 04104 int ofd; 04105 int res; 04106 int len; 04107 char buf[4096]; 04108 04109 #ifdef HARDLINK_WHEN_POSSIBLE 04110 /* Hard link if possible; saves disk space & is faster */ 04111 if (link(infile, outfile)) { 04112 #endif 04113 if ((ifd = open(infile, O_RDONLY)) < 0) { 04114 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04115 return -1; 04116 } 04117 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04118 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04119 close(ifd); 04120 return -1; 04121 } 04122 do { 04123 len = read(ifd, buf, sizeof(buf)); 04124 if (len < 0) { 04125 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04126 close(ifd); 04127 close(ofd); 04128 unlink(outfile); 04129 } else if (len) { 04130 res = write(ofd, buf, len); 04131 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04132 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04133 close(ifd); 04134 close(ofd); 04135 unlink(outfile); 04136 } 04137 } 04138 } while (len); 04139 close(ifd); 04140 close(ofd); 04141 return 0; 04142 #ifdef HARDLINK_WHEN_POSSIBLE 04143 } else { 04144 /* Hard link succeeded */ 04145 return 0; 04146 } 04147 #endif 04148 }
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 5337 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().
05338 { 05339 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05340 const char *frombox = mbox(vmu, imbox); 05341 const char *userfolder; 05342 int recipmsgnum; 05343 int res = 0; 05344 05345 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05346 05347 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05348 userfolder = "Urgent"; 05349 } else { 05350 userfolder = "INBOX"; 05351 } 05352 05353 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05354 05355 if (!dir) 05356 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05357 else 05358 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05359 05360 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05361 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05362 05363 if (vm_lock_path(todir)) 05364 return ERROR_LOCK_PATH; 05365 05366 recipmsgnum = last_message_index(recip, todir) + 1; 05367 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05368 make_file(topath, sizeof(topath), todir, recipmsgnum); 05369 #ifndef ODBC_STORAGE 05370 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05371 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05372 } else { 05373 #endif 05374 /* If we are prepending a message for ODBC, then the message already 05375 * exists in the database, but we want to force copying from the 05376 * filesystem (since only the FS contains the prepend). */ 05377 copy_plain_file(frompath, topath); 05378 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05379 vm_delete(topath); 05380 #ifndef ODBC_STORAGE 05381 } 05382 #endif 05383 } else { 05384 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05385 res = -1; 05386 } 05387 ast_unlock_path(todir); 05388 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05389 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05390 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05391 flag); 05392 05393 return res; 05394 }
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 4159 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().
04160 { 04161 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04162 struct ast_variable *tmp,*var = NULL; 04163 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04164 ast_filecopy(frompath, topath, NULL); 04165 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04166 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04167 if (ast_check_realtime("voicemail_data")) { 04168 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04169 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04170 for (tmp = var; tmp; tmp = tmp->next) { 04171 if (!strcasecmp(tmp->name, "origmailbox")) { 04172 origmailbox = tmp->value; 04173 } else if (!strcasecmp(tmp->name, "context")) { 04174 context = tmp->value; 04175 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04176 macrocontext = tmp->value; 04177 } else if (!strcasecmp(tmp->name, "exten")) { 04178 exten = tmp->value; 04179 } else if (!strcasecmp(tmp->name, "priority")) { 04180 priority = tmp->value; 04181 } else if (!strcasecmp(tmp->name, "callerchan")) { 04182 callerchan = tmp->value; 04183 } else if (!strcasecmp(tmp->name, "callerid")) { 04184 callerid = tmp->value; 04185 } else if (!strcasecmp(tmp->name, "origdate")) { 04186 origdate = tmp->value; 04187 } else if (!strcasecmp(tmp->name, "origtime")) { 04188 origtime = tmp->value; 04189 } else if (!strcasecmp(tmp->name, "category")) { 04190 category = tmp->value; 04191 } else if (!strcasecmp(tmp->name, "duration")) { 04192 duration = tmp->value; 04193 } 04194 } 04195 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); 04196 } 04197 copy(frompath2, topath2); 04198 ast_variables_destroy(var); 04199 }
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 3996 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().
03997 { 03998 03999 int vmcount = 0; 04000 DIR *vmdir = NULL; 04001 struct dirent *vment = NULL; 04002 04003 if (vm_lock_path(dir)) 04004 return ERROR_LOCK_PATH; 04005 04006 if ((vmdir = opendir(dir))) { 04007 while ((vment = readdir(vmdir))) { 04008 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 04009 vmcount++; 04010 } 04011 } 04012 closedir(vmdir); 04013 } 04014 ast_unlock_path(dir); 04015 04016 return vmcount; 04017 }
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 1679 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().
01680 { 01681 mode_t mode = VOICEMAIL_DIR_MODE; 01682 int res; 01683 01684 make_dir(dest, len, context, ext, folder); 01685 if ((res = ast_mkdir(dest, mode))) { 01686 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01687 return -1; 01688 } 01689 return 0; 01690 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13192 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().
13193 { 13194 int cmd = 0; 13195 char destination[80] = ""; 13196 int retries = 0; 13197 13198 if (!num) { 13199 ast_verb(3, "Destination number will be entered manually\n"); 13200 while (retries < 3 && cmd != 't') { 13201 destination[1] = '\0'; 13202 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13203 if (!cmd) 13204 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13205 if (!cmd) 13206 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13207 if (!cmd) { 13208 cmd = ast_waitfordigit(chan, 6000); 13209 if (cmd) 13210 destination[0] = cmd; 13211 } 13212 if (!cmd) { 13213 retries++; 13214 } else { 13215 13216 if (cmd < 0) 13217 return 0; 13218 if (cmd == '*') { 13219 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13220 return 0; 13221 } 13222 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13223 retries++; 13224 else 13225 cmd = 't'; 13226 } 13227 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13228 } 13229 if (retries >= 3) { 13230 return 0; 13231 } 13232 13233 } else { 13234 if (option_verbose > 2) 13235 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13236 ast_copy_string(destination, num, sizeof(destination)); 13237 } 13238 13239 if (!ast_strlen_zero(destination)) { 13240 if (destination[strlen(destination) -1 ] == '*') 13241 return 0; 13242 if (option_verbose > 2) 13243 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13244 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13245 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13246 chan->priority = 0; 13247 return 9; 13248 } 13249 return 0; 13250 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static, read] |
Definition at line 10746 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().
10747 { 10748 struct ast_vm_user *vmu; 10749 10750 if (!ast_strlen_zero(box) && box[0] == '*') { 10751 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10752 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10753 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10754 "\n\tand will be ignored.\n", box, context); 10755 return NULL; 10756 } 10757 10758 AST_LIST_TRAVERSE(&users, vmu, list) { 10759 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10760 if (strcasecmp(vmu->context, context)) { 10761 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10762 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10763 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10764 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10765 } 10766 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10767 return NULL; 10768 } 10769 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10770 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10771 return NULL; 10772 } 10773 } 10774 10775 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10776 return NULL; 10777 10778 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10779 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10780 10781 AST_LIST_INSERT_TAIL(&users, vmu, list); 10782 10783 return vmu; 10784 }
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 1418 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().
01419 { 01420 /* This function could be made to generate one from a database, too */ 01421 struct ast_vm_user *vmu = NULL, *cur; 01422 AST_LIST_LOCK(&users); 01423 01424 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01425 context = "default"; 01426 01427 AST_LIST_TRAVERSE(&users, cur, list) { 01428 #ifdef IMAP_STORAGE 01429 if (cur->imapversion != imapversion) { 01430 continue; 01431 } 01432 #endif 01433 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01434 break; 01435 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01436 break; 01437 } 01438 if (cur) { 01439 /* Make a copy, so that on a reload, we have no race */ 01440 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01441 *vmu = *cur; 01442 if (!ivm) { 01443 vmu->emailbody = ast_strdup(cur->emailbody); 01444 vmu->emailsubject = ast_strdup(cur->emailsubject); 01445 } 01446 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01447 AST_LIST_NEXT(vmu, list) = NULL; 01448 } 01449 } else 01450 vmu = find_user_realtime(ivm, context, mailbox); 01451 AST_LIST_UNLOCK(&users); 01452 return vmu; 01453 }
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 1377 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().
01378 { 01379 struct ast_variable *var; 01380 struct ast_vm_user *retval; 01381 01382 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01383 if (ivm) { 01384 memset(retval, 0, sizeof(*retval)); 01385 } 01386 populate_defaults(retval); 01387 if (!ivm) { 01388 ast_set_flag(retval, VM_ALLOCED); 01389 } 01390 if (mailbox) { 01391 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01392 } 01393 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01394 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01395 } else { 01396 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01397 } 01398 if (var) { 01399 apply_options_full(retval, var); 01400 ast_variables_destroy(var); 01401 } else { 01402 if (!ivm) 01403 free_user(retval); 01404 retval = NULL; 01405 } 01406 } 01407 return retval; 01408 }
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 7187 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().
07188 { 07189 #ifdef IMAP_STORAGE 07190 int todircount = 0; 07191 struct vm_state *dstvms; 07192 #endif 07193 char username[70]=""; 07194 char fn[PATH_MAX]; /* for playback of name greeting */ 07195 char ecodes[16] = "#"; 07196 int res = 0, cmd = 0; 07197 struct ast_vm_user *receiver = NULL, *vmtmp; 07198 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07199 char *stringp; 07200 const char *s; 07201 int saved_messages = 0; 07202 int valid_extensions = 0; 07203 char *dir; 07204 int curmsg; 07205 char urgent_str[7] = ""; 07206 int prompt_played = 0; 07207 #ifndef IMAP_STORAGE 07208 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07209 #endif 07210 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07211 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07212 } 07213 07214 if (vms == NULL) return -1; 07215 dir = vms->curdir; 07216 curmsg = vms->curmsg; 07217 07218 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07219 while (!res && !valid_extensions) { 07220 int use_directory = 0; 07221 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07222 int done = 0; 07223 int retries = 0; 07224 cmd = 0; 07225 while ((cmd >= 0) && !done ){ 07226 if (cmd) 07227 retries = 0; 07228 switch (cmd) { 07229 case '1': 07230 use_directory = 0; 07231 done = 1; 07232 break; 07233 case '2': 07234 use_directory = 1; 07235 done = 1; 07236 break; 07237 case '*': 07238 cmd = 't'; 07239 done = 1; 07240 break; 07241 default: 07242 /* Press 1 to enter an extension press 2 to use the directory */ 07243 cmd = ast_play_and_wait(chan, "vm-forward"); 07244 if (!cmd) { 07245 cmd = ast_waitfordigit(chan, 3000); 07246 } 07247 if (!cmd) { 07248 retries++; 07249 } 07250 if (retries > 3) { 07251 cmd = 't'; 07252 done = 1; 07253 } 07254 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07255 } 07256 } 07257 if (cmd < 0 || cmd == 't') 07258 break; 07259 } 07260 07261 if (use_directory) { 07262 /* use app_directory */ 07263 07264 char old_context[sizeof(chan->context)]; 07265 char old_exten[sizeof(chan->exten)]; 07266 int old_priority; 07267 struct ast_app* directory_app; 07268 07269 directory_app = pbx_findapp("Directory"); 07270 if (directory_app) { 07271 char vmcontext[256]; 07272 /* make backup copies */ 07273 memcpy(old_context, chan->context, sizeof(chan->context)); 07274 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07275 old_priority = chan->priority; 07276 07277 /* call the the Directory, changes the channel */ 07278 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07279 res = pbx_exec(chan, directory_app, vmcontext); 07280 07281 ast_copy_string(username, chan->exten, sizeof(username)); 07282 07283 /* restore the old context, exten, and priority */ 07284 memcpy(chan->context, old_context, sizeof(chan->context)); 07285 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07286 chan->priority = old_priority; 07287 } else { 07288 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07289 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07290 } 07291 } else { 07292 /* Ask for an extension */ 07293 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07294 prompt_played++; 07295 if (res || prompt_played > 4) 07296 break; 07297 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07298 break; 07299 } 07300 07301 /* start all over if no username */ 07302 if (ast_strlen_zero(username)) 07303 continue; 07304 stringp = username; 07305 s = strsep(&stringp, "*"); 07306 /* start optimistic */ 07307 valid_extensions = 1; 07308 while (s) { 07309 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07310 int oldmsgs; 07311 int newmsgs; 07312 int capacity; 07313 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07314 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07315 /* Shouldn't happen, but allow trying another extension if it does */ 07316 res = ast_play_and_wait(chan, "pbx-invalid"); 07317 valid_extensions = 0; 07318 break; 07319 } 07320 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07321 if ((newmsgs + oldmsgs) >= capacity) { 07322 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07323 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07324 valid_extensions = 0; 07325 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07326 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07327 free_user(vmtmp); 07328 } 07329 inprocess_count(receiver->mailbox, receiver->context, -1); 07330 break; 07331 } 07332 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07333 } else { 07334 /* XXX Optimization for the future. When we encounter a single bad extension, 07335 * bailing out on all of the extensions may not be the way to go. We should 07336 * probably just bail on that single extension, then allow the user to enter 07337 * several more. XXX 07338 */ 07339 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07340 free_user(receiver); 07341 } 07342 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07343 /* "I am sorry, that's not a valid extension. Please try again." */ 07344 res = ast_play_and_wait(chan, "pbx-invalid"); 07345 valid_extensions = 0; 07346 break; 07347 } 07348 07349 /* play name if available, else play extension number */ 07350 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07351 RETRIEVE(fn, -1, s, receiver->context); 07352 if (ast_fileexists(fn, NULL, NULL) > 0) { 07353 res = ast_stream_and_wait(chan, fn, ecodes); 07354 if (res) { 07355 DISPOSE(fn, -1); 07356 return res; 07357 } 07358 } else { 07359 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07360 } 07361 DISPOSE(fn, -1); 07362 07363 s = strsep(&stringp, "*"); 07364 } 07365 /* break from the loop of reading the extensions */ 07366 if (valid_extensions) 07367 break; 07368 } 07369 /* check if we're clear to proceed */ 07370 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07371 return res; 07372 if (is_new_message == 1) { 07373 struct leave_vm_options leave_options; 07374 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07375 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07376 07377 /* Send VoiceMail */ 07378 memset(&leave_options, 0, sizeof(leave_options)); 07379 leave_options.record_gain = record_gain; 07380 cmd = leave_voicemail(chan, mailbox, &leave_options); 07381 } else { 07382 /* Forward VoiceMail */ 07383 long duration = 0; 07384 struct vm_state vmstmp; 07385 int copy_msg_result = 0; 07386 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07387 07388 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07389 07390 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07391 if (!cmd) { 07392 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07393 #ifdef IMAP_STORAGE 07394 int attach_user_voicemail; 07395 char *myserveremail = serveremail; 07396 07397 /* get destination mailbox */ 07398 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07399 if (!dstvms) { 07400 dstvms = create_vm_state_from_user(vmtmp); 07401 } 07402 if (dstvms) { 07403 init_mailstream(dstvms, 0); 07404 if (!dstvms->mailstream) { 07405 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07406 } else { 07407 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07408 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07409 } 07410 } else { 07411 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07412 } 07413 if (!ast_strlen_zero(vmtmp->serveremail)) 07414 myserveremail = vmtmp->serveremail; 07415 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07416 /* NULL category for IMAP storage */ 07417 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07418 dstvms->curbox, 07419 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07420 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07421 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07422 NULL, urgent_str); 07423 #else 07424 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07425 #endif 07426 saved_messages++; 07427 AST_LIST_REMOVE_CURRENT(list); 07428 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07429 free_user(vmtmp); 07430 if (res) 07431 break; 07432 } 07433 AST_LIST_TRAVERSE_SAFE_END; 07434 if (saved_messages > 0 && !copy_msg_result) { 07435 /* give confirmation that the message was saved */ 07436 /* commented out since we can't forward batches yet 07437 if (saved_messages == 1) 07438 res = ast_play_and_wait(chan, "vm-message"); 07439 else 07440 res = ast_play_and_wait(chan, "vm-messages"); 07441 if (!res) 07442 res = ast_play_and_wait(chan, "vm-saved"); */ 07443 #ifdef IMAP_STORAGE 07444 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07445 if (ast_strlen_zero(vmstmp.introfn)) 07446 #endif 07447 res = ast_play_and_wait(chan, "vm-msgsaved"); 07448 } 07449 #ifndef IMAP_STORAGE 07450 else { 07451 /* with IMAP, mailbox full warning played by imap_check_limits */ 07452 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07453 } 07454 /* Restore original message without prepended message if backup exists */ 07455 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07456 strcpy(textfile, msgfile); 07457 strcpy(backup, msgfile); 07458 strcpy(backup_textfile, msgfile); 07459 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07460 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07461 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07462 if (ast_fileexists(backup, NULL, NULL) > 0) { 07463 ast_filerename(backup, msgfile, NULL); 07464 rename(backup_textfile, textfile); 07465 } 07466 #endif 07467 } 07468 DISPOSE(dir, curmsg); 07469 #ifndef IMAP_STORAGE 07470 if (cmd) { /* assuming hangup, cleanup backup file */ 07471 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07472 strcpy(textfile, msgfile); 07473 strcpy(backup_textfile, msgfile); 07474 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07475 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07476 rename(backup_textfile, textfile); 07477 } 07478 #endif 07479 } 07480 07481 /* If anything failed above, we still have this list to free */ 07482 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07483 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07484 free_user(vmtmp); 07485 } 07486 return res ? res : cmd; 07487 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1734 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().
01735 { 01736 if (ast_test_flag(vmu, VM_ALLOCED)) { 01737 01738 ast_free(vmu->emailbody); 01739 vmu->emailbody = NULL; 01740 01741 ast_free(vmu->emailsubject); 01742 vmu->emailsubject = NULL; 01743 01744 ast_free(vmu); 01745 } 01746 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11775 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().
11776 { 11777 struct ast_vm_user *current; 11778 AST_LIST_LOCK(&users); 11779 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11780 ast_set_flag(current, VM_ALLOCED); 11781 free_user(current); 11782 } 11783 AST_LIST_UNLOCK(&users); 11784 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11787 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().
11788 { 11789 struct vm_zone *zcur; 11790 AST_LIST_LOCK(&zones); 11791 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11792 free_zone(zcur); 11793 AST_LIST_UNLOCK(&zones); 11794 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5105 of file app_voicemail_odbcstorage.c.
References ast_free.
Referenced by free_vm_zones().
05106 { 05107 ast_free(z); 05108 }
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 5061 of file app_voicemail_odbcstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
05062 { 05063 struct ast_tm tm; 05064 struct timeval t = ast_tvnow(); 05065 05066 ast_localtime(&t, &tm, "UTC"); 05067 05068 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05069 }
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 6796 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().
06797 { 06798 int x; 06799 int d; 06800 char fn[PATH_MAX]; 06801 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06802 if (d) 06803 return d; 06804 for (x = start; x < 5; x++) { /* For all folders */ 06805 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06806 return d; 06807 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06808 if (d) 06809 return d; 06810 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06811 06812 /* The inbox folder can have its name changed under certain conditions 06813 * so this checks if the sound file exists for the inbox folder name and 06814 * if it doesn't, plays the default name instead. */ 06815 if (x == 0) { 06816 if (ast_fileexists(fn, NULL, NULL)) { 06817 d = vm_play_folder_name(chan, fn); 06818 } else { 06819 ast_verb(1, "failed to find %s\n", fn); 06820 d = vm_play_folder_name(chan, "vm-INBOX"); 06821 } 06822 } else { 06823 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06824 d = vm_play_folder_name(chan, fn); 06825 } 06826 06827 if (d) 06828 return d; 06829 d = ast_waitfordigit(chan, 500); 06830 if (d) 06831 return d; 06832 } 06833 06834 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06835 if (d) 06836 return d; 06837 d = ast_waitfordigit(chan, 4000); 06838 return d; 06839 }
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 6853 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
06854 { 06855 int res = 0; 06856 int loops = 0; 06857 06858 res = ast_play_and_wait(chan, fn); /* Folder name */ 06859 while (((res < '0') || (res > '9')) && 06860 (res != '#') && (res >= 0) && 06861 loops < 4) { 06862 res = get_folder(chan, 0); 06863 loops++; 06864 } 06865 if (loops == 4) { /* give up */ 06866 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06867 return '#'; 06868 } 06869 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06870 return res; 06871 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1721 of file app_voicemail_odbcstorage.c.
References ARRAY_LEN.
Referenced by vm_execmain().
01722 { 01723 size_t i; 01724 01725 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01726 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01727 return i; 01728 } 01729 } 01730 01731 return -1; 01732 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11545 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().
11546 { 11547 unsigned int len; 11548 struct mwi_sub *mwi_sub; 11549 struct mwi_sub_task *p = datap; 11550 11551 len = sizeof(*mwi_sub); 11552 if (!ast_strlen_zero(p->mailbox)) 11553 len += strlen(p->mailbox); 11554 11555 if (!ast_strlen_zero(p->context)) 11556 len += strlen(p->context) + 1; /* Allow for seperator */ 11557 11558 if (!(mwi_sub = ast_calloc(1, len))) 11559 return -1; 11560 11561 mwi_sub->uniqueid = p->uniqueid; 11562 if (!ast_strlen_zero(p->mailbox)) 11563 strcpy(mwi_sub->mailbox, p->mailbox); 11564 11565 if (!ast_strlen_zero(p->context)) { 11566 strcat(mwi_sub->mailbox, "@"); 11567 strcat(mwi_sub->mailbox, p->context); 11568 } 11569 11570 AST_RWLIST_WRLOCK(&mwi_subs); 11571 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11572 AST_RWLIST_UNLOCK(&mwi_subs); 11573 ast_free((void *) p->mailbox); 11574 ast_free((void *) p->context); 11575 ast_free(p); 11576 poll_subscribed_mailbox(mwi_sub); 11577 return 0; 11578 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11523 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().
11524 { 11525 struct mwi_sub *mwi_sub; 11526 uint32_t *uniqueid = datap; 11527 11528 AST_RWLIST_WRLOCK(&mwi_subs); 11529 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11530 if (mwi_sub->uniqueid == *uniqueid) { 11531 AST_LIST_REMOVE_CURRENT(entry); 11532 break; 11533 } 11534 } 11535 AST_RWLIST_TRAVERSE_SAFE_END 11536 AST_RWLIST_UNLOCK(&mwi_subs); 11537 11538 if (mwi_sub) 11539 mwi_sub_destroy(mwi_sub); 11540 11541 ast_free(uniqueid); 11542 return 0; 11543 }
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 11300 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.
11301 { 11302 switch (cmd) { 11303 case CLI_INIT: 11304 e->command = "voicemail reload"; 11305 e->usage = 11306 "Usage: voicemail reload\n" 11307 " Reload voicemail configuration\n"; 11308 return NULL; 11309 case CLI_GENERATE: 11310 return NULL; 11311 } 11312 11313 if (a->argc != 2) 11314 return CLI_SHOWUSAGE; 11315 11316 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11317 load_config(1); 11318 11319 return CLI_SUCCESS; 11320 }
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 11188 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.
11189 { 11190 struct ast_vm_user *vmu; 11191 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11192 const char *context = NULL; 11193 int users_counter = 0; 11194 11195 switch (cmd) { 11196 case CLI_INIT: 11197 e->command = "voicemail show users"; 11198 e->usage = 11199 "Usage: voicemail show users [for <context>]\n" 11200 " Lists all mailboxes currently set up\n"; 11201 return NULL; 11202 case CLI_GENERATE: 11203 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11204 } 11205 11206 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11207 return CLI_SHOWUSAGE; 11208 if (a->argc == 5) { 11209 if (strcmp(a->argv[3],"for")) 11210 return CLI_SHOWUSAGE; 11211 context = a->argv[4]; 11212 } 11213 11214 if (ast_check_realtime("voicemail")) { 11215 if (!context) { 11216 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11217 return CLI_SHOWUSAGE; 11218 } 11219 return show_users_realtime(a->fd, context); 11220 } 11221 11222 AST_LIST_LOCK(&users); 11223 if (AST_LIST_EMPTY(&users)) { 11224 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11225 AST_LIST_UNLOCK(&users); 11226 return CLI_FAILURE; 11227 } 11228 if (!context) { 11229 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11230 } else { 11231 int count = 0; 11232 AST_LIST_TRAVERSE(&users, vmu, list) { 11233 if (!strcmp(context, vmu->context)) { 11234 count++; 11235 break; 11236 } 11237 } 11238 if (count) { 11239 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11240 } else { 11241 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11242 AST_LIST_UNLOCK(&users); 11243 return CLI_FAILURE; 11244 } 11245 } 11246 AST_LIST_TRAVERSE(&users, vmu, list) { 11247 int newmsgs = 0, oldmsgs = 0; 11248 char count[12], tmp[256] = ""; 11249 11250 if (!context || !strcmp(context, vmu->context)) { 11251 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11252 inboxcount(tmp, &newmsgs, &oldmsgs); 11253 snprintf(count, sizeof(count), "%d", newmsgs); 11254 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11255 users_counter++; 11256 } 11257 } 11258 AST_LIST_UNLOCK(&users); 11259 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11260 return CLI_SUCCESS; 11261 }
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 11264 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.
11265 { 11266 struct vm_zone *zone; 11267 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11268 char *res = CLI_SUCCESS; 11269 11270 switch (cmd) { 11271 case CLI_INIT: 11272 e->command = "voicemail show zones"; 11273 e->usage = 11274 "Usage: voicemail show zones\n" 11275 " Lists zone message formats\n"; 11276 return NULL; 11277 case CLI_GENERATE: 11278 return NULL; 11279 } 11280 11281 if (a->argc != 3) 11282 return CLI_SHOWUSAGE; 11283 11284 AST_LIST_LOCK(&zones); 11285 if (!AST_LIST_EMPTY(&zones)) { 11286 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11287 AST_LIST_TRAVERSE(&zones, zone, list) { 11288 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11289 } 11290 } else { 11291 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11292 res = CLI_FAILURE; 11293 } 11294 AST_LIST_UNLOCK(&zones); 11295 11296 return res; 11297 }
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 5449 of file app_voicemail_odbcstorage.c.
References __has_voicemail(), ast_copy_string(), and ast_strlen_zero().
Referenced by load_module(), and vm_execmain().
05450 { 05451 char tmp[256], *tmp2 = tmp, *box, *context; 05452 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05453 if (ast_strlen_zero(folder)) { 05454 folder = "INBOX"; 05455 } 05456 while ((box = strsep(&tmp2, ",&"))) { 05457 if ((context = strchr(box, '@'))) 05458 *context++ = '\0'; 05459 else 05460 context = "default"; 05461 if (__has_voicemail(context, box, folder, 1)) 05462 return 1; 05463 /* If we are checking INBOX, we should check Urgent as well */ 05464 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05465 return 1; 05466 } 05467 } 05468 return 0; 05469 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5531 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().
05532 { 05533 int urgentmsgs = 0; 05534 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05535 if (newmsgs) { 05536 *newmsgs += urgentmsgs; 05537 } 05538 return res; 05539 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5472 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().
05473 { 05474 char tmp[256]; 05475 char *context; 05476 05477 /* If no mailbox, return immediately */ 05478 if (ast_strlen_zero(mailbox)) 05479 return 0; 05480 05481 if (newmsgs) 05482 *newmsgs = 0; 05483 if (oldmsgs) 05484 *oldmsgs = 0; 05485 if (urgentmsgs) 05486 *urgentmsgs = 0; 05487 05488 if (strchr(mailbox, ',')) { 05489 int tmpnew, tmpold, tmpurgent; 05490 char *mb, *cur; 05491 05492 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05493 mb = tmp; 05494 while ((cur = strsep(&mb, ", "))) { 05495 if (!ast_strlen_zero(cur)) { 05496 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05497 return -1; 05498 else { 05499 if (newmsgs) 05500 *newmsgs += tmpnew; 05501 if (oldmsgs) 05502 *oldmsgs += tmpold; 05503 if (urgentmsgs) 05504 *urgentmsgs += tmpurgent; 05505 } 05506 } 05507 } 05508 return 0; 05509 } 05510 05511 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05512 05513 if ((context = strchr(tmp, '@'))) 05514 *context++ = '\0'; 05515 else 05516 context = "default"; 05517 05518 if (newmsgs) 05519 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05520 if (oldmsgs) 05521 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05522 if (urgentmsgs) 05523 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05524 05525 return 0; 05526 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4231 of file app_voicemail_odbcstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by inchar().
04232 { 04233 int l; 04234 04235 if (bio->ateof) 04236 return 0; 04237 04238 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04239 if (ferror(fi)) 04240 return -1; 04241 04242 bio->ateof = 1; 04243 return 0; 04244 } 04245 04246 bio->iolen = l; 04247 bio->iocp = 0; 04248 04249 return 1; 04250 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4255 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 916 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 925 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().
00926 { 00927 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00928 arg->context = arg->mailbox + strlen(mailbox) + 1; 00929 strcpy(arg->mailbox, mailbox); /* SAFE */ 00930 strcpy(arg->context, context); /* SAFE */ 00931 ao2_lock(inprocess_container); 00932 if ((i = ao2_find(inprocess_container, arg, 0))) { 00933 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00934 ao2_unlock(inprocess_container); 00935 ao2_ref(i, -1); 00936 return ret; 00937 } 00938 if (delta < 0) { 00939 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00940 } 00941 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00942 ao2_unlock(inprocess_container); 00943 return 0; 00944 } 00945 i->context = i->mailbox + strlen(mailbox) + 1; 00946 strcpy(i->mailbox, mailbox); /* SAFE */ 00947 strcpy(i->context, context); /* SAFE */ 00948 i->count = delta; 00949 ao2_link(inprocess_container, i); 00950 ao2_unlock(inprocess_container); 00951 ao2_ref(i, -1); 00952 return 0; 00953 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 910 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 5071 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().
05072 { 05073 int res; 05074 char fn[PATH_MAX]; 05075 char dest[PATH_MAX]; 05076 05077 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05078 05079 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05080 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05081 return -1; 05082 } 05083 05084 RETRIEVE(fn, -1, ext, context); 05085 if (ast_fileexists(fn, NULL, NULL) > 0) { 05086 res = ast_stream_and_wait(chan, fn, ecodes); 05087 if (res) { 05088 DISPOSE(fn, -1); 05089 return res; 05090 } 05091 } else { 05092 /* Dispose just in case */ 05093 DISPOSE(fn, -1); 05094 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05095 if (res) 05096 return res; 05097 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05098 if (res) 05099 return res; 05100 } 05101 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05102 return res; 05103 }
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 1352 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01353 { 01354 int i; 01355 char *local_key = ast_strdupa(key); 01356 01357 for (i = 0; i < strlen(key); ++i) { 01358 if (!strchr(VALID_DTMF, *local_key)) { 01359 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01360 return 0; 01361 } 01362 local_key++; 01363 } 01364 return 1; 01365 }
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 4050 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().
04051 { 04052 int x; 04053 unsigned char map[MAXMSGLIMIT] = ""; 04054 DIR *msgdir; 04055 struct dirent *msgdirent; 04056 int msgdirint; 04057 char extension[4]; 04058 int stopcount = 0; 04059 04060 /* Reading the entire directory into a file map scales better than 04061 * doing a stat repeatedly on a predicted sequence. I suspect this 04062 * is partially due to stat(2) internally doing a readdir(2) itself to 04063 * find each file. */ 04064 if (!(msgdir = opendir(dir))) { 04065 return -1; 04066 } 04067 04068 while ((msgdirent = readdir(msgdir))) { 04069 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04070 map[msgdirint] = 1; 04071 stopcount++; 04072 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04073 } 04074 } 04075 closedir(msgdir); 04076 04077 for (x = 0; x < vmu->maxmsg; x++) { 04078 if (map[x] == 1) { 04079 stopcount--; 04080 } else if (map[x] == 0 && !stopcount) { 04081 break; 04082 } 04083 } 04084 04085 return x - 1; 04086 }
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 5607 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().
05608 { 05609 #ifdef IMAP_STORAGE 05610 int newmsgs, oldmsgs; 05611 #else 05612 char urgdir[PATH_MAX]; 05613 #endif 05614 char txtfile[PATH_MAX]; 05615 char tmptxtfile[PATH_MAX]; 05616 struct vm_state *vms = NULL; 05617 char callerid[256]; 05618 FILE *txt; 05619 char date[256]; 05620 int txtdes; 05621 int res = 0; 05622 int msgnum; 05623 int duration = 0; 05624 int sound_duration = 0; 05625 int ausemacro = 0; 05626 int ousemacro = 0; 05627 int ouseexten = 0; 05628 char tmpdur[16]; 05629 char priority[16]; 05630 char origtime[16]; 05631 char dir[PATH_MAX]; 05632 char tmpdir[PATH_MAX]; 05633 char fn[PATH_MAX]; 05634 char prefile[PATH_MAX] = ""; 05635 char tempfile[PATH_MAX] = ""; 05636 char ext_context[256] = ""; 05637 char fmt[80]; 05638 char *context; 05639 char ecodes[17] = "#"; 05640 struct ast_str *tmp = ast_str_create(16); 05641 char *tmpptr; 05642 struct ast_vm_user *vmu; 05643 struct ast_vm_user svm; 05644 const char *category = NULL; 05645 const char *code; 05646 const char *alldtmf = "0123456789ABCD*#"; 05647 char flag[80]; 05648 05649 if (!tmp) { 05650 return -1; 05651 } 05652 05653 ast_str_set(&tmp, 0, "%s", ext); 05654 ext = ast_str_buffer(tmp); 05655 if ((context = strchr(ext, '@'))) { 05656 *context++ = '\0'; 05657 tmpptr = strchr(context, '&'); 05658 } else { 05659 tmpptr = strchr(ext, '&'); 05660 } 05661 05662 if (tmpptr) 05663 *tmpptr++ = '\0'; 05664 05665 ast_channel_lock(chan); 05666 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05667 category = ast_strdupa(category); 05668 } 05669 ast_channel_unlock(chan); 05670 05671 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05672 ast_copy_string(flag, "Urgent", sizeof(flag)); 05673 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05674 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05675 } else { 05676 flag[0] = '\0'; 05677 } 05678 05679 ast_debug(3, "Before find_user\n"); 05680 if (!(vmu = find_user(&svm, context, ext))) { 05681 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05682 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05683 ast_free(tmp); 05684 return res; 05685 } 05686 /* Setup pre-file if appropriate */ 05687 if (strcmp(vmu->context, "default")) 05688 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05689 else 05690 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05691 05692 /* Set the path to the prefile. Will be one of 05693 VM_SPOOL_DIRcontext/ext/busy 05694 VM_SPOOL_DIRcontext/ext/unavail 05695 Depending on the flag set in options. 05696 */ 05697 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05698 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05699 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05700 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05701 } 05702 /* Set the path to the tmpfile as 05703 VM_SPOOL_DIR/context/ext/temp 05704 and attempt to create the folder structure. 05705 */ 05706 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05707 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05708 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05709 ast_free(tmp); 05710 return -1; 05711 } 05712 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05713 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05714 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05715 05716 DISPOSE(tempfile, -1); 05717 /* It's easier just to try to make it than to check for its existence */ 05718 #ifndef IMAP_STORAGE 05719 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05720 #else 05721 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05722 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05723 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05724 } 05725 #endif 05726 05727 /* Check current or macro-calling context for special extensions */ 05728 if (ast_test_flag(vmu, VM_OPERATOR)) { 05729 if (!ast_strlen_zero(vmu->exit)) { 05730 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05731 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05732 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05733 ouseexten = 1; 05734 } 05735 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05736 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05737 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05738 ouseexten = 1; 05739 } else if (!ast_strlen_zero(chan->macrocontext) 05740 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05741 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05742 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05743 ousemacro = 1; 05744 } 05745 } 05746 05747 if (!ast_strlen_zero(vmu->exit)) { 05748 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05749 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05750 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05751 } 05752 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05753 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05754 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05755 } else if (!ast_strlen_zero(chan->macrocontext) 05756 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05757 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05758 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05759 ausemacro = 1; 05760 } 05761 05762 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05763 for (code = alldtmf; *code; code++) { 05764 char e[2] = ""; 05765 e[0] = *code; 05766 if (strchr(ecodes, e[0]) == NULL 05767 && ast_canmatch_extension(chan, 05768 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05769 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05770 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05771 } 05772 } 05773 } 05774 05775 /* Play the beginning intro if desired */ 05776 if (!ast_strlen_zero(prefile)) { 05777 #ifdef ODBC_STORAGE 05778 int success = 05779 #endif 05780 RETRIEVE(prefile, -1, ext, context); 05781 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05782 if (ast_streamfile(chan, prefile, chan->language) > -1) 05783 res = ast_waitstream(chan, ecodes); 05784 #ifdef ODBC_STORAGE 05785 if (success == -1) { 05786 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05787 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05788 store_file(prefile, vmu->mailbox, vmu->context, -1); 05789 } 05790 #endif 05791 } else { 05792 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05793 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05794 } 05795 DISPOSE(prefile, -1); 05796 if (res < 0) { 05797 ast_debug(1, "Hang up during prefile playback\n"); 05798 free_user(vmu); 05799 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05800 ast_free(tmp); 05801 return -1; 05802 } 05803 } 05804 if (res == '#') { 05805 /* On a '#' we skip the instructions */ 05806 ast_set_flag(options, OPT_SILENT); 05807 res = 0; 05808 } 05809 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05810 if (vmu->maxmsg == 0) { 05811 if (option_debug > 2) 05812 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05813 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05814 goto leave_vm_out; 05815 } 05816 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05817 res = ast_stream_and_wait(chan, INTRO, ecodes); 05818 if (res == '#') { 05819 ast_set_flag(options, OPT_SILENT); 05820 res = 0; 05821 } 05822 } 05823 if (res > 0) 05824 ast_stopstream(chan); 05825 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05826 other than the operator -- an automated attendant or mailbox login for example */ 05827 if (res == '*') { 05828 chan->exten[0] = 'a'; 05829 chan->exten[1] = '\0'; 05830 if (!ast_strlen_zero(vmu->exit)) { 05831 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05832 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05833 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05834 } 05835 chan->priority = 0; 05836 free_user(vmu); 05837 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05838 ast_free(tmp); 05839 return 0; 05840 } 05841 05842 /* Check for a '0' here */ 05843 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05844 transfer: 05845 if (ouseexten || ousemacro) { 05846 chan->exten[0] = 'o'; 05847 chan->exten[1] = '\0'; 05848 if (!ast_strlen_zero(vmu->exit)) { 05849 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05850 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05851 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05852 } 05853 ast_play_and_wait(chan, "transfer"); 05854 chan->priority = 0; 05855 free_user(vmu); 05856 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05857 } 05858 ast_free(tmp); 05859 return OPERATOR_EXIT; 05860 } 05861 05862 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05863 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05864 if (!ast_strlen_zero(options->exitcontext)) { 05865 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05866 } 05867 free_user(vmu); 05868 ast_free(tmp); 05869 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05870 return res; 05871 } 05872 05873 if (res < 0) { 05874 free_user(vmu); 05875 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05876 ast_free(tmp); 05877 return -1; 05878 } 05879 /* The meat of recording the message... All the announcements and beeps have been played*/ 05880 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05881 if (!ast_strlen_zero(fmt)) { 05882 msgnum = 0; 05883 05884 #ifdef IMAP_STORAGE 05885 /* Is ext a mailbox? */ 05886 /* must open stream for this user to get info! */ 05887 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05888 if (res < 0) { 05889 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05890 ast_free(tmp); 05891 return -1; 05892 } 05893 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05894 /* It is possible under certain circumstances that inboxcount did not 05895 * create a vm_state when it was needed. This is a catchall which will 05896 * rarely be used. 05897 */ 05898 if (!(vms = create_vm_state_from_user(vmu))) { 05899 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05900 ast_free(tmp); 05901 return -1; 05902 } 05903 } 05904 vms->newmessages++; 05905 05906 /* here is a big difference! We add one to it later */ 05907 msgnum = newmsgs + oldmsgs; 05908 ast_debug(3, "Messagecount set to %d\n", msgnum); 05909 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05910 /* set variable for compatibility */ 05911 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05912 05913 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05914 goto leave_vm_out; 05915 } 05916 #else 05917 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05918 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05919 if (!res) 05920 res = ast_waitstream(chan, ""); 05921 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05922 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05923 inprocess_count(vmu->mailbox, vmu->context, -1); 05924 goto leave_vm_out; 05925 } 05926 05927 #endif 05928 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05929 txtdes = mkstemp(tmptxtfile); 05930 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05931 if (txtdes < 0) { 05932 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05933 if (!res) 05934 res = ast_waitstream(chan, ""); 05935 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05936 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05937 inprocess_count(vmu->mailbox, vmu->context, -1); 05938 goto leave_vm_out; 05939 } 05940 05941 /* Now play the beep once we have the message number for our next message. */ 05942 if (res >= 0) { 05943 /* Unless we're *really* silent, try to send the beep */ 05944 res = ast_stream_and_wait(chan, "beep", ""); 05945 } 05946 05947 /* Store information in real-time storage */ 05948 if (ast_check_realtime("voicemail_data")) { 05949 snprintf(priority, sizeof(priority), "%d", chan->priority); 05950 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05951 get_date(date, sizeof(date)); 05952 ast_callerid_merge(callerid, sizeof(callerid), 05953 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05954 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05955 "Unknown"); 05956 ast_store_realtime("voicemail_data", 05957 "origmailbox", ext, 05958 "context", chan->context, 05959 "macrocontext", chan->macrocontext, 05960 "exten", chan->exten, 05961 "priority", priority, 05962 "callerchan", chan->name, 05963 "callerid", callerid, 05964 "origdate", date, 05965 "origtime", origtime, 05966 "category", S_OR(category, ""), 05967 "filename", tmptxtfile, 05968 SENTINEL); 05969 } 05970 05971 /* Store information */ 05972 txt = fdopen(txtdes, "w+"); 05973 if (txt) { 05974 get_date(date, sizeof(date)); 05975 ast_callerid_merge(callerid, sizeof(callerid), 05976 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05977 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05978 "Unknown"); 05979 fprintf(txt, 05980 ";\n" 05981 "; Message Information file\n" 05982 ";\n" 05983 "[message]\n" 05984 "origmailbox=%s\n" 05985 "context=%s\n" 05986 "macrocontext=%s\n" 05987 "exten=%s\n" 05988 "rdnis=%s\n" 05989 "priority=%d\n" 05990 "callerchan=%s\n" 05991 "callerid=%s\n" 05992 "origdate=%s\n" 05993 "origtime=%ld\n" 05994 "category=%s\n", 05995 ext, 05996 chan->context, 05997 chan->macrocontext, 05998 chan->exten, 05999 S_COR(chan->redirecting.from.number.valid, 06000 chan->redirecting.from.number.str, "unknown"), 06001 chan->priority, 06002 chan->name, 06003 callerid, 06004 date, (long) time(NULL), 06005 category ? category : ""); 06006 } else { 06007 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 06008 inprocess_count(vmu->mailbox, vmu->context, -1); 06009 if (ast_check_realtime("voicemail_data")) { 06010 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06011 } 06012 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 06013 goto leave_vm_out; 06014 } 06015 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 06016 06017 if (txt) { 06018 fprintf(txt, "flag=%s\n", flag); 06019 if (sound_duration < vmu->minsecs) { 06020 fclose(txt); 06021 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06022 ast_filedelete(tmptxtfile, NULL); 06023 unlink(tmptxtfile); 06024 if (ast_check_realtime("voicemail_data")) { 06025 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06026 } 06027 inprocess_count(vmu->mailbox, vmu->context, -1); 06028 } else { 06029 fprintf(txt, "duration=%d\n", duration); 06030 fclose(txt); 06031 if (vm_lock_path(dir)) { 06032 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06033 /* Delete files */ 06034 ast_filedelete(tmptxtfile, NULL); 06035 unlink(tmptxtfile); 06036 inprocess_count(vmu->mailbox, vmu->context, -1); 06037 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06038 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06039 unlink(tmptxtfile); 06040 ast_unlock_path(dir); 06041 inprocess_count(vmu->mailbox, vmu->context, -1); 06042 if (ast_check_realtime("voicemail_data")) { 06043 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06044 } 06045 } else { 06046 #ifndef IMAP_STORAGE 06047 msgnum = last_message_index(vmu, dir) + 1; 06048 #endif 06049 make_file(fn, sizeof(fn), dir, msgnum); 06050 06051 /* assign a variable with the name of the voicemail file */ 06052 #ifndef IMAP_STORAGE 06053 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06054 #else 06055 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06056 #endif 06057 06058 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06059 ast_filerename(tmptxtfile, fn, NULL); 06060 rename(tmptxtfile, txtfile); 06061 inprocess_count(vmu->mailbox, vmu->context, -1); 06062 06063 /* Properly set permissions on voicemail text descriptor file. 06064 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06065 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06066 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06067 06068 ast_unlock_path(dir); 06069 if (ast_check_realtime("voicemail_data")) { 06070 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06071 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06072 } 06073 /* We must store the file first, before copying the message, because 06074 * ODBC storage does the entire copy with SQL. 06075 */ 06076 if (ast_fileexists(fn, NULL, NULL) > 0) { 06077 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06078 } 06079 06080 /* Are there to be more recipients of this message? */ 06081 while (tmpptr) { 06082 struct ast_vm_user recipu, *recip; 06083 char *exten, *cntx; 06084 06085 exten = strsep(&tmpptr, "&"); 06086 cntx = strchr(exten, '@'); 06087 if (cntx) { 06088 *cntx = '\0'; 06089 cntx++; 06090 } 06091 if ((recip = find_user(&recipu, cntx, exten))) { 06092 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06093 free_user(recip); 06094 } 06095 } 06096 #ifndef IMAP_STORAGE 06097 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06098 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06099 char sfn[PATH_MAX]; 06100 char dfn[PATH_MAX]; 06101 int x; 06102 /* It's easier just to try to make it than to check for its existence */ 06103 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06104 x = last_message_index(vmu, urgdir) + 1; 06105 make_file(sfn, sizeof(sfn), dir, msgnum); 06106 make_file(dfn, sizeof(dfn), urgdir, x); 06107 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06108 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06109 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06110 ast_copy_string(fn, dfn, sizeof(fn)); 06111 msgnum = x; 06112 } 06113 #endif 06114 /* Notification needs to happen after the copy, though. */ 06115 if (ast_fileexists(fn, NULL, NULL)) { 06116 #ifdef IMAP_STORAGE 06117 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06118 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06119 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06120 flag); 06121 #else 06122 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06123 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06124 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06125 flag); 06126 #endif 06127 } 06128 06129 /* Disposal needs to happen after the optional move and copy */ 06130 if (ast_fileexists(fn, NULL, NULL)) { 06131 DISPOSE(dir, msgnum); 06132 } 06133 } 06134 } 06135 } else { 06136 inprocess_count(vmu->mailbox, vmu->context, -1); 06137 } 06138 if (res == '0') { 06139 goto transfer; 06140 } else if (res > 0 && res != 't') 06141 res = 0; 06142 06143 if (sound_duration < vmu->minsecs) 06144 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06145 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06146 else 06147 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06148 } else 06149 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06150 leave_vm_out: 06151 free_user(vmu); 06152 06153 #ifdef IMAP_STORAGE 06154 /* expunge message - use UID Expunge if supported on IMAP server*/ 06155 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06156 if (expungeonhangup == 1) { 06157 ast_mutex_lock(&vms->lock); 06158 #ifdef HAVE_IMAP_TK2006 06159 if (LEVELUIDPLUS (vms->mailstream)) { 06160 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06161 } else 06162 #endif 06163 mail_expunge(vms->mailstream); 06164 ast_mutex_unlock(&vms->lock); 06165 } 06166 #endif 06167 06168 ast_free(tmp); 06169 return res; 06170 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11843 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().
11844 { 11845 struct ast_config *cfg, *ucfg; 11846 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11847 int res; 11848 11849 ast_unload_realtime("voicemail"); 11850 ast_unload_realtime("voicemail_data"); 11851 11852 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11853 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11854 return 0; 11855 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11856 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11857 ucfg = NULL; 11858 } 11859 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11860 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11861 ast_config_destroy(ucfg); 11862 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11863 return 0; 11864 } 11865 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11866 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11867 return 0; 11868 } else { 11869 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11870 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11871 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11872 ucfg = NULL; 11873 } 11874 } 11875 11876 res = actual_load_config(reload, cfg, ucfg); 11877 11878 ast_config_destroy(cfg); 11879 ast_config_destroy(ucfg); 11880 11881 return res; 11882 }
static int load_module | ( | void | ) | [static] |
Definition at line 13144 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().
13145 { 13146 int res; 13147 my_umask = umask(0); 13148 umask(my_umask); 13149 13150 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13151 return AST_MODULE_LOAD_DECLINE; 13152 } 13153 13154 /* compute the location of the voicemail spool directory */ 13155 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13156 13157 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13158 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13159 } 13160 13161 if ((res = load_config(0))) 13162 return res; 13163 13164 res = ast_register_application_xml(app, vm_exec); 13165 res |= ast_register_application_xml(app2, vm_execmain); 13166 res |= ast_register_application_xml(app3, vm_box_exists); 13167 res |= ast_register_application_xml(app4, vmauthenticate); 13168 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13169 res |= ast_custom_function_register(&mailbox_exists_acf); 13170 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13171 #ifdef TEST_FRAMEWORK 13172 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13173 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13174 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13175 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13176 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13177 #endif 13178 13179 if (res) 13180 return res; 13181 13182 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13183 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13184 13185 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13186 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13187 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13188 13189 return res; 13190 }
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 1633 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().
01634 { 01635 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01636 }
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 4548 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(), valid_config(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04549 { 04550 char date[256]; 04551 char host[MAXHOSTNAMELEN] = ""; 04552 char who[256]; 04553 char bound[256]; 04554 char dur[256]; 04555 struct ast_tm tm; 04556 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04557 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04558 char *greeting_attachment; 04559 char filename[256]; 04560 04561 if (!str1 || !str2) { 04562 ast_free(str1); 04563 ast_free(str2); 04564 return; 04565 } 04566 04567 if (cidnum) { 04568 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04569 } 04570 if (cidname) { 04571 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04572 } 04573 gethostname(host, sizeof(host) - 1); 04574 04575 if (strchr(srcemail, '@')) { 04576 ast_copy_string(who, srcemail, sizeof(who)); 04577 } else { 04578 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04579 } 04580 04581 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04582 if (greeting_attachment) { 04583 *greeting_attachment++ = '\0'; 04584 } 04585 04586 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04587 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04588 fprintf(p, "Date: %s" ENDL, date); 04589 04590 /* Set date format for voicemail mail */ 04591 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04592 04593 if (!ast_strlen_zero(fromstring)) { 04594 struct ast_channel *ast; 04595 if ((ast = ast_dummy_channel_alloc())) { 04596 char *ptr; 04597 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04598 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04599 04600 if (check_mime(ast_str_buffer(str1))) { 04601 int first_line = 1; 04602 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04603 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04604 *ptr = '\0'; 04605 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04606 first_line = 0; 04607 /* Substring is smaller, so this will never grow */ 04608 ast_str_set(&str2, 0, "%s", ptr + 1); 04609 } 04610 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04611 } else { 04612 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04613 } 04614 ast = ast_channel_unref(ast); 04615 } else { 04616 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04617 } 04618 } else { 04619 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04620 } 04621 04622 if (check_mime(vmu->fullname)) { 04623 int first_line = 1; 04624 char *ptr; 04625 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04626 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04627 *ptr = '\0'; 04628 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04629 first_line = 0; 04630 /* Substring is smaller, so this will never grow */ 04631 ast_str_set(&str2, 0, "%s", ptr + 1); 04632 } 04633 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04634 } else { 04635 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04636 } 04637 04638 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04639 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04640 struct ast_channel *ast; 04641 if ((ast = ast_dummy_channel_alloc())) { 04642 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04643 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04644 if (check_mime(ast_str_buffer(str1))) { 04645 int first_line = 1; 04646 char *ptr; 04647 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04648 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04649 *ptr = '\0'; 04650 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04651 first_line = 0; 04652 /* Substring is smaller, so this will never grow */ 04653 ast_str_set(&str2, 0, "%s", ptr + 1); 04654 } 04655 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04656 } else { 04657 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04658 } 04659 ast = ast_channel_unref(ast); 04660 } else { 04661 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04662 } 04663 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04664 if (ast_strlen_zero(flag)) { 04665 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04666 } else { 04667 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04668 } 04669 } else { 04670 if (ast_strlen_zero(flag)) { 04671 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04672 } else { 04673 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04674 } 04675 } 04676 04677 fprintf(p, "Message-ID: <Asterisk-%d-%u-%s-%d@%s>" ENDL, msgnum + 1, 04678 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04679 if (imap) { 04680 /* additional information needed for IMAP searching */ 04681 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04682 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04683 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04684 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04685 #ifdef IMAP_STORAGE 04686 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04687 #else 04688 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04689 #endif 04690 /* flag added for Urgent */ 04691 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04692 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04693 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04694 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04695 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04696 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04697 if (!ast_strlen_zero(category)) { 04698 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04699 } else { 04700 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04701 } 04702 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04703 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04704 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04705 } 04706 if (!ast_strlen_zero(cidnum)) { 04707 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04708 } 04709 if (!ast_strlen_zero(cidname)) { 04710 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04711 } 04712 fprintf(p, "MIME-Version: 1.0" ENDL); 04713 if (attach_user_voicemail) { 04714 /* Something unique. */ 04715 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%u", msgnum + 1, mailbox, 04716 (int) getpid(), (unsigned int) ast_random()); 04717 04718 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04719 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04720 fprintf(p, "--%s" ENDL, bound); 04721 } 04722 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04723 if (emailbody || vmu->emailbody) { 04724 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04725 struct ast_channel *ast; 04726 if ((ast = ast_dummy_channel_alloc())) { 04727 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04728 ast_str_substitute_variables(&str1, 0, ast, e_body); 04729 #ifdef IMAP_STORAGE 04730 { 04731 /* Convert body to native line terminators for IMAP backend */ 04732 char *line = ast_str_buffer(str1), *next; 04733 do { 04734 /* Terminate line before outputting it to the file */ 04735 if ((next = strchr(line, '\n'))) { 04736 *next++ = '\0'; 04737 } 04738 fprintf(p, "%s" ENDL, line); 04739 line = next; 04740 } while (!ast_strlen_zero(line)); 04741 } 04742 #else 04743 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04744 #endif 04745 ast = ast_channel_unref(ast); 04746 } else { 04747 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04748 } 04749 } else if (msgnum > -1) { 04750 if (strcmp(vmu->mailbox, mailbox)) { 04751 /* Forwarded type */ 04752 struct ast_config *msg_cfg; 04753 const char *v; 04754 int inttime; 04755 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04756 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04757 /* Retrieve info from VM attribute file */ 04758 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04759 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04760 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04761 strcat(fromfile, ".txt"); 04762 } 04763 if ((msg_cfg = ast_config_load(fromfile, config_flags)) && valid_config(msg_cfg)) { 04764 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04765 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04766 } 04767 04768 /* You might be tempted to do origdate, except that a) it's in the wrong 04769 * format, and b) it's missing for IMAP recordings. */ 04770 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04771 struct timeval tv = { inttime, }; 04772 struct ast_tm tm; 04773 ast_localtime(&tv, &tm, NULL); 04774 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04775 } 04776 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04777 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04778 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04779 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04780 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04781 date, origcallerid, origdate); 04782 ast_config_destroy(msg_cfg); 04783 } else { 04784 goto plain_message; 04785 } 04786 } else { 04787 plain_message: 04788 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04789 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04790 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04791 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04792 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04793 } 04794 } else { 04795 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04796 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04797 } 04798 04799 if (imap || attach_user_voicemail) { 04800 if (!ast_strlen_zero(attach2)) { 04801 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04802 ast_debug(5, "creating second attachment filename %s\n", filename); 04803 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04804 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04805 ast_debug(5, "creating attachment filename %s\n", filename); 04806 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04807 } else { 04808 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04809 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04810 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04811 } 04812 } 04813 ast_free(str1); 04814 ast_free(str2); 04815 }
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 1650 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().
01651 { 01652 return snprintf(dest, len, "%s/msg%04d", dir, num); 01653 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11674 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().
11675 { 11676 struct ast_vm_user *vmu = NULL; 11677 const char *id = astman_get_header(m, "ActionID"); 11678 char actionid[128] = ""; 11679 11680 if (!ast_strlen_zero(id)) 11681 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11682 11683 AST_LIST_LOCK(&users); 11684 11685 if (AST_LIST_EMPTY(&users)) { 11686 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11687 AST_LIST_UNLOCK(&users); 11688 return RESULT_SUCCESS; 11689 } 11690 11691 astman_send_ack(s, m, "Voicemail user list will follow"); 11692 11693 AST_LIST_TRAVERSE(&users, vmu, list) { 11694 char dirname[256]; 11695 11696 #ifdef IMAP_STORAGE 11697 int new, old; 11698 inboxcount(vmu->mailbox, &new, &old); 11699 #endif 11700 11701 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11702 astman_append(s, 11703 "%s" 11704 "Event: VoicemailUserEntry\r\n" 11705 "VMContext: %s\r\n" 11706 "VoiceMailbox: %s\r\n" 11707 "Fullname: %s\r\n" 11708 "Email: %s\r\n" 11709 "Pager: %s\r\n" 11710 "ServerEmail: %s\r\n" 11711 "MailCommand: %s\r\n" 11712 "Language: %s\r\n" 11713 "TimeZone: %s\r\n" 11714 "Callback: %s\r\n" 11715 "Dialout: %s\r\n" 11716 "UniqueID: %s\r\n" 11717 "ExitContext: %s\r\n" 11718 "SayDurationMinimum: %d\r\n" 11719 "SayEnvelope: %s\r\n" 11720 "SayCID: %s\r\n" 11721 "AttachMessage: %s\r\n" 11722 "AttachmentFormat: %s\r\n" 11723 "DeleteMessage: %s\r\n" 11724 "VolumeGain: %.2f\r\n" 11725 "CanReview: %s\r\n" 11726 "CallOperator: %s\r\n" 11727 "MaxMessageCount: %d\r\n" 11728 "MaxMessageLength: %d\r\n" 11729 "NewMessageCount: %d\r\n" 11730 #ifdef IMAP_STORAGE 11731 "OldMessageCount: %d\r\n" 11732 "IMAPUser: %s\r\n" 11733 #endif 11734 "\r\n", 11735 actionid, 11736 vmu->context, 11737 vmu->mailbox, 11738 vmu->fullname, 11739 vmu->email, 11740 vmu->pager, 11741 ast_strlen_zero(vmu->serveremail) ? serveremail : vmu->serveremail, 11742 mailcmd, 11743 vmu->language, 11744 vmu->zonetag, 11745 vmu->callback, 11746 vmu->dialout, 11747 vmu->uniqueid, 11748 vmu->exit, 11749 vmu->saydurationm, 11750 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11751 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11752 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11753 vmu->attachfmt, 11754 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11755 vmu->volgain, 11756 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11757 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11758 vmu->maxmsg, 11759 vmu->maxsecs, 11760 #ifdef IMAP_STORAGE 11761 new, old, vmu->imapuser 11762 #else 11763 count_messages(vmu, dirname) 11764 #endif 11765 ); 11766 } 11767 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11768 11769 AST_LIST_UNLOCK(&users); 11770 11771 return RESULT_SUCCESS; 11772 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11495 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().
11496 { 11497 while (poll_thread_run) { 11498 struct timespec ts = { 0, }; 11499 struct timeval wait; 11500 11501 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11502 ts.tv_sec = wait.tv_sec; 11503 ts.tv_nsec = wait.tv_usec * 1000; 11504 11505 ast_mutex_lock(&poll_lock); 11506 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11507 ast_mutex_unlock(&poll_lock); 11508 11509 if (!poll_thread_run) 11510 break; 11511 11512 poll_subscribed_mailboxes(); 11513 } 11514 11515 return NULL; 11516 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1711 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().
01712 { 01713 #ifdef IMAP_STORAGE 01714 if (vmu && id == 0) { 01715 return vmu->imapfolder; 01716 } 01717 #endif 01718 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01719 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5398 of file app_voicemail_odbcstorage.c.
References __has_voicemail().
Referenced by load_module().
05399 { 05400 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05401 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11518 of file app_voicemail_odbcstorage.c.
References ast_free.
Referenced by handle_unsubscribe().
11519 { 11520 ast_free(mwi_sub); 11521 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11606 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().
11607 { 11608 struct mwi_sub_task *mwist; 11609 11610 if (ast_event_get_type(event) != AST_EVENT_SUB) 11611 return; 11612 11613 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11614 return; 11615 11616 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11617 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11618 return; 11619 } 11620 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11621 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11622 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11623 11624 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11625 ast_free(mwist); 11626 } 11627 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11580 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().
11581 { 11582 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11583 11584 if (!uniqueid) { 11585 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11586 return; 11587 } 11588 11589 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11590 ast_free(uniqueid); 11591 return; 11592 } 11593 11594 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11595 ast_free(uniqueid); 11596 return; 11597 } 11598 11599 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11600 *uniqueid = u; 11601 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11602 ast_free(uniqueid); 11603 } 11604 }
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 7084 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().
07085 { 07086 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07087 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07088 const char *category; 07089 char *myserveremail = serveremail; 07090 07091 ast_channel_lock(chan); 07092 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07093 category = ast_strdupa(category); 07094 } 07095 ast_channel_unlock(chan); 07096 07097 #ifndef IMAP_STORAGE 07098 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07099 #else 07100 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07101 #endif 07102 make_file(fn, sizeof(fn), todir, msgnum); 07103 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07104 07105 if (!ast_strlen_zero(vmu->attachfmt)) { 07106 if (strstr(fmt, vmu->attachfmt)) 07107 fmt = vmu->attachfmt; 07108 else 07109 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); 07110 } 07111 07112 /* Attach only the first format */ 07113 fmt = ast_strdupa(fmt); 07114 stringp = fmt; 07115 strsep(&stringp, "|"); 07116 07117 if (!ast_strlen_zero(vmu->serveremail)) 07118 myserveremail = vmu->serveremail; 07119 07120 if (!ast_strlen_zero(vmu->email)) { 07121 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07122 07123 if (attach_user_voicemail) 07124 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07125 07126 /* XXX possible imap issue, should category be NULL XXX */ 07127 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07128 07129 if (attach_user_voicemail) 07130 DISPOSE(todir, msgnum); 07131 } 07132 07133 if (!ast_strlen_zero(vmu->pager)) { 07134 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07135 } 07136 07137 if (ast_test_flag(vmu, VM_DELETE)) 07138 DELETE(todir, msgnum, fn, vmu); 07139 07140 /* Leave voicemail for someone */ 07141 if (ast_app_has_voicemail(ext_context, NULL)) 07142 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07143 07144 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07145 07146 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); 07147 run_externnotify(vmu->context, vmu->mailbox, flag); 07148 07149 #ifdef IMAP_STORAGE 07150 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07151 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07152 vm_imap_delete(NULL, vms->curmsg, vmu); 07153 vms->newmessages--; /* Fix new message count */ 07154 } 07155 #endif 07156 07157 return 0; 07158 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4268 of file app_voicemail_odbcstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04269 { 04270 if (bio->linelength >= BASELINELEN) { 04271 if (fputs(ENDL, so) == EOF) { 04272 return -1; 04273 } 04274 04275 bio->linelength = 0; 04276 } 04277 04278 if (putc(((unsigned char) c), so) == EOF) { 04279 return -1; 04280 } 04281 04282 bio->linelength++; 04283 04284 return 1; 04285 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7932 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().
07933 { 07934 int count_msg, last_msg; 07935 07936 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07937 07938 /* Rename the member vmbox HERE so that we don't try to return before 07939 * we know what's going on. 07940 */ 07941 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07942 07943 /* Faster to make the directory than to check if it exists. */ 07944 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07945 07946 /* traverses directory using readdir (or select query for ODBC) */ 07947 count_msg = count_messages(vmu, vms->curdir); 07948 if (count_msg < 0) { 07949 return count_msg; 07950 } else { 07951 vms->lastmsg = count_msg - 1; 07952 } 07953 07954 if (vm_allocate_dh(vms, vmu, count_msg)) { 07955 return -1; 07956 } 07957 07958 /* 07959 The following test is needed in case sequencing gets messed up. 07960 There appears to be more than one way to mess up sequence, so 07961 we will not try to find all of the root causes--just fix it when 07962 detected. 07963 */ 07964 07965 if (vm_lock_path(vms->curdir)) { 07966 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07967 return ERROR_LOCK_PATH; 07968 } 07969 07970 /* for local storage, checks directory for messages up to maxmsg limit */ 07971 last_msg = last_message_index(vmu, vms->curdir); 07972 ast_unlock_path(vms->curdir); 07973 07974 if (last_msg < -1) { 07975 return last_msg; 07976 } else if (vms->lastmsg != last_msg) { 07977 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); 07978 resequence_mailbox(vmu, vms->curdir, count_msg); 07979 } 07980 07981 return 0; 07982 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7706 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, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, valid_config(), VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
Referenced by vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), vm_browse_messages_zh(), and vm_execmain().
07707 { 07708 int res = 0; 07709 char filename[256], *cid; 07710 const char *origtime, *context, *category, *duration, *flag; 07711 struct ast_config *msg_cfg; 07712 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07713 07714 vms->starting = 0; 07715 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07716 adsi_message(chan, vms); 07717 if (!vms->curmsg) { 07718 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07719 } else if (vms->curmsg == vms->lastmsg) { 07720 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07721 } 07722 07723 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07724 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07725 msg_cfg = ast_config_load(filename, config_flags); 07726 if (!valid_config(msg_cfg)) { 07727 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07728 return 0; 07729 } 07730 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07731 07732 /* Play the word urgent if we are listening to urgent messages */ 07733 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07734 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07735 } 07736 07737 if (!res) { 07738 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07739 /* POLISH syntax */ 07740 if (!strncasecmp(chan->language, "pl", 2)) { 07741 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07742 int ten, one; 07743 char nextmsg[256]; 07744 ten = (vms->curmsg + 1) / 10; 07745 one = (vms->curmsg + 1) % 10; 07746 07747 if (vms->curmsg < 20) { 07748 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07749 res = wait_file2(chan, vms, nextmsg); 07750 } else { 07751 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07752 res = wait_file2(chan, vms, nextmsg); 07753 if (one > 0) { 07754 if (!res) { 07755 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07756 res = wait_file2(chan, vms, nextmsg); 07757 } 07758 } 07759 } 07760 } 07761 if (!res) 07762 res = wait_file2(chan, vms, "vm-message"); 07763 /* HEBREW syntax */ 07764 } else if (!strncasecmp(chan->language, "he", 2)) { 07765 if (!vms->curmsg) { 07766 res = wait_file2(chan, vms, "vm-message"); 07767 res = wait_file2(chan, vms, "vm-first"); 07768 } else if (vms->curmsg == vms->lastmsg) { 07769 res = wait_file2(chan, vms, "vm-message"); 07770 res = wait_file2(chan, vms, "vm-last"); 07771 } else { 07772 res = wait_file2(chan, vms, "vm-message"); 07773 res = wait_file2(chan, vms, "vm-number"); 07774 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07775 } 07776 /* VIETNAMESE syntax */ 07777 } else if (!strncasecmp(chan->language, "vi", 2)) { 07778 if (!vms->curmsg) { 07779 res = wait_file2(chan, vms, "vm-message"); 07780 res = wait_file2(chan, vms, "vm-first"); 07781 } else if (vms->curmsg == vms->lastmsg) { 07782 res = wait_file2(chan, vms, "vm-message"); 07783 res = wait_file2(chan, vms, "vm-last"); 07784 } else { 07785 res = wait_file2(chan, vms, "vm-message"); 07786 res = wait_file2(chan, vms, "vm-number"); 07787 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07788 } 07789 } else { 07790 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07791 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07792 } else { /* DEFAULT syntax */ 07793 res = wait_file2(chan, vms, "vm-message"); 07794 } 07795 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07796 if (!res) { 07797 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07798 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07799 } 07800 } 07801 } 07802 } 07803 07804 if (!valid_config(msg_cfg)) { 07805 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07806 return 0; 07807 } 07808 07809 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07810 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07811 DISPOSE(vms->curdir, vms->curmsg); 07812 ast_config_destroy(msg_cfg); 07813 return 0; 07814 } 07815 07816 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07817 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07818 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07819 07820 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07821 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07822 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07823 if (!res) { 07824 res = play_message_category(chan, category); 07825 } 07826 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07827 res = play_message_datetime(chan, vmu, origtime, filename); 07828 } 07829 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07830 res = play_message_callerid(chan, vms, cid, context, 0); 07831 } 07832 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07833 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07834 } 07835 /* Allow pressing '1' to skip envelope / callerid */ 07836 if (res == '1') { 07837 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07838 res = 0; 07839 } 07840 ast_config_destroy(msg_cfg); 07841 07842 if (!res) { 07843 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07844 #ifdef IMAP_STORAGE 07845 ast_mutex_lock(&vms->lock); 07846 #endif 07847 vms->heard[vms->curmsg] = 1; 07848 #ifdef IMAP_STORAGE 07849 ast_mutex_unlock(&vms->lock); 07850 /*IMAP storage stores any prepended message from a forward 07851 * as a separate file from the rest of the message 07852 */ 07853 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07854 wait_file(chan, vms, vms->introfn); 07855 } 07856 #endif 07857 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07858 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07859 res = 0; 07860 } 07861 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07862 } 07863 DISPOSE(vms->curdir, vms->curmsg); 07864 return res; 07865 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7592 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().
07593 { 07594 int res = 0; 07595 int i; 07596 char *callerid, *name; 07597 char prefile[PATH_MAX] = ""; 07598 07599 07600 /* If voicemail cid is not enabled, or we didn't get cid or context from 07601 * the attribute file, leave now. 07602 * 07603 * TODO Still need to change this so that if this function is called by the 07604 * message envelope (and someone is explicitly requesting to hear the CID), 07605 * it does not check to see if CID is enabled in the config file. 07606 */ 07607 if ((cid == NULL)||(context == NULL)) 07608 return res; 07609 07610 /* Strip off caller ID number from name */ 07611 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07612 ast_callerid_parse(cid, &name, &callerid); 07613 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07614 /* Check for internal contexts and only */ 07615 /* say extension when the call didn't come from an internal context in the list */ 07616 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07617 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07618 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07619 break; 07620 } 07621 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07622 if (!res) { 07623 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07624 if (!ast_strlen_zero(prefile)) { 07625 /* See if we can find a recorded name for this person instead of their extension number */ 07626 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07627 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07628 if (!callback) 07629 res = wait_file2(chan, vms, "vm-from"); 07630 res = ast_stream_and_wait(chan, prefile, ""); 07631 } else { 07632 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07633 /* Say "from extension" as one saying to sound smoother */ 07634 if (!callback) 07635 res = wait_file2(chan, vms, "vm-from-extension"); 07636 res = ast_say_digit_str(chan, callerid, "", chan->language); 07637 } 07638 } 07639 } 07640 } else if (!res) { 07641 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07642 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07643 if (!callback) 07644 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07645 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07646 } 07647 } else { 07648 /* Number unknown */ 07649 ast_debug(1, "VM-CID: From an unknown number\n"); 07650 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07651 res = wait_file2(chan, vms, "vm-unknown-caller"); 07652 } 07653 return res; 07654 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7503 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07504 { 07505 int res = 0; 07506 07507 if (!ast_strlen_zero(category)) 07508 res = ast_play_and_wait(chan, category); 07509 07510 if (res) { 07511 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07512 res = 0; 07513 } 07514 07515 return res; 07516 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7518 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().
07519 { 07520 int res = 0; 07521 struct vm_zone *the_zone = NULL; 07522 time_t t; 07523 07524 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07525 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07526 return 0; 07527 } 07528 07529 /* Does this user have a timezone specified? */ 07530 if (!ast_strlen_zero(vmu->zonetag)) { 07531 /* Find the zone in the list */ 07532 struct vm_zone *z; 07533 AST_LIST_LOCK(&zones); 07534 AST_LIST_TRAVERSE(&zones, z, list) { 07535 if (!strcmp(z->name, vmu->zonetag)) { 07536 the_zone = z; 07537 break; 07538 } 07539 } 07540 AST_LIST_UNLOCK(&zones); 07541 } 07542 07543 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07544 #if 0 07545 /* Set the DIFF_* variables */ 07546 ast_localtime(&t, &time_now, NULL); 07547 tv_now = ast_tvnow(); 07548 ast_localtime(&tv_now, &time_then, NULL); 07549 07550 /* Day difference */ 07551 if (time_now.tm_year == time_then.tm_year) 07552 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07553 else 07554 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07555 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07556 07557 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07558 #endif 07559 if (the_zone) { 07560 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07561 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07562 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07563 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07564 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07565 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07566 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); 07567 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07568 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07569 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07570 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07571 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07572 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07573 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07574 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); 07575 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07576 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07577 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07578 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07579 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07580 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); 07581 } else { 07582 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07583 } 07584 #if 0 07585 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07586 #endif 07587 return res; 07588 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7656 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().
07657 { 07658 int res = 0; 07659 int durationm; 07660 int durations; 07661 /* Verify that we have a duration for the message */ 07662 if (duration == NULL) 07663 return res; 07664 07665 /* Convert from seconds to minutes */ 07666 durations = atoi(duration); 07667 durationm = (durations / 60); 07668 07669 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07670 07671 if ((!res) && (durationm >= minduration)) { 07672 res = wait_file2(chan, vms, "vm-duration"); 07673 07674 /* POLISH syntax */ 07675 if (!strncasecmp(chan->language, "pl", 2)) { 07676 div_t num = div(durationm, 10); 07677 07678 if (durationm == 1) { 07679 res = ast_play_and_wait(chan, "digits/1z"); 07680 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07681 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07682 if (num.rem == 2) { 07683 if (!num.quot) { 07684 res = ast_play_and_wait(chan, "digits/2-ie"); 07685 } else { 07686 res = say_and_wait(chan, durationm - 2 , chan->language); 07687 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07688 } 07689 } else { 07690 res = say_and_wait(chan, durationm, chan->language); 07691 } 07692 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07693 } else { 07694 res = say_and_wait(chan, durationm, chan->language); 07695 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07696 } 07697 /* DEFAULT syntax */ 07698 } else { 07699 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07700 res = wait_file2(chan, vms, "vm-minutes"); 07701 } 07702 } 07703 return res; 07704 }
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 13457 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().
13460 { 13461 /* Record message & let caller review or re-record it, or set options if applicable */ 13462 int res = 0; 13463 int cmd = 0; 13464 int max_attempts = 3; 13465 int attempts = 0; 13466 int recorded = 0; 13467 int msg_exists = 0; 13468 signed char zero_gain = 0; 13469 char tempfile[PATH_MAX]; 13470 char *acceptdtmf = "#"; 13471 char *canceldtmf = ""; 13472 int canceleddtmf = 0; 13473 13474 /* Note that urgent and private are for flagging messages as such in the future */ 13475 13476 /* barf if no pointer passed to store duration in */ 13477 if (duration == NULL) { 13478 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13479 return -1; 13480 } 13481 13482 if (!outsidecaller) 13483 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13484 else 13485 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13486 13487 cmd = '3'; /* Want to start by recording */ 13488 13489 while ((cmd >= 0) && (cmd != 't')) { 13490 switch (cmd) { 13491 case '1': 13492 if (!msg_exists) { 13493 /* In this case, 1 is to record a message */ 13494 cmd = '3'; 13495 break; 13496 } else { 13497 /* Otherwise 1 is to save the existing message */ 13498 ast_verb(3, "Saving message as is\n"); 13499 if (!outsidecaller) 13500 ast_filerename(tempfile, recordfile, NULL); 13501 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13502 if (!outsidecaller) { 13503 /* Saves to IMAP server only if imapgreeting=yes */ 13504 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13505 DISPOSE(recordfile, -1); 13506 } 13507 cmd = 't'; 13508 return res; 13509 } 13510 case '2': 13511 /* Review */ 13512 ast_verb(3, "Reviewing the message\n"); 13513 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13514 break; 13515 case '3': 13516 msg_exists = 0; 13517 /* Record */ 13518 if (recorded == 1) 13519 ast_verb(3, "Re-recording the message\n"); 13520 else 13521 ast_verb(3, "Recording the message\n"); 13522 13523 if (recorded && outsidecaller) { 13524 cmd = ast_play_and_wait(chan, INTRO); 13525 cmd = ast_play_and_wait(chan, "beep"); 13526 } 13527 recorded = 1; 13528 /* 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 */ 13529 if (record_gain) 13530 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13531 if (ast_test_flag(vmu, VM_OPERATOR)) 13532 canceldtmf = "0"; 13533 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13534 if (strchr(canceldtmf, cmd)) { 13535 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13536 canceleddtmf = 1; 13537 } 13538 if (record_gain) 13539 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13540 if (cmd == -1) { 13541 /* User has hung up, no options to give */ 13542 if (!outsidecaller) { 13543 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13544 ast_filedelete(tempfile, NULL); 13545 } 13546 return cmd; 13547 } 13548 if (cmd == '0') { 13549 break; 13550 } else if (cmd == '*') { 13551 break; 13552 #if 0 13553 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13554 /* Message is too short */ 13555 ast_verb(3, "Message too short\n"); 13556 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13557 cmd = ast_filedelete(tempfile, NULL); 13558 break; 13559 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13560 /* Message is all silence */ 13561 ast_verb(3, "Nothing recorded\n"); 13562 cmd = ast_filedelete(tempfile, NULL); 13563 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13564 if (!cmd) 13565 cmd = ast_play_and_wait(chan, "vm-speakup"); 13566 break; 13567 #endif 13568 } else { 13569 /* If all is well, a message exists */ 13570 msg_exists = 1; 13571 cmd = 0; 13572 } 13573 break; 13574 case '4': 13575 if (outsidecaller) { /* only mark vm messages */ 13576 /* Mark Urgent */ 13577 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13578 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13579 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13580 strcpy(flag, "Urgent"); 13581 } else if (flag) { 13582 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13583 res = ast_play_and_wait(chan, "vm-marked-nonurgent"); 13584 strcpy(flag, ""); 13585 } else { 13586 ast_play_and_wait(chan, "vm-sorry"); 13587 } 13588 cmd = 0; 13589 } else { 13590 cmd = ast_play_and_wait(chan, "vm-sorry"); 13591 } 13592 break; 13593 case '5': 13594 case '6': 13595 case '7': 13596 case '8': 13597 case '9': 13598 case '*': 13599 case '#': 13600 cmd = ast_play_and_wait(chan, "vm-sorry"); 13601 break; 13602 #if 0 13603 /* XXX Commented out for the moment because of the dangers of deleting 13604 a message while recording (can put the message numbers out of sync) */ 13605 case '*': 13606 /* Cancel recording, delete message, offer to take another message*/ 13607 cmd = ast_play_and_wait(chan, "vm-deleted"); 13608 cmd = ast_filedelete(tempfile, NULL); 13609 if (outsidecaller) { 13610 res = vm_exec(chan, NULL); 13611 return res; 13612 } 13613 else 13614 return 1; 13615 #endif 13616 case '0': 13617 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13618 cmd = ast_play_and_wait(chan, "vm-sorry"); 13619 break; 13620 } 13621 if (msg_exists || recorded) { 13622 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13623 if (!cmd) 13624 cmd = ast_waitfordigit(chan, 3000); 13625 if (cmd == '1') { 13626 ast_filerename(tempfile, recordfile, NULL); 13627 ast_play_and_wait(chan, "vm-msgsaved"); 13628 cmd = '0'; 13629 } else if (cmd == '4') { 13630 if (flag) { 13631 ast_play_and_wait(chan, "vm-marked-urgent"); 13632 strcpy(flag, "Urgent"); 13633 } 13634 ast_play_and_wait(chan, "vm-msgsaved"); 13635 cmd = '0'; 13636 } else { 13637 ast_play_and_wait(chan, "vm-deleted"); 13638 DELETE(tempfile, -1, tempfile, vmu); 13639 cmd = '0'; 13640 } 13641 } 13642 return cmd; 13643 default: 13644 /* If the caller is an ouside caller, and the review option is enabled, 13645 allow them to review the message, but let the owner of the box review 13646 their OGM's */ 13647 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13648 return cmd; 13649 if (msg_exists) { 13650 cmd = ast_play_and_wait(chan, "vm-review"); 13651 if (!cmd && outsidecaller) { 13652 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13653 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13654 } else if (flag) { 13655 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13656 } 13657 } 13658 } else { 13659 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13660 if (!cmd) 13661 cmd = ast_waitfordigit(chan, 600); 13662 } 13663 13664 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13665 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13666 if (!cmd) 13667 cmd = ast_waitfordigit(chan, 600); 13668 } 13669 #if 0 13670 if (!cmd) 13671 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13672 #endif 13673 if (!cmd) 13674 cmd = ast_waitfordigit(chan, 6000); 13675 if (!cmd) { 13676 attempts++; 13677 } 13678 if (attempts > max_attempts) { 13679 cmd = 't'; 13680 } 13681 } 13682 } 13683 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13684 /* Hang up or timeout, so delete the recording. */ 13685 ast_filedelete(tempfile, NULL); 13686 } 13687 13688 if (cmd != 't' && outsidecaller) 13689 ast_play_and_wait(chan, "vm-goodbye"); 13690 13691 return cmd; 13692 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11467 of file app_voicemail_odbcstorage.c.
References inboxcount2(), queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11468 { 11469 int new = 0, old = 0, urgent = 0; 11470 11471 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11472 11473 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11474 mwi_sub->old_urgent = urgent; 11475 mwi_sub->old_new = new; 11476 mwi_sub->old_old = old; 11477 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11478 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11479 } 11480 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11482 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().
11483 { 11484 struct mwi_sub *mwi_sub; 11485 11486 AST_RWLIST_RDLOCK(&mwi_subs); 11487 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11488 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11489 poll_subscribed_mailbox(mwi_sub); 11490 } 11491 } 11492 AST_RWLIST_UNLOCK(&mwi_subs); 11493 }
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 995 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().
00996 { 00997 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00998 vmu->passwordlocation = passwordlocation; 00999 if (saydurationminfo) { 01000 vmu->saydurationm = saydurationminfo; 01001 } 01002 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01003 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01004 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01005 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01006 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01007 if (vmminsecs) { 01008 vmu->minsecs = vmminsecs; 01009 } 01010 if (vmmaxsecs) { 01011 vmu->maxsecs = vmmaxsecs; 01012 } 01013 if (maxmsg) { 01014 vmu->maxmsg = maxmsg; 01015 } 01016 if (maxdeletedmsg) { 01017 vmu->maxdeletedmsg = maxdeletedmsg; 01018 } 01019 vmu->volgain = volgain; 01020 ast_free(vmu->emailsubject); 01021 vmu->emailsubject = NULL; 01022 ast_free(vmu->emailbody); 01023 vmu->emailbody = NULL; 01024 #ifdef IMAP_STORAGE 01025 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01026 #endif 01027 }
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 4356 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(), S_OR, and valid_config().
Referenced by make_email_file(), and sendpage().
04357 { 04358 char callerid[256]; 04359 char num[12]; 04360 char fromdir[256], fromfile[256]; 04361 struct ast_config *msg_cfg; 04362 const char *origcallerid, *origtime; 04363 char origcidname[80], origcidnum[80], origdate[80]; 04364 int inttime; 04365 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04366 04367 /* Prepare variables for substitution in email body and subject */ 04368 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04369 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04370 snprintf(num, sizeof(num), "%d", msgnum); 04371 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04372 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04373 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04374 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04375 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04376 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04377 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04378 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04379 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04380 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04381 04382 /* Retrieve info from VM attribute file */ 04383 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04384 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04385 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04386 strcat(fromfile, ".txt"); 04387 } 04388 if (!(msg_cfg = ast_config_load(fromfile, config_flags)) || !(valid_config(msg_cfg))) { 04389 if (option_debug > 0) { 04390 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04391 } 04392 return; 04393 } 04394 04395 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04396 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04397 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04398 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04399 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04400 } 04401 04402 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04403 struct timeval tv = { inttime, }; 04404 struct ast_tm tm; 04405 ast_localtime(&tv, &tm, NULL); 04406 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04407 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04408 } 04409 ast_config_destroy(msg_cfg); 04410 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7047 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().
07048 { 07049 struct ast_event *event; 07050 char *mailbox, *context; 07051 07052 /* Strip off @default */ 07053 context = mailbox = ast_strdupa(box); 07054 strsep(&context, "@"); 07055 if (ast_strlen_zero(context)) 07056 context = "default"; 07057 07058 if (!(event = ast_event_new(AST_EVENT_MWI, 07059 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07060 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07061 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07062 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07063 AST_EVENT_IE_END))) { 07064 return; 07065 } 07066 07067 ast_event_queue_and_cache(event); 07068 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12573 of file app_voicemail_odbcstorage.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), LOG_NOTICE, and valid_config().
Referenced by actual_load_config(), and append_mailbox().
12573 { 12574 struct ast_config *pwconf; 12575 struct ast_flags config_flags = { 0 }; 12576 12577 pwconf = ast_config_load(secretfn, config_flags); 12578 if (valid_config(pwconf)) { 12579 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12580 if (val) { 12581 ast_copy_string(password, val, passwordlen); 12582 ast_config_destroy(pwconf); 12583 return; 12584 } 12585 ast_config_destroy(pwconf); 12586 } 12587 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12588 }
static int reload | ( | void | ) | [static] |
Definition at line 13104 of file app_voicemail_odbcstorage.c.
References load_config().
13105 { 13106 return load_config(1); 13107 }
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 4026 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04027 { 04028 char stxt[PATH_MAX]; 04029 char dtxt[PATH_MAX]; 04030 ast_filerename(sfn, dfn, NULL); 04031 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04032 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04033 if (ast_check_realtime("voicemail_data")) { 04034 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04035 } 04036 rename(stxt, dtxt); 04037 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6173 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().
06174 { 06175 /* we know the actual number of messages, so stop process when number is hit */ 06176 06177 int x, dest; 06178 char sfn[PATH_MAX]; 06179 char dfn[PATH_MAX]; 06180 06181 if (vm_lock_path(dir)) { 06182 return ERROR_LOCK_PATH; 06183 } 06184 06185 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06186 make_file(sfn, sizeof(sfn), dir, x); 06187 if (EXISTS(dir, x, sfn, NULL)) { 06188 06189 if (x != dest) { 06190 make_file(dfn, sizeof(dfn), dir, dest); 06191 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06192 } 06193 06194 dest++; 06195 } 06196 } 06197 ast_unlock_path(dir); 06198 06199 return dest; 06200 }
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 1465 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().
01466 { 01467 /* This function could be made to generate one from a database, too */ 01468 struct ast_vm_user *cur; 01469 int res = -1; 01470 AST_LIST_LOCK(&users); 01471 AST_LIST_TRAVERSE(&users, cur, list) { 01472 if ((!context || !strcasecmp(context, cur->context)) && 01473 (!strcasecmp(mailbox, cur->mailbox))) 01474 break; 01475 } 01476 if (cur) { 01477 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01478 res = 0; 01479 } 01480 AST_LIST_UNLOCK(&users); 01481 return res; 01482 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5541 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(), S_OR, and SMDI_MWI_WAIT_TIMEOUT.
Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
05542 { 05543 char arguments[255]; 05544 char ext_context[256] = ""; 05545 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05546 struct ast_smdi_mwi_message *mwi_msg; 05547 05548 if (!ast_strlen_zero(context)) 05549 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05550 else 05551 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05552 05553 if (smdi_iface) { 05554 if (ast_app_has_voicemail(ext_context, NULL)) 05555 ast_smdi_mwi_set(smdi_iface, extension); 05556 else 05557 ast_smdi_mwi_unset(smdi_iface, extension); 05558 05559 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05560 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05561 if (!strncmp(mwi_msg->cause, "INV", 3)) 05562 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05563 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05564 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05565 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05566 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05567 } else { 05568 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05569 } 05570 } 05571 05572 if (!ast_strlen_zero(externnotify)) { 05573 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05574 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05575 } else { 05576 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", 05577 externnotify, S_OR(context, "\"\""), 05578 extension, newvoicemails, 05579 oldvoicemails, urgentvoicemails); 05580 ast_debug(1, "Executing %s\n", arguments); 05581 ast_safe_system(arguments); 05582 } 05583 } 05584 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6210 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().
06211 { 06212 #ifdef IMAP_STORAGE 06213 /* we must use mbox(x) folder names, and copy the message there */ 06214 /* simple. huh? */ 06215 char sequence[10]; 06216 char mailbox[256]; 06217 int res; 06218 06219 /* get the real IMAP message number for this message */ 06220 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06221 06222 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06223 ast_mutex_lock(&vms->lock); 06224 /* if save to Old folder, put in INBOX as read */ 06225 if (box == OLD_FOLDER) { 06226 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06227 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06228 } else if (box == NEW_FOLDER) { 06229 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06230 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06231 } 06232 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06233 ast_mutex_unlock(&vms->lock); 06234 return 0; 06235 } 06236 /* Create the folder if it don't exist */ 06237 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06238 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06239 if (mail_create(vms->mailstream, mailbox) == NIL) 06240 ast_debug(5, "Folder exists.\n"); 06241 else 06242 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06243 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06244 ast_mutex_unlock(&vms->lock); 06245 return res; 06246 #else 06247 char *dir = vms->curdir; 06248 char *username = vms->username; 06249 char *context = vmu->context; 06250 char sfn[PATH_MAX]; 06251 char dfn[PATH_MAX]; 06252 char ddir[PATH_MAX]; 06253 const char *dbox = mbox(vmu, box); 06254 int x, i; 06255 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06256 06257 if (vm_lock_path(ddir)) 06258 return ERROR_LOCK_PATH; 06259 06260 x = last_message_index(vmu, ddir) + 1; 06261 06262 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06263 x--; 06264 for (i = 1; i <= x; i++) { 06265 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06266 make_file(sfn, sizeof(sfn), ddir, i); 06267 make_file(dfn, sizeof(dfn), ddir, i - 1); 06268 if (EXISTS(ddir, i, sfn, NULL)) { 06269 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06270 } else 06271 break; 06272 } 06273 } else { 06274 if (x >= vmu->maxmsg) { 06275 ast_unlock_path(ddir); 06276 return -1; 06277 } 06278 } 06279 make_file(sfn, sizeof(sfn), dir, msg); 06280 make_file(dfn, sizeof(dfn), ddir, x); 06281 if (strcmp(sfn, dfn)) { 06282 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06283 } 06284 ast_unlock_path(ddir); 06285 #endif 06286 return 0; 06287 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6203 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().
06204 { 06205 int d; 06206 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06207 return d; 06208 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12559 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().
12560 { 12561 int res = -1; 12562 char dir[PATH_MAX]; 12563 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12564 ast_debug(2, "About to try retrieving name file %s\n", dir); 12565 RETRIEVE(dir, -1, mailbox, context); 12566 if (ast_fileexists(dir, NULL, NULL)) { 12567 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12568 } 12569 DISPOSE(dir, -1); 12570 return res; 12571 }
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 4871 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().
04872 { 04873 FILE *p = NULL; 04874 char tmp[80] = "/tmp/astmail-XXXXXX"; 04875 char tmp2[256]; 04876 char *stringp; 04877 04878 if (vmu && ast_strlen_zero(vmu->email)) { 04879 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04880 return(0); 04881 } 04882 04883 /* Mail only the first format */ 04884 format = ast_strdupa(format); 04885 stringp = format; 04886 strsep(&stringp, "|"); 04887 04888 if (!strcmp(format, "wav49")) 04889 format = "WAV"; 04890 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %u\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04891 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04892 command hangs */ 04893 if ((p = vm_mkftemp(tmp)) == NULL) { 04894 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04895 return -1; 04896 } else { 04897 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04898 fclose(p); 04899 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04900 ast_safe_system(tmp2); 04901 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04902 } 04903 return 0; 04904 }
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 4906 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().
04907 { 04908 char enc_cidnum[256], enc_cidname[256]; 04909 char date[256]; 04910 char host[MAXHOSTNAMELEN] = ""; 04911 char who[256]; 04912 char dur[PATH_MAX]; 04913 char tmp[80] = "/tmp/astmail-XXXXXX"; 04914 char tmp2[PATH_MAX]; 04915 struct ast_tm tm; 04916 FILE *p; 04917 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04918 04919 if (!str1 || !str2) { 04920 ast_free(str1); 04921 ast_free(str2); 04922 return -1; 04923 } 04924 04925 if (cidnum) { 04926 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04927 } 04928 if (cidname) { 04929 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04930 } 04931 04932 if ((p = vm_mkftemp(tmp)) == NULL) { 04933 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04934 ast_free(str1); 04935 ast_free(str2); 04936 return -1; 04937 } 04938 gethostname(host, sizeof(host)-1); 04939 if (strchr(srcemail, '@')) { 04940 ast_copy_string(who, srcemail, sizeof(who)); 04941 } else { 04942 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04943 } 04944 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04945 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04946 fprintf(p, "Date: %s\n", date); 04947 04948 /* Reformat for custom pager format */ 04949 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04950 04951 if (!ast_strlen_zero(pagerfromstring)) { 04952 struct ast_channel *ast; 04953 if ((ast = ast_dummy_channel_alloc())) { 04954 char *ptr; 04955 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04956 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04957 04958 if (check_mime(ast_str_buffer(str1))) { 04959 int first_line = 1; 04960 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04961 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04962 *ptr = '\0'; 04963 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04964 first_line = 0; 04965 /* Substring is smaller, so this will never grow */ 04966 ast_str_set(&str2, 0, "%s", ptr + 1); 04967 } 04968 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04969 } else { 04970 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04971 } 04972 ast = ast_channel_unref(ast); 04973 } else { 04974 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04975 } 04976 } else { 04977 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04978 } 04979 04980 if (check_mime(vmu->fullname)) { 04981 int first_line = 1; 04982 char *ptr; 04983 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04984 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04985 *ptr = '\0'; 04986 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04987 first_line = 0; 04988 /* Substring is smaller, so this will never grow */ 04989 ast_str_set(&str2, 0, "%s", ptr + 1); 04990 } 04991 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04992 } else { 04993 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04994 } 04995 04996 if (!ast_strlen_zero(pagersubject)) { 04997 struct ast_channel *ast; 04998 if ((ast = ast_dummy_channel_alloc())) { 04999 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05000 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 05001 if (check_mime(ast_str_buffer(str1))) { 05002 int first_line = 1; 05003 char *ptr; 05004 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 05005 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 05006 *ptr = '\0'; 05007 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05008 first_line = 0; 05009 /* Substring is smaller, so this will never grow */ 05010 ast_str_set(&str2, 0, "%s", ptr + 1); 05011 } 05012 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 05013 } else { 05014 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 05015 } 05016 ast = ast_channel_unref(ast); 05017 } else { 05018 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05019 } 05020 } else { 05021 if (ast_strlen_zero(flag)) { 05022 fprintf(p, "Subject: New VM\n\n"); 05023 } else { 05024 fprintf(p, "Subject: New %s VM\n\n", flag); 05025 } 05026 } 05027 05028 if (pagerbody) { 05029 struct ast_channel *ast; 05030 if ((ast = ast_dummy_channel_alloc())) { 05031 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05032 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05033 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05034 ast = ast_channel_unref(ast); 05035 } else { 05036 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05037 } 05038 } else { 05039 fprintf(p, "New %s long %s msg in box %s\n" 05040 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05041 } 05042 05043 fclose(p); 05044 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05045 ast_safe_system(tmp2); 05046 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05047 ast_free(str1); 05048 ast_free(str2); 05049 return 0; 05050 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11124 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().
11125 { 11126 struct ast_config *cfg; 11127 const char *cat = NULL; 11128 11129 if (!(cfg = ast_load_realtime_multientry("voicemail", 11130 "context", context, SENTINEL))) { 11131 return CLI_FAILURE; 11132 } 11133 11134 ast_cli(fd, 11135 "\n" 11136 "=============================================================\n" 11137 "=== Configured Voicemail Users ==============================\n" 11138 "=============================================================\n" 11139 "===\n"); 11140 11141 while ((cat = ast_category_browse(cfg, cat))) { 11142 struct ast_variable *var = NULL; 11143 ast_cli(fd, 11144 "=== Mailbox ...\n" 11145 "===\n"); 11146 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11147 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11148 ast_cli(fd, 11149 "===\n" 11150 "=== ---------------------------------------------------------\n" 11151 "===\n"); 11152 } 11153 11154 ast_cli(fd, 11155 "=============================================================\n" 11156 "\n"); 11157 11158 ast_config_destroy(cfg); 11159 11160 return CLI_SUCCESS; 11161 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11629 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().
11630 { 11631 int errcode; 11632 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11633 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11634 AST_EVENT_IE_END); 11635 11636 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11637 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11638 AST_EVENT_IE_END); 11639 11640 if (mwi_sub_sub) 11641 ast_event_report_subs(mwi_sub_sub); 11642 11643 poll_thread_run = 1; 11644 11645 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11646 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11647 } 11648 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11650 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().
11651 { 11652 poll_thread_run = 0; 11653 11654 if (mwi_sub_sub) { 11655 ast_event_unsubscribe(mwi_sub_sub); 11656 mwi_sub_sub = NULL; 11657 } 11658 11659 if (mwi_unsub_sub) { 11660 ast_event_unsubscribe(mwi_unsub_sub); 11661 mwi_unsub_sub = NULL; 11662 } 11663 11664 ast_mutex_lock(&poll_lock); 11665 ast_cond_signal(&poll_cond); 11666 ast_mutex_unlock(&poll_lock); 11667 11668 pthread_join(poll_thread, NULL); 11669 11670 poll_thread = AST_PTHREADT_NULL; 11671 }
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 965 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 11796 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().
11797 { 11798 char *current; 11799 11800 /* Add 16 for fudge factor */ 11801 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11802 11803 ast_str_reset(str); 11804 11805 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11806 for (current = (char *) value; *current; current++) { 11807 if (*current == '\\') { 11808 current++; 11809 if (!*current) { 11810 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11811 break; 11812 } 11813 switch (*current) { 11814 case '\\': 11815 ast_str_append(&str, 0, "\\"); 11816 break; 11817 case 'r': 11818 ast_str_append(&str, 0, "\r"); 11819 break; 11820 case 'n': 11821 #ifdef IMAP_STORAGE 11822 if (!str->used || str->str[str->used - 1] != '\r') { 11823 ast_str_append(&str, 0, "\r"); 11824 } 11825 #endif 11826 ast_str_append(&str, 0, "\n"); 11827 break; 11828 case 't': 11829 ast_str_append(&str, 0, "\t"); 11830 break; 11831 default: 11832 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11833 break; 11834 } 11835 } else { 11836 ast_str_append(&str, 0, "%c", *current); 11837 } 11838 } 11839 11840 return ast_str_buffer(str); 11841 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13109 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().
13110 { 13111 int res; 13112 13113 res = ast_unregister_application(app); 13114 res |= ast_unregister_application(app2); 13115 res |= ast_unregister_application(app3); 13116 res |= ast_unregister_application(app4); 13117 res |= ast_unregister_application(sayname_app); 13118 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13119 res |= ast_manager_unregister("VoicemailUsersList"); 13120 res |= ast_data_unregister(NULL); 13121 #ifdef TEST_FRAMEWORK 13122 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13123 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13124 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13125 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13126 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13127 #endif 13128 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13129 ast_uninstall_vm_functions(); 13130 ao2_ref(inprocess_container, -1); 13131 13132 if (poll_thread != AST_PTHREADT_NULL) 13133 stop_poll_thread(); 13134 13135 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13136 ast_unload_realtime("voicemail"); 13137 ast_unload_realtime("voicemail_data"); 13138 13139 free_vm_users(); 13140 free_vm_zones(); 13141 return res; 13142 }
static int valid_config | ( | const struct ast_config * | cfg | ) | [inline, static] |
Check if configuration file is valid.
Definition at line 1487 of file app_voicemail_odbcstorage.c.
References CONFIG_STATUS_FILEINVALID.
Referenced by advanced_options(), make_email_file(), play_message(), prep_email_sub_vars(), read_password_from_file(), vm_change_password(), and vm_forwardoptions().
01488 { 01489 return cfg && cfg != CONFIG_STATUS_FILEINVALID; 01490 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1748 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().
01748 { 01749 01750 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01751 01752 /* remove old allocation */ 01753 if (vms->deleted) { 01754 ast_free(vms->deleted); 01755 vms->deleted = NULL; 01756 } 01757 if (vms->heard) { 01758 ast_free(vms->heard); 01759 vms->heard = NULL; 01760 } 01761 vms->dh_arraysize = 0; 01762 01763 if (arraysize > 0) { 01764 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01765 return -1; 01766 } 01767 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01768 ast_free(vms->deleted); 01769 vms->deleted = NULL; 01770 return -1; 01771 } 01772 vms->dh_arraysize = arraysize; 01773 } 01774 01775 return 0; 01776 }
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 9804 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_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().
09807 { 09808 int useadsi = 0, valid = 0, logretries = 0; 09809 char password[AST_MAX_EXTENSION]="", *passptr; 09810 struct ast_vm_user vmus, *vmu = NULL; 09811 09812 /* If ADSI is supported, setup login screen */ 09813 adsi_begin(chan, &useadsi); 09814 if (!skipuser && useadsi) 09815 adsi_login(chan); 09816 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09817 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09818 return -1; 09819 } 09820 09821 /* Authenticate them and get their mailbox/password */ 09822 09823 while (!valid && (logretries < max_logins)) { 09824 /* Prompt for, and read in the username */ 09825 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09826 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09827 return -1; 09828 } 09829 if (ast_strlen_zero(mailbox)) { 09830 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09831 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09832 } else { 09833 ast_verb(3, "Username not entered\n"); 09834 return -1; 09835 } 09836 } else if (mailbox[0] == '*') { 09837 /* user entered '*' */ 09838 ast_verb(4, "Mailbox 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 return -1; 09842 } 09843 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09844 mailbox[0] = '\0'; 09845 } 09846 09847 if (useadsi) 09848 adsi_password(chan); 09849 09850 if (!ast_strlen_zero(prefix)) { 09851 char fullusername[80] = ""; 09852 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09853 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09854 ast_copy_string(mailbox, fullusername, mailbox_size); 09855 } 09856 09857 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09858 vmu = find_user(&vmus, context, mailbox); 09859 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09860 /* saved password is blank, so don't bother asking */ 09861 password[0] = '\0'; 09862 } else { 09863 if (ast_streamfile(chan, vm_password, chan->language)) { 09864 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09865 return -1; 09866 } 09867 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09868 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09869 return -1; 09870 } else if (password[0] == '*') { 09871 /* user entered '*' */ 09872 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09873 if (ast_exists_extension(chan, chan->context, "a", 1, 09874 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09875 mailbox[0] = '*'; 09876 return -1; 09877 } 09878 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09879 mailbox[0] = '\0'; 09880 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09881 vmu = NULL; 09882 } 09883 } 09884 09885 if (vmu) { 09886 passptr = vmu->password; 09887 if (passptr[0] == '-') passptr++; 09888 } 09889 if (vmu && !strcmp(passptr, password)) 09890 valid++; 09891 else { 09892 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09893 if (!ast_strlen_zero(prefix)) 09894 mailbox[0] = '\0'; 09895 } 09896 logretries++; 09897 if (!valid) { 09898 if (skipuser || logretries >= max_logins) { 09899 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09900 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09901 return -1; 09902 } 09903 } else { 09904 if (useadsi) 09905 adsi_login(chan); 09906 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09907 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09908 return -1; 09909 } 09910 } 09911 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09912 return -1; 09913 } 09914 } 09915 if (!valid && (logretries >= max_logins)) { 09916 ast_stopstream(chan); 09917 ast_play_and_wait(chan, "vm-goodbye"); 09918 return -1; 09919 } 09920 if (vmu && !skipuser) { 09921 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09922 } 09923 return 0; 09924 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11019 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().
11020 { 11021 struct ast_vm_user svm; 11022 char *context, *box; 11023 AST_DECLARE_APP_ARGS(args, 11024 AST_APP_ARG(mbox); 11025 AST_APP_ARG(options); 11026 ); 11027 static int dep_warning = 0; 11028 11029 if (ast_strlen_zero(data)) { 11030 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11031 return -1; 11032 } 11033 11034 if (!dep_warning) { 11035 dep_warning = 1; 11036 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11037 } 11038 11039 box = ast_strdupa(data); 11040 11041 AST_STANDARD_APP_ARGS(args, box); 11042 11043 if (args.options) { 11044 } 11045 11046 if ((context = strchr(args.mbox, '@'))) { 11047 *context = '\0'; 11048 context++; 11049 } 11050 11051 if (find_user(&svm, context, args.mbox)) { 11052 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11053 } else 11054 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11055 11056 return 0; 11057 }
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 9783 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().
09784 { 09785 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09786 return vm_browse_messages_es(chan, vms, vmu); 09787 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09788 return vm_browse_messages_gr(chan, vms, vmu); 09789 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09790 return vm_browse_messages_he(chan, vms, vmu); 09791 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09792 return vm_browse_messages_it(chan, vms, vmu); 09793 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09794 return vm_browse_messages_pt(chan, vms, vmu); 09795 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09796 return vm_browse_messages_vi(chan, vms, vmu); 09797 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09798 return vm_browse_messages_zh(chan, vms, vmu); 09799 } else { /* Default to English syntax */ 09800 return vm_browse_messages_en(chan, vms, vmu); 09801 } 09802 }
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 9622 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().
09623 { 09624 int cmd = 0; 09625 09626 if (vms->lastmsg > -1) { 09627 cmd = play_message(chan, vmu, vms); 09628 } else { 09629 cmd = ast_play_and_wait(chan, "vm-youhave"); 09630 if (!cmd) 09631 cmd = ast_play_and_wait(chan, "vm-no"); 09632 if (!cmd) { 09633 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09634 cmd = ast_play_and_wait(chan, vms->fn); 09635 } 09636 if (!cmd) 09637 cmd = ast_play_and_wait(chan, "vm-messages"); 09638 } 09639 return cmd; 09640 }
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 9676 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().
09677 { 09678 int cmd; 09679 09680 if (vms->lastmsg > -1) { 09681 cmd = play_message(chan, vmu, vms); 09682 } else { 09683 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09684 if (!cmd) 09685 cmd = ast_play_and_wait(chan, "vm-messages"); 09686 if (!cmd) { 09687 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09688 cmd = ast_play_and_wait(chan, vms->fn); 09689 } 09690 } 09691 return cmd; 09692 }
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 9570 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().
09571 { 09572 int cmd = 0; 09573 09574 if (vms->lastmsg > -1) { 09575 cmd = play_message(chan, vmu, vms); 09576 } else { 09577 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09578 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09579 if (!cmd) { 09580 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09581 cmd = ast_play_and_wait(chan, vms->fn); 09582 } 09583 if (!cmd) 09584 cmd = ast_play_and_wait(chan, "vm-messages"); 09585 } else { 09586 if (!cmd) 09587 cmd = ast_play_and_wait(chan, "vm-messages"); 09588 if (!cmd) { 09589 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09590 cmd = ast_play_and_wait(chan, vms->fn); 09591 } 09592 } 09593 } 09594 return cmd; 09595 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9598 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().
09599 { 09600 int cmd = 0; 09601 09602 if (vms->lastmsg > -1) { 09603 cmd = play_message(chan, vmu, vms); 09604 } else { 09605 if (!strcasecmp(vms->fn, "INBOX")) { 09606 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09607 } else { 09608 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09609 } 09610 } 09611 return cmd; 09612 }
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 9650 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().
09651 { 09652 int cmd; 09653 09654 if (vms->lastmsg > -1) { 09655 cmd = play_message(chan, vmu, vms); 09656 } else { 09657 cmd = ast_play_and_wait(chan, "vm-no"); 09658 if (!cmd) 09659 cmd = ast_play_and_wait(chan, "vm-message"); 09660 if (!cmd) { 09661 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09662 cmd = ast_play_and_wait(chan, vms->fn); 09663 } 09664 } 09665 return cmd; 09666 }
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 9702 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().
09703 { 09704 int cmd; 09705 09706 if (vms->lastmsg > -1) { 09707 cmd = play_message(chan, vmu, vms); 09708 } else { 09709 cmd = ast_play_and_wait(chan, "vm-no"); 09710 if (!cmd) { 09711 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09712 cmd = ast_play_and_wait(chan, vms->fn); 09713 } 09714 if (!cmd) 09715 cmd = ast_play_and_wait(chan, "vm-messages"); 09716 } 09717 return cmd; 09718 }
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 9756 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().
09757 { 09758 int cmd = 0; 09759 09760 if (vms->lastmsg > -1) { 09761 cmd = play_message(chan, vmu, vms); 09762 } else { 09763 cmd = ast_play_and_wait(chan, "vm-no"); 09764 if (!cmd) { 09765 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09766 cmd = ast_play_and_wait(chan, vms->fn); 09767 } 09768 } 09769 return cmd; 09770 }
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 9728 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().
09729 { 09730 int cmd; 09731 09732 if (vms->lastmsg > -1) { 09733 cmd = play_message(chan, vmu, vms); 09734 } else { 09735 cmd = ast_play_and_wait(chan, "vm-you"); 09736 if (!cmd) 09737 cmd = ast_play_and_wait(chan, "vm-haveno"); 09738 if (!cmd) 09739 cmd = ast_play_and_wait(chan, "vm-messages"); 09740 if (!cmd) { 09741 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09742 cmd = ast_play_and_wait(chan, vms->fn); 09743 } 09744 } 09745 return cmd; 09746 }
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 1499 of file app_voicemail_odbcstorage.c.
References ast_alloca, ast_category_browse(), ast_category_get(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_copy_string(), ast_debug, ast_free, ast_log(), AST_LOG_WARNING, ast_test_suite_event_notify, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), valid_config(), value, var, VOICEMAIL_CONFIG, and write_password_to_file().
Referenced by vm_newuser(), and vm_options().
01500 { 01501 struct ast_config *cfg = NULL; 01502 struct ast_variable *var = NULL; 01503 struct ast_category *cat = NULL; 01504 char *category = NULL, *value = NULL, *new = NULL; 01505 const char *tmp = NULL; 01506 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01507 char secretfn[PATH_MAX] = ""; 01508 int found = 0; 01509 01510 if (!change_password_realtime(vmu, newpassword)) 01511 return; 01512 01513 /* check if we should store the secret in the spool directory next to the messages */ 01514 switch (vmu->passwordlocation) { 01515 case OPT_PWLOC_SPOOLDIR: 01516 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01517 if (write_password_to_file(secretfn, newpassword) == 0) { 01518 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01519 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01520 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01521 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01522 break; 01523 } else { 01524 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01525 } 01526 /* Fall-through */ 01527 case OPT_PWLOC_VOICEMAILCONF: 01528 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && valid_config(cfg)) { 01529 while ((category = ast_category_browse(cfg, category))) { 01530 if (!strcasecmp(category, vmu->context)) { 01531 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01532 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01533 break; 01534 } 01535 value = strstr(tmp, ","); 01536 if (!value) { 01537 new = ast_alloca(strlen(newpassword)+1); 01538 sprintf(new, "%s", newpassword); 01539 } else { 01540 new = ast_alloca((strlen(value) + strlen(newpassword) + 1)); 01541 sprintf(new, "%s%s", newpassword, value); 01542 } 01543 if (!(cat = ast_category_get(cfg, category))) { 01544 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01545 break; 01546 } 01547 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01548 found = 1; 01549 } 01550 } 01551 /* save the results */ 01552 if (found) { 01553 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01554 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01555 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01556 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01557 ast_config_destroy(cfg); 01558 break; 01559 } 01560 01561 ast_config_destroy(cfg); 01562 } 01563 /* Fall-through */ 01564 case OPT_PWLOC_USERSCONF: 01565 /* check users.conf and update the password stored for the mailbox */ 01566 /* if no vmsecret entry exists create one. */ 01567 if ((cfg = ast_config_load("users.conf", config_flags)) && valid_config(cfg)) { 01568 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01569 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01570 ast_debug(4, "users.conf: %s\n", category); 01571 if (!strcasecmp(category, vmu->mailbox)) { 01572 if (!ast_variable_retrieve(cfg, category, "vmsecret")) { 01573 ast_debug(3, "looks like we need to make vmsecret!\n"); 01574 var = ast_variable_new("vmsecret", newpassword, ""); 01575 } else { 01576 var = NULL; 01577 } 01578 new = ast_alloca(strlen(newpassword) + 1); 01579 sprintf(new, "%s", newpassword); 01580 if (!(cat = ast_category_get(cfg, category))) { 01581 ast_debug(4, "failed to get category!\n"); 01582 ast_free(var); 01583 break; 01584 } 01585 if (!var) { 01586 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01587 } else { 01588 ast_variable_append(cat, var); 01589 } 01590 found = 1; 01591 break; 01592 } 01593 } 01594 /* save the results and clean things up */ 01595 if (found) { 01596 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01597 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01598 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01599 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01600 } 01601 01602 ast_config_destroy(cfg); 01603 } 01604 } 01605 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1607 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().
01608 { 01609 char buf[255]; 01610 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01611 ast_debug(1, "External password: %s\n",buf); 01612 if (!ast_safe_system(buf)) { 01613 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01614 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01615 /* Reset the password in memory, too */ 01616 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01617 } 01618 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1162 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().
01163 { 01164 int fds[2], pid = 0; 01165 01166 memset(buf, 0, len); 01167 01168 if (pipe(fds)) { 01169 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01170 } else { 01171 /* good to go*/ 01172 pid = ast_safe_fork(0); 01173 01174 if (pid < 0) { 01175 /* ok maybe not */ 01176 close(fds[0]); 01177 close(fds[1]); 01178 snprintf(buf, len, "FAILURE: Fork failed"); 01179 } else if (pid) { 01180 /* parent */ 01181 close(fds[1]); 01182 if (read(fds[0], buf, len) < 0) { 01183 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01184 } 01185 close(fds[0]); 01186 } else { 01187 /* child */ 01188 AST_DECLARE_APP_ARGS(arg, 01189 AST_APP_ARG(v)[20]; 01190 ); 01191 char *mycmd = ast_strdupa(command); 01192 01193 close(fds[0]); 01194 dup2(fds[1], STDOUT_FILENO); 01195 close(fds[1]); 01196 ast_close_fds_above_n(STDOUT_FILENO); 01197 01198 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01199 01200 execv(arg.v[0], arg.v); 01201 printf("FAILURE: %s", strerror(errno)); 01202 _exit(0); 01203 } 01204 } 01205 return buf; 01206 }
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 4210 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().
04211 { 04212 char *txt; 04213 int txtsize = 0; 04214 04215 txtsize = (strlen(file) + 5)*sizeof(char); 04216 txt = ast_alloca(txtsize); 04217 /* Sprintf here would safe because we alloca'd exactly the right length, 04218 * but trying to eliminate all sprintf's anyhow 04219 */ 04220 if (ast_check_realtime("voicemail_data")) { 04221 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04222 } 04223 snprintf(txt, txtsize, "%s.txt", file); 04224 unlink(txt); 04225 return ast_filedelete(file, NULL); 04226 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10678 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().
10679 { 10680 int res = 0; 10681 char *tmp; 10682 struct leave_vm_options leave_options; 10683 struct ast_flags flags = { 0 }; 10684 char *opts[OPT_ARG_ARRAY_SIZE]; 10685 AST_DECLARE_APP_ARGS(args, 10686 AST_APP_ARG(argv0); 10687 AST_APP_ARG(argv1); 10688 ); 10689 10690 memset(&leave_options, 0, sizeof(leave_options)); 10691 10692 if (chan->_state != AST_STATE_UP) 10693 ast_answer(chan); 10694 10695 if (!ast_strlen_zero(data)) { 10696 tmp = ast_strdupa(data); 10697 AST_STANDARD_APP_ARGS(args, tmp); 10698 if (args.argc == 2) { 10699 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10700 return -1; 10701 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10702 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10703 int gain; 10704 10705 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10706 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10707 return -1; 10708 } else { 10709 leave_options.record_gain = (signed char) gain; 10710 } 10711 } 10712 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10713 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10714 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10715 } 10716 } 10717 } else { 10718 char temp[256]; 10719 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10720 if (res < 0) 10721 return res; 10722 if (ast_strlen_zero(temp)) 10723 return 0; 10724 args.argv0 = ast_strdupa(temp); 10725 } 10726 10727 res = leave_voicemail(chan, args.argv0, &leave_options); 10728 if (res == 't') { 10729 ast_play_and_wait(chan, "vm-goodbye"); 10730 res = 0; 10731 } 10732 10733 if (res == OPERATOR_EXIT) { 10734 res = 0; 10735 } 10736 10737 if (res == ERROR_LOCK_PATH) { 10738 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10739 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10740 res = 0; 10741 } 10742 10743 return res; 10744 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9926 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().
09927 { 09928 /* XXX This is, admittedly, some pretty horrendous code. For some 09929 reason it just seemed a lot easier to do with GOTO's. I feel 09930 like I'm back in my GWBASIC days. XXX */ 09931 int res = -1; 09932 int cmd = 0; 09933 int valid = 0; 09934 char prefixstr[80] =""; 09935 char ext_context[256]=""; 09936 int box; 09937 int useadsi = 0; 09938 int skipuser = 0; 09939 struct vm_state vms; 09940 struct ast_vm_user *vmu = NULL, vmus; 09941 char *context = NULL; 09942 int silentexit = 0; 09943 struct ast_flags flags = { 0 }; 09944 signed char record_gain = 0; 09945 int play_auto = 0; 09946 int play_folder = 0; 09947 int in_urgent = 0; 09948 #ifdef IMAP_STORAGE 09949 int deleted = 0; 09950 #endif 09951 09952 /* Add the vm_state to the active list and keep it active */ 09953 memset(&vms, 0, sizeof(vms)); 09954 09955 vms.lastmsg = -1; 09956 09957 memset(&vmus, 0, sizeof(vmus)); 09958 09959 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09960 if (chan->_state != AST_STATE_UP) { 09961 ast_debug(1, "Before ast_answer\n"); 09962 ast_answer(chan); 09963 } 09964 09965 if (!ast_strlen_zero(data)) { 09966 char *opts[OPT_ARG_ARRAY_SIZE]; 09967 char *parse; 09968 AST_DECLARE_APP_ARGS(args, 09969 AST_APP_ARG(argv0); 09970 AST_APP_ARG(argv1); 09971 ); 09972 09973 parse = ast_strdupa(data); 09974 09975 AST_STANDARD_APP_ARGS(args, parse); 09976 09977 if (args.argc == 2) { 09978 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09979 return -1; 09980 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09981 int gain; 09982 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09983 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09984 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09985 return -1; 09986 } else { 09987 record_gain = (signed char) gain; 09988 } 09989 } else { 09990 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09991 } 09992 } 09993 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09994 play_auto = 1; 09995 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09996 /* See if it is a folder name first */ 09997 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09998 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09999 play_folder = -1; 10000 } 10001 } else { 10002 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 10003 } 10004 } else { 10005 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 10006 } 10007 if (play_folder > 9 || play_folder < 0) { 10008 ast_log(AST_LOG_WARNING, 10009 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 10010 opts[OPT_ARG_PLAYFOLDER]); 10011 play_folder = 0; 10012 } 10013 } 10014 } else { 10015 /* old style options parsing */ 10016 while (*(args.argv0)) { 10017 if (*(args.argv0) == 's') 10018 ast_set_flag(&flags, OPT_SILENT); 10019 else if (*(args.argv0) == 'p') 10020 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10021 else 10022 break; 10023 (args.argv0)++; 10024 } 10025 10026 } 10027 10028 valid = ast_test_flag(&flags, OPT_SILENT); 10029 10030 if ((context = strchr(args.argv0, '@'))) 10031 *context++ = '\0'; 10032 10033 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10034 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10035 else 10036 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10037 10038 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10039 skipuser++; 10040 else 10041 valid = 0; 10042 } 10043 10044 if (!valid) 10045 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10046 10047 ast_debug(1, "After vm_authenticate\n"); 10048 10049 if (vms.username[0] == '*') { 10050 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10051 10052 /* user entered '*' */ 10053 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10054 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10055 res = 0; /* prevent hangup */ 10056 goto out; 10057 } 10058 } 10059 10060 if (!res) { 10061 valid = 1; 10062 if (!skipuser) 10063 vmu = &vmus; 10064 } else { 10065 res = 0; 10066 } 10067 10068 /* If ADSI is supported, setup login screen */ 10069 adsi_begin(chan, &useadsi); 10070 10071 ast_test_suite_assert(valid); 10072 if (!valid) { 10073 goto out; 10074 } 10075 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10076 10077 #ifdef IMAP_STORAGE 10078 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10079 pthread_setspecific(ts_vmstate.key, &vms); 10080 10081 vms.interactive = 1; 10082 vms.updated = 1; 10083 if (vmu) 10084 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10085 vmstate_insert(&vms); 10086 init_vm_state(&vms); 10087 #endif 10088 10089 /* Set language from config to override channel language */ 10090 if (!ast_strlen_zero(vmu->language)) 10091 ast_string_field_set(chan, language, vmu->language); 10092 10093 /* Retrieve urgent, old and new message counts */ 10094 ast_debug(1, "Before open_mailbox\n"); 10095 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10096 if (res < 0) 10097 goto out; 10098 vms.oldmessages = vms.lastmsg + 1; 10099 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10100 /* check INBOX */ 10101 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10102 if (res < 0) 10103 goto out; 10104 vms.newmessages = vms.lastmsg + 1; 10105 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10106 /* Start in Urgent */ 10107 in_urgent = 1; 10108 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10109 if (res < 0) 10110 goto out; 10111 vms.urgentmessages = vms.lastmsg + 1; 10112 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10113 10114 /* Select proper mailbox FIRST!! */ 10115 if (play_auto) { 10116 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10117 if (vms.urgentmessages) { 10118 in_urgent = 1; 10119 res = open_mailbox(&vms, vmu, 11); 10120 } else { 10121 in_urgent = 0; 10122 res = open_mailbox(&vms, vmu, play_folder); 10123 } 10124 if (res < 0) 10125 goto out; 10126 10127 /* If there are no new messages, inform the user and hangup */ 10128 if (vms.lastmsg == -1) { 10129 in_urgent = 0; 10130 cmd = vm_browse_messages(chan, &vms, vmu); 10131 res = 0; 10132 goto out; 10133 } 10134 } else { 10135 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10136 /* If we only have old messages start here */ 10137 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10138 in_urgent = 0; 10139 play_folder = 1; 10140 if (res < 0) 10141 goto out; 10142 } else if (!vms.urgentmessages && vms.newmessages) { 10143 /* If we have new messages but none are urgent */ 10144 in_urgent = 0; 10145 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10146 if (res < 0) 10147 goto out; 10148 } 10149 } 10150 10151 if (useadsi) 10152 adsi_status(chan, &vms); 10153 res = 0; 10154 10155 /* Check to see if this is a new user */ 10156 if (!strcasecmp(vmu->mailbox, vmu->password) && 10157 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10158 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10159 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10160 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10161 if ((cmd == 't') || (cmd == '#')) { 10162 /* Timeout */ 10163 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10164 res = 0; 10165 goto out; 10166 } else if (cmd < 0) { 10167 /* Hangup */ 10168 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10169 res = -1; 10170 goto out; 10171 } 10172 } 10173 #ifdef IMAP_STORAGE 10174 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10175 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10176 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10177 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10178 } 10179 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10180 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10181 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10182 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10183 } 10184 #endif 10185 10186 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10187 if (play_auto) { 10188 cmd = '1'; 10189 } else { 10190 cmd = vm_intro(chan, vmu, &vms); 10191 } 10192 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10193 10194 vms.repeats = 0; 10195 vms.starting = 1; 10196 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10197 /* Run main menu */ 10198 switch (cmd) { 10199 case '1': /* First message */ 10200 vms.curmsg = 0; 10201 /* Fall through */ 10202 case '5': /* Play current message */ 10203 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10204 cmd = vm_browse_messages(chan, &vms, vmu); 10205 break; 10206 case '2': /* Change folders */ 10207 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10208 if (useadsi) 10209 adsi_folders(chan, 0, "Change to folder..."); 10210 10211 cmd = get_folder2(chan, "vm-changeto", 0); 10212 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10213 if (cmd == '#') { 10214 cmd = 0; 10215 } else if (cmd > 0) { 10216 cmd = cmd - '0'; 10217 res = close_mailbox(&vms, vmu); 10218 if (res == ERROR_LOCK_PATH) 10219 goto out; 10220 /* If folder is not urgent, set in_urgent to zero! */ 10221 if (cmd != 11) in_urgent = 0; 10222 res = open_mailbox(&vms, vmu, cmd); 10223 if (res < 0) 10224 goto out; 10225 play_folder = cmd; 10226 cmd = 0; 10227 } 10228 if (useadsi) 10229 adsi_status2(chan, &vms); 10230 10231 if (!cmd) { 10232 cmd = vm_play_folder_name(chan, vms.vmbox); 10233 } 10234 10235 vms.starting = 1; 10236 vms.curmsg = 0; 10237 break; 10238 case '3': /* Advanced options */ 10239 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10240 cmd = 0; 10241 vms.repeats = 0; 10242 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10243 switch (cmd) { 10244 case '1': /* Reply */ 10245 if (vms.lastmsg > -1 && !vms.starting) { 10246 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10247 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10248 res = cmd; 10249 goto out; 10250 } 10251 } else { 10252 cmd = ast_play_and_wait(chan, "vm-sorry"); 10253 } 10254 cmd = 't'; 10255 break; 10256 case '2': /* Callback */ 10257 if (!vms.starting) 10258 ast_verb(3, "Callback Requested\n"); 10259 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10260 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10261 if (cmd == 9) { 10262 silentexit = 1; 10263 goto out; 10264 } else if (cmd == ERROR_LOCK_PATH) { 10265 res = cmd; 10266 goto out; 10267 } 10268 } else { 10269 cmd = ast_play_and_wait(chan, "vm-sorry"); 10270 } 10271 cmd = 't'; 10272 break; 10273 case '3': /* Envelope */ 10274 if (vms.lastmsg > -1 && !vms.starting) { 10275 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10276 if (cmd == ERROR_LOCK_PATH) { 10277 res = cmd; 10278 goto out; 10279 } 10280 } else { 10281 cmd = ast_play_and_wait(chan, "vm-sorry"); 10282 } 10283 cmd = 't'; 10284 break; 10285 case '4': /* Dialout */ 10286 if (!ast_strlen_zero(vmu->dialout)) { 10287 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10288 if (cmd == 9) { 10289 silentexit = 1; 10290 goto out; 10291 } 10292 } else { 10293 cmd = ast_play_and_wait(chan, "vm-sorry"); 10294 } 10295 cmd = 't'; 10296 break; 10297 10298 case '5': /* Leave VoiceMail */ 10299 if (ast_test_flag(vmu, VM_SVMAIL)) { 10300 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10301 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10302 res = cmd; 10303 goto out; 10304 } 10305 } else { 10306 cmd = ast_play_and_wait(chan, "vm-sorry"); 10307 } 10308 cmd = 't'; 10309 break; 10310 10311 case '*': /* Return to main menu */ 10312 cmd = 't'; 10313 break; 10314 10315 default: 10316 cmd = 0; 10317 if (!vms.starting) { 10318 cmd = ast_play_and_wait(chan, "vm-toreply"); 10319 } 10320 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10321 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10322 } 10323 if (!cmd && !vms.starting) { 10324 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10325 } 10326 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10327 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10328 } 10329 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10330 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10331 } 10332 if (!cmd) { 10333 cmd = ast_play_and_wait(chan, "vm-starmain"); 10334 } 10335 if (!cmd) { 10336 cmd = ast_waitfordigit(chan, 6000); 10337 } 10338 if (!cmd) { 10339 vms.repeats++; 10340 } 10341 if (vms.repeats > 3) { 10342 cmd = 't'; 10343 } 10344 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10345 } 10346 } 10347 if (cmd == 't') { 10348 cmd = 0; 10349 vms.repeats = 0; 10350 } 10351 break; 10352 case '4': /* Go to the previous 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 > 0) { 10355 vms.curmsg--; 10356 cmd = play_message(chan, vmu, &vms); 10357 } else { 10358 /* Check if we were listening to new 10359 messages. If so, go to Urgent messages 10360 instead of saying "no more messages" 10361 */ 10362 if (in_urgent == 0 && vms.urgentmessages > 0) { 10363 /* Check for Urgent messages */ 10364 in_urgent = 1; 10365 res = close_mailbox(&vms, vmu); 10366 if (res == ERROR_LOCK_PATH) 10367 goto out; 10368 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10369 if (res < 0) 10370 goto out; 10371 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10372 vms.curmsg = vms.lastmsg; 10373 if (vms.lastmsg < 0) { 10374 cmd = ast_play_and_wait(chan, "vm-nomore"); 10375 } 10376 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10377 vms.curmsg = vms.lastmsg; 10378 cmd = play_message(chan, vmu, &vms); 10379 } else { 10380 cmd = ast_play_and_wait(chan, "vm-nomore"); 10381 } 10382 } 10383 break; 10384 case '6': /* Go to the next message */ 10385 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10386 if (vms.curmsg < vms.lastmsg) { 10387 vms.curmsg++; 10388 cmd = play_message(chan, vmu, &vms); 10389 } else { 10390 if (in_urgent && vms.newmessages > 0) { 10391 /* Check if we were listening to urgent 10392 * messages. If so, go to regular new messages 10393 * instead of saying "no more messages" 10394 */ 10395 in_urgent = 0; 10396 res = close_mailbox(&vms, vmu); 10397 if (res == ERROR_LOCK_PATH) 10398 goto out; 10399 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10400 if (res < 0) 10401 goto out; 10402 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10403 vms.curmsg = -1; 10404 if (vms.lastmsg < 0) { 10405 cmd = ast_play_and_wait(chan, "vm-nomore"); 10406 } 10407 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10408 vms.curmsg = 0; 10409 cmd = play_message(chan, vmu, &vms); 10410 } else { 10411 cmd = ast_play_and_wait(chan, "vm-nomore"); 10412 } 10413 } 10414 break; 10415 case '7': /* Delete the current message */ 10416 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10417 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10418 if (useadsi) 10419 adsi_delete(chan, &vms); 10420 if (vms.deleted[vms.curmsg]) { 10421 if (play_folder == 0) { 10422 if (in_urgent) { 10423 vms.urgentmessages--; 10424 } else { 10425 vms.newmessages--; 10426 } 10427 } 10428 else if (play_folder == 1) 10429 vms.oldmessages--; 10430 cmd = ast_play_and_wait(chan, "vm-deleted"); 10431 } else { 10432 if (play_folder == 0) { 10433 if (in_urgent) { 10434 vms.urgentmessages++; 10435 } else { 10436 vms.newmessages++; 10437 } 10438 } 10439 else if (play_folder == 1) 10440 vms.oldmessages++; 10441 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10442 } 10443 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10444 if (vms.curmsg < vms.lastmsg) { 10445 vms.curmsg++; 10446 cmd = play_message(chan, vmu, &vms); 10447 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10448 vms.curmsg = 0; 10449 cmd = play_message(chan, vmu, &vms); 10450 } else { 10451 /* Check if we were listening to urgent 10452 messages. If so, go to regular new messages 10453 instead of saying "no more messages" 10454 */ 10455 if (in_urgent == 1) { 10456 /* Check for new messages */ 10457 in_urgent = 0; 10458 res = close_mailbox(&vms, vmu); 10459 if (res == ERROR_LOCK_PATH) 10460 goto out; 10461 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10462 if (res < 0) 10463 goto out; 10464 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10465 vms.curmsg = -1; 10466 if (vms.lastmsg < 0) { 10467 cmd = ast_play_and_wait(chan, "vm-nomore"); 10468 } 10469 } else { 10470 cmd = ast_play_and_wait(chan, "vm-nomore"); 10471 } 10472 } 10473 } 10474 } else /* Delete not valid if we haven't selected a message */ 10475 cmd = 0; 10476 #ifdef IMAP_STORAGE 10477 deleted = 1; 10478 #endif 10479 break; 10480 10481 case '8': /* Forward the current message */ 10482 if (vms.lastmsg > -1) { 10483 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10484 if (cmd == ERROR_LOCK_PATH) { 10485 res = cmd; 10486 goto out; 10487 } 10488 } else { 10489 /* Check if we were listening to urgent 10490 messages. If so, go to regular new messages 10491 instead of saying "no more messages" 10492 */ 10493 if (in_urgent == 1 && vms.newmessages > 0) { 10494 /* Check for new messages */ 10495 in_urgent = 0; 10496 res = close_mailbox(&vms, vmu); 10497 if (res == ERROR_LOCK_PATH) 10498 goto out; 10499 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10500 if (res < 0) 10501 goto out; 10502 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10503 vms.curmsg = -1; 10504 if (vms.lastmsg < 0) { 10505 cmd = ast_play_and_wait(chan, "vm-nomore"); 10506 } 10507 } else { 10508 cmd = ast_play_and_wait(chan, "vm-nomore"); 10509 } 10510 } 10511 break; 10512 case '9': /* Save message to folder */ 10513 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10514 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10515 /* No message selected */ 10516 cmd = 0; 10517 break; 10518 } 10519 if (useadsi) 10520 adsi_folders(chan, 1, "Save to folder..."); 10521 cmd = get_folder2(chan, "vm-savefolder", 1); 10522 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10523 box = 0; /* Shut up compiler */ 10524 if (cmd == '#') { 10525 cmd = 0; 10526 break; 10527 } else if (cmd > 0) { 10528 box = cmd = cmd - '0'; 10529 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10530 if (cmd == ERROR_LOCK_PATH) { 10531 res = cmd; 10532 goto out; 10533 #ifndef IMAP_STORAGE 10534 } else if (!cmd) { 10535 vms.deleted[vms.curmsg] = 1; 10536 #endif 10537 } else { 10538 vms.deleted[vms.curmsg] = 0; 10539 vms.heard[vms.curmsg] = 0; 10540 } 10541 } 10542 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10543 if (useadsi) 10544 adsi_message(chan, &vms); 10545 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10546 if (!cmd) { 10547 cmd = ast_play_and_wait(chan, "vm-message"); 10548 if (!cmd) 10549 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10550 if (!cmd) 10551 cmd = ast_play_and_wait(chan, "vm-savedto"); 10552 if (!cmd) 10553 cmd = vm_play_folder_name(chan, vms.fn); 10554 } else { 10555 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10556 } 10557 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10558 if (vms.curmsg < vms.lastmsg) { 10559 vms.curmsg++; 10560 cmd = play_message(chan, vmu, &vms); 10561 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10562 vms.curmsg = 0; 10563 cmd = play_message(chan, vmu, &vms); 10564 } else { 10565 /* Check if we were listening to urgent 10566 messages. If so, go to regular new messages 10567 instead of saying "no more messages" 10568 */ 10569 if (in_urgent == 1 && vms.newmessages > 0) { 10570 /* Check for new messages */ 10571 in_urgent = 0; 10572 res = close_mailbox(&vms, vmu); 10573 if (res == ERROR_LOCK_PATH) 10574 goto out; 10575 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10576 if (res < 0) 10577 goto out; 10578 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10579 vms.curmsg = -1; 10580 if (vms.lastmsg < 0) { 10581 cmd = ast_play_and_wait(chan, "vm-nomore"); 10582 } 10583 } else { 10584 cmd = ast_play_and_wait(chan, "vm-nomore"); 10585 } 10586 } 10587 } 10588 break; 10589 case '*': /* Help */ 10590 if (!vms.starting) { 10591 cmd = ast_play_and_wait(chan, "vm-onefor"); 10592 if (!strncasecmp(chan->language, "he", 2)) { 10593 cmd = ast_play_and_wait(chan, "vm-for"); 10594 } 10595 if (!cmd) 10596 cmd = vm_play_folder_name(chan, vms.vmbox); 10597 if (!cmd) 10598 cmd = ast_play_and_wait(chan, "vm-opts"); 10599 if (!cmd) 10600 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10601 } else 10602 cmd = 0; 10603 break; 10604 case '0': /* Mailbox options */ 10605 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10606 if (useadsi) 10607 adsi_status(chan, &vms); 10608 break; 10609 default: /* Nothing */ 10610 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10611 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10612 break; 10613 } 10614 } 10615 if ((cmd == 't') || (cmd == '#')) { 10616 /* Timeout */ 10617 res = 0; 10618 } else { 10619 /* Hangup */ 10620 res = -1; 10621 } 10622 10623 out: 10624 if (res > -1) { 10625 ast_stopstream(chan); 10626 adsi_goodbye(chan); 10627 if (valid && res != OPERATOR_EXIT) { 10628 if (silentexit) 10629 res = ast_play_and_wait(chan, "vm-dialout"); 10630 else 10631 res = ast_play_and_wait(chan, "vm-goodbye"); 10632 } 10633 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10634 res = 0; 10635 } 10636 if (useadsi) 10637 ast_adsi_unload_session(chan); 10638 } 10639 if (vmu) 10640 close_mailbox(&vms, vmu); 10641 if (valid) { 10642 int new = 0, old = 0, urgent = 0; 10643 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10644 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10645 /* Urgent flag not passwd to externnotify here */ 10646 run_externnotify(vmu->context, vmu->mailbox, NULL); 10647 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10648 queue_mwi_event(ext_context, urgent, new, old); 10649 } 10650 #ifdef IMAP_STORAGE 10651 /* expunge message - use UID Expunge if supported on IMAP server*/ 10652 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10653 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10654 ast_mutex_lock(&vms.lock); 10655 #ifdef HAVE_IMAP_TK2006 10656 if (LEVELUIDPLUS (vms.mailstream)) { 10657 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10658 } else 10659 #endif 10660 mail_expunge(vms.mailstream); 10661 ast_mutex_unlock(&vms.lock); 10662 } 10663 /* before we delete the state, we should copy pertinent info 10664 * back to the persistent model */ 10665 if (vmu) { 10666 vmstate_delete(&vms); 10667 } 10668 #endif 10669 if (vmu) 10670 free_user(vmu); 10671 10672 #ifdef IMAP_STORAGE 10673 pthread_setspecific(ts_vmstate.key, NULL); 10674 #endif 10675 return res; 10676 }
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 6891 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, copy(), INTRO, make_file(), ast_vm_user::maxsecs, play_record_review(), and valid_config().
Referenced by forward_message().
06893 { 06894 int cmd = 0; 06895 int retries = 0, prepend_duration = 0, already_recorded = 0; 06896 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06897 char textfile[PATH_MAX]; 06898 struct ast_config *msg_cfg; 06899 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06900 #ifndef IMAP_STORAGE 06901 signed char zero_gain = 0; 06902 #endif 06903 const char *duration_str; 06904 06905 /* Must always populate duration correctly */ 06906 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06907 strcpy(textfile, msgfile); 06908 strcpy(backup, msgfile); 06909 strcpy(backup_textfile, msgfile); 06910 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06911 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06912 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06913 06914 if ((msg_cfg = ast_config_load(textfile, config_flags)) && valid_config(msg_cfg) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06915 *duration = atoi(duration_str); 06916 } else { 06917 *duration = 0; 06918 } 06919 06920 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06921 if (cmd) 06922 retries = 0; 06923 switch (cmd) { 06924 case '1': 06925 06926 #ifdef IMAP_STORAGE 06927 /* Record new intro file */ 06928 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06929 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06930 ast_play_and_wait(chan, INTRO); 06931 ast_play_and_wait(chan, "beep"); 06932 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06933 if (cmd == -1) { 06934 break; 06935 } 06936 cmd = 't'; 06937 #else 06938 06939 /* prepend a message to the current message, update the metadata and return */ 06940 06941 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06942 strcpy(textfile, msgfile); 06943 strncat(textfile, ".txt", sizeof(textfile) - 1); 06944 *duration = 0; 06945 06946 /* if we can't read the message metadata, stop now */ 06947 if (!valid_config(msg_cfg)) { 06948 cmd = 0; 06949 break; 06950 } 06951 06952 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06953 #ifndef IMAP_STORAGE 06954 if (already_recorded) { 06955 ast_filecopy(backup, msgfile, NULL); 06956 copy(backup_textfile, textfile); 06957 } 06958 else { 06959 ast_filecopy(msgfile, backup, NULL); 06960 copy(textfile, backup_textfile); 06961 } 06962 #endif 06963 already_recorded = 1; 06964 06965 if (record_gain) 06966 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06967 06968 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06969 06970 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06971 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06972 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06973 ast_filerename(backup, msgfile, NULL); 06974 } 06975 06976 if (record_gain) 06977 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06978 06979 06980 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06981 *duration = atoi(duration_str); 06982 06983 if (prepend_duration) { 06984 struct ast_category *msg_cat; 06985 /* need enough space for a maximum-length message duration */ 06986 char duration_buf[12]; 06987 06988 *duration += prepend_duration; 06989 msg_cat = ast_category_get(msg_cfg, "message"); 06990 snprintf(duration_buf, 11, "%ld", *duration); 06991 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06992 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06993 } 06994 } 06995 06996 #endif 06997 break; 06998 case '2': 06999 /* NULL out introfile so we know there is no intro! */ 07000 #ifdef IMAP_STORAGE 07001 *vms->introfn = '\0'; 07002 #endif 07003 cmd = 't'; 07004 break; 07005 case '*': 07006 cmd = '*'; 07007 break; 07008 default: 07009 /* If time_out and return to menu, reset already_recorded */ 07010 already_recorded = 0; 07011 07012 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 07013 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 07014 if (!cmd) { 07015 cmd = ast_play_and_wait(chan, "vm-starmain"); 07016 /* "press star to return to the main menu" */ 07017 } 07018 if (!cmd) { 07019 cmd = ast_waitfordigit(chan, 6000); 07020 } 07021 if (!cmd) { 07022 retries++; 07023 } 07024 if (retries > 3) { 07025 cmd = '*'; /* Let's cancel this beast */ 07026 } 07027 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07028 } 07029 } 07030 07031 if (valid_config(msg_cfg)) 07032 ast_config_destroy(msg_cfg); 07033 if (prepend_duration) 07034 *duration = prepend_duration; 07035 07036 if (already_recorded && cmd == -1) { 07037 /* restore original message if prepention cancelled */ 07038 ast_filerename(backup, msgfile, NULL); 07039 rename(backup_textfile, textfile); 07040 } 07041 07042 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07043 cmd = 0; 07044 return cmd; 07045 }
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 9245 of file app_voicemail_odbcstorage.c.
References vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09246 { 09247 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09248 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09249 } else { /* Default to ENGLISH */ 09250 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09251 } 09252 }
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 9133 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().
09134 { 09135 int res = 0; 09136 /* Play instructions and wait for new command */ 09137 while (!res) { 09138 if (vms->starting) { 09139 if (vms->lastmsg > -1) { 09140 if (skipadvanced) 09141 res = ast_play_and_wait(chan, "vm-onefor-full"); 09142 else 09143 res = ast_play_and_wait(chan, "vm-onefor"); 09144 if (!res) 09145 res = vm_play_folder_name(chan, vms->vmbox); 09146 } 09147 if (!res) { 09148 if (skipadvanced) 09149 res = ast_play_and_wait(chan, "vm-opts-full"); 09150 else 09151 res = ast_play_and_wait(chan, "vm-opts"); 09152 } 09153 } else { 09154 /* Added for additional help */ 09155 if (skipadvanced) { 09156 res = ast_play_and_wait(chan, "vm-onefor-full"); 09157 if (!res) 09158 res = vm_play_folder_name(chan, vms->vmbox); 09159 res = ast_play_and_wait(chan, "vm-opts-full"); 09160 } 09161 /* Logic: 09162 * If the current message is not the first OR 09163 * if we're listening to the first new message and there are 09164 * also urgent messages, then prompt for navigation to the 09165 * previous message 09166 */ 09167 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09168 res = ast_play_and_wait(chan, "vm-prev"); 09169 } 09170 if (!res && !skipadvanced) 09171 res = ast_play_and_wait(chan, "vm-advopts"); 09172 if (!res) 09173 res = ast_play_and_wait(chan, "vm-repeat"); 09174 /* Logic: 09175 * If we're not listening to the last message OR 09176 * we're listening to the last urgent message and there are 09177 * also new non-urgent messages, then prompt for navigation 09178 * to the next message 09179 */ 09180 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09181 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09182 res = ast_play_and_wait(chan, "vm-next"); 09183 } 09184 if (!res) { 09185 int curmsg_deleted; 09186 #ifdef IMAP_STORAGE 09187 ast_mutex_lock(&vms->lock); 09188 #endif 09189 curmsg_deleted = vms->deleted[vms->curmsg]; 09190 #ifdef IMAP_STORAGE 09191 ast_mutex_unlock(&vms->lock); 09192 #endif 09193 if (!curmsg_deleted) { 09194 res = ast_play_and_wait(chan, "vm-delete"); 09195 } else { 09196 res = ast_play_and_wait(chan, "vm-undelete"); 09197 } 09198 if (!res) { 09199 res = ast_play_and_wait(chan, "vm-toforward"); 09200 } 09201 if (!res) { 09202 res = ast_play_and_wait(chan, "vm-savemessage"); 09203 } 09204 } 09205 } 09206 if (!res) { 09207 res = ast_play_and_wait(chan, "vm-helpexit"); 09208 } 09209 if (!res) 09210 res = ast_waitfordigit(chan, 6000); 09211 if (!res) { 09212 vms->repeats++; 09213 if (vms->repeats > 2) { 09214 res = 't'; 09215 } 09216 } 09217 } 09218 return res; 09219 }
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 9221 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().
09222 { 09223 int res = 0; 09224 /* Play instructions and wait for new command */ 09225 while (!res) { 09226 if (vms->lastmsg > -1) { 09227 res = ast_play_and_wait(chan, "vm-listen"); 09228 if (!res) 09229 res = vm_play_folder_name(chan, vms->vmbox); 09230 if (!res) 09231 res = ast_play_and_wait(chan, "press"); 09232 if (!res) 09233 res = ast_play_and_wait(chan, "digits/1"); 09234 } 09235 if (!res) 09236 res = ast_play_and_wait(chan, "vm-opts"); 09237 if (!res) { 09238 vms->starting = 0; 09239 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09240 } 09241 } 09242 return res; 09243 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9071 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().
09072 { 09073 char prefile[256]; 09074 09075 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09076 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09077 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09078 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09079 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09080 ast_play_and_wait(chan, "vm-tempgreetactive"); 09081 } 09082 DISPOSE(prefile, -1); 09083 } 09084 09085 /* Play voicemail intro - syntax is different for different languages */ 09086 if (0) { 09087 return 0; 09088 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09089 return vm_intro_cs(chan, vms); 09090 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09091 static int deprecation_warning = 0; 09092 if (deprecation_warning++ % 10 == 0) { 09093 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09094 } 09095 return vm_intro_cs(chan, vms); 09096 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09097 return vm_intro_de(chan, vms); 09098 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09099 return vm_intro_es(chan, vms); 09100 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09101 return vm_intro_fr(chan, vms); 09102 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09103 return vm_intro_gr(chan, vms); 09104 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09105 return vm_intro_he(chan, vms); 09106 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09107 return vm_intro_it(chan, vms); 09108 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09109 return vm_intro_nl(chan, vms); 09110 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09111 return vm_intro_no(chan, vms); 09112 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09113 return vm_intro_pl(chan, vms); 09114 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09115 return vm_intro_pt_BR(chan, vms); 09116 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09117 return vm_intro_pt(chan, vms); 09118 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09119 return vm_intro_multilang(chan, vms, "n"); 09120 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09121 return vm_intro_se(chan, vms); 09122 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09123 return vm_intro_multilang(chan, vms, "n"); 09124 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09125 return vm_intro_vi(chan, vms); 09126 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09127 return vm_intro_zh(chan, vms); 09128 } else { /* Default to ENGLISH */ 09129 return vm_intro_en(chan, vms); 09130 } 09131 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8941 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().
08942 { 08943 int res; 08944 res = ast_play_and_wait(chan, "vm-youhave"); 08945 if (!res) { 08946 if (vms->newmessages) { 08947 if (vms->newmessages == 1) { 08948 res = ast_play_and_wait(chan, "digits/jednu"); 08949 } else { 08950 res = say_and_wait(chan, vms->newmessages, chan->language); 08951 } 08952 if (!res) { 08953 if ((vms->newmessages == 1)) 08954 res = ast_play_and_wait(chan, "vm-novou"); 08955 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08956 res = ast_play_and_wait(chan, "vm-nove"); 08957 if (vms->newmessages > 4) 08958 res = ast_play_and_wait(chan, "vm-novych"); 08959 } 08960 if (vms->oldmessages && !res) 08961 res = ast_play_and_wait(chan, "vm-and"); 08962 else if (!res) { 08963 if ((vms->newmessages == 1)) 08964 res = ast_play_and_wait(chan, "vm-zpravu"); 08965 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08966 res = ast_play_and_wait(chan, "vm-zpravy"); 08967 if (vms->newmessages > 4) 08968 res = ast_play_and_wait(chan, "vm-zprav"); 08969 } 08970 } 08971 if (!res && vms->oldmessages) { 08972 res = say_and_wait(chan, vms->oldmessages, chan->language); 08973 if (!res) { 08974 if ((vms->oldmessages == 1)) 08975 res = ast_play_and_wait(chan, "vm-starou"); 08976 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08977 res = ast_play_and_wait(chan, "vm-stare"); 08978 if (vms->oldmessages > 4) 08979 res = ast_play_and_wait(chan, "vm-starych"); 08980 } 08981 if (!res) { 08982 if ((vms->oldmessages == 1)) 08983 res = ast_play_and_wait(chan, "vm-zpravu"); 08984 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08985 res = ast_play_and_wait(chan, "vm-zpravy"); 08986 if (vms->oldmessages > 4) 08987 res = ast_play_and_wait(chan, "vm-zprav"); 08988 } 08989 } 08990 if (!res) { 08991 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08992 res = ast_play_and_wait(chan, "vm-no"); 08993 if (!res) 08994 res = ast_play_and_wait(chan, "vm-zpravy"); 08995 } 08996 } 08997 } 08998 return res; 08999 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8637 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().
08638 { 08639 /* Introduce messages they have */ 08640 int res; 08641 res = ast_play_and_wait(chan, "vm-youhave"); 08642 if (!res) { 08643 if (vms->newmessages) { 08644 if ((vms->newmessages == 1)) 08645 res = ast_play_and_wait(chan, "digits/1F"); 08646 else 08647 res = say_and_wait(chan, vms->newmessages, chan->language); 08648 if (!res) 08649 res = ast_play_and_wait(chan, "vm-INBOX"); 08650 if (vms->oldmessages && !res) 08651 res = ast_play_and_wait(chan, "vm-and"); 08652 else if (!res) { 08653 if ((vms->newmessages == 1)) 08654 res = ast_play_and_wait(chan, "vm-message"); 08655 else 08656 res = ast_play_and_wait(chan, "vm-messages"); 08657 } 08658 08659 } 08660 if (!res && vms->oldmessages) { 08661 if (vms->oldmessages == 1) 08662 res = ast_play_and_wait(chan, "digits/1F"); 08663 else 08664 res = say_and_wait(chan, vms->oldmessages, chan->language); 08665 if (!res) 08666 res = ast_play_and_wait(chan, "vm-Old"); 08667 if (!res) { 08668 if (vms->oldmessages == 1) 08669 res = ast_play_and_wait(chan, "vm-message"); 08670 else 08671 res = ast_play_and_wait(chan, "vm-messages"); 08672 } 08673 } 08674 if (!res) { 08675 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08676 res = ast_play_and_wait(chan, "vm-no"); 08677 if (!res) 08678 res = ast_play_and_wait(chan, "vm-messages"); 08679 } 08680 } 08681 } 08682 return res; 08683 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8386 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().
08387 { 08388 int res; 08389 08390 /* Introduce messages they have */ 08391 res = ast_play_and_wait(chan, "vm-youhave"); 08392 if (!res) { 08393 if (vms->urgentmessages) { 08394 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08395 if (!res) 08396 res = ast_play_and_wait(chan, "vm-Urgent"); 08397 if ((vms->oldmessages || vms->newmessages) && !res) { 08398 res = ast_play_and_wait(chan, "vm-and"); 08399 } else if (!res) { 08400 if ((vms->urgentmessages == 1)) 08401 res = ast_play_and_wait(chan, "vm-message"); 08402 else 08403 res = ast_play_and_wait(chan, "vm-messages"); 08404 } 08405 } 08406 if (vms->newmessages) { 08407 res = say_and_wait(chan, vms->newmessages, chan->language); 08408 if (!res) 08409 res = ast_play_and_wait(chan, "vm-INBOX"); 08410 if (vms->oldmessages && !res) 08411 res = ast_play_and_wait(chan, "vm-and"); 08412 else if (!res) { 08413 if ((vms->newmessages == 1)) 08414 res = ast_play_and_wait(chan, "vm-message"); 08415 else 08416 res = ast_play_and_wait(chan, "vm-messages"); 08417 } 08418 08419 } 08420 if (!res && vms->oldmessages) { 08421 res = say_and_wait(chan, vms->oldmessages, chan->language); 08422 if (!res) 08423 res = ast_play_and_wait(chan, "vm-Old"); 08424 if (!res) { 08425 if (vms->oldmessages == 1) 08426 res = ast_play_and_wait(chan, "vm-message"); 08427 else 08428 res = ast_play_and_wait(chan, "vm-messages"); 08429 } 08430 } 08431 if (!res) { 08432 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08433 res = ast_play_and_wait(chan, "vm-no"); 08434 if (!res) 08435 res = ast_play_and_wait(chan, "vm-messages"); 08436 } 08437 } 08438 } 08439 return res; 08440 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8686 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().
08687 { 08688 /* Introduce messages they have */ 08689 int res; 08690 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08691 res = ast_play_and_wait(chan, "vm-youhaveno"); 08692 if (!res) 08693 res = ast_play_and_wait(chan, "vm-messages"); 08694 } else { 08695 res = ast_play_and_wait(chan, "vm-youhave"); 08696 } 08697 if (!res) { 08698 if (vms->newmessages) { 08699 if (!res) { 08700 if ((vms->newmessages == 1)) { 08701 res = ast_play_and_wait(chan, "digits/1M"); 08702 if (!res) 08703 res = ast_play_and_wait(chan, "vm-message"); 08704 if (!res) 08705 res = ast_play_and_wait(chan, "vm-INBOXs"); 08706 } else { 08707 res = say_and_wait(chan, vms->newmessages, chan->language); 08708 if (!res) 08709 res = ast_play_and_wait(chan, "vm-messages"); 08710 if (!res) 08711 res = ast_play_and_wait(chan, "vm-INBOX"); 08712 } 08713 } 08714 if (vms->oldmessages && !res) 08715 res = ast_play_and_wait(chan, "vm-and"); 08716 } 08717 if (vms->oldmessages) { 08718 if (!res) { 08719 if (vms->oldmessages == 1) { 08720 res = ast_play_and_wait(chan, "digits/1M"); 08721 if (!res) 08722 res = ast_play_and_wait(chan, "vm-message"); 08723 if (!res) 08724 res = ast_play_and_wait(chan, "vm-Olds"); 08725 } else { 08726 res = say_and_wait(chan, vms->oldmessages, chan->language); 08727 if (!res) 08728 res = ast_play_and_wait(chan, "vm-messages"); 08729 if (!res) 08730 res = ast_play_and_wait(chan, "vm-Old"); 08731 } 08732 } 08733 } 08734 } 08735 return res; 08736 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8784 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().
08785 { 08786 /* Introduce messages they have */ 08787 int res; 08788 res = ast_play_and_wait(chan, "vm-youhave"); 08789 if (!res) { 08790 if (vms->newmessages) { 08791 res = say_and_wait(chan, vms->newmessages, chan->language); 08792 if (!res) 08793 res = ast_play_and_wait(chan, "vm-INBOX"); 08794 if (vms->oldmessages && !res) 08795 res = ast_play_and_wait(chan, "vm-and"); 08796 else if (!res) { 08797 if ((vms->newmessages == 1)) 08798 res = ast_play_and_wait(chan, "vm-message"); 08799 else 08800 res = ast_play_and_wait(chan, "vm-messages"); 08801 } 08802 08803 } 08804 if (!res && vms->oldmessages) { 08805 res = say_and_wait(chan, vms->oldmessages, chan->language); 08806 if (!res) 08807 res = ast_play_and_wait(chan, "vm-Old"); 08808 if (!res) { 08809 if (vms->oldmessages == 1) 08810 res = ast_play_and_wait(chan, "vm-message"); 08811 else 08812 res = ast_play_and_wait(chan, "vm-messages"); 08813 } 08814 } 08815 if (!res) { 08816 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08817 res = ast_play_and_wait(chan, "vm-no"); 08818 if (!res) 08819 res = ast_play_and_wait(chan, "vm-messages"); 08820 } 08821 } 08822 } 08823 return res; 08824 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8185 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().
08186 { 08187 int res = 0; 08188 08189 if (vms->newmessages) { 08190 res = ast_play_and_wait(chan, "vm-youhave"); 08191 if (!res) 08192 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08193 if (!res) { 08194 if ((vms->newmessages == 1)) { 08195 res = ast_play_and_wait(chan, "vm-INBOX"); 08196 if (!res) 08197 res = ast_play_and_wait(chan, "vm-message"); 08198 } else { 08199 res = ast_play_and_wait(chan, "vm-INBOXs"); 08200 if (!res) 08201 res = ast_play_and_wait(chan, "vm-messages"); 08202 } 08203 } 08204 } else if (vms->oldmessages){ 08205 res = ast_play_and_wait(chan, "vm-youhave"); 08206 if (!res) 08207 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08208 if ((vms->oldmessages == 1)){ 08209 res = ast_play_and_wait(chan, "vm-Old"); 08210 if (!res) 08211 res = ast_play_and_wait(chan, "vm-message"); 08212 } else { 08213 res = ast_play_and_wait(chan, "vm-Olds"); 08214 if (!res) 08215 res = ast_play_and_wait(chan, "vm-messages"); 08216 } 08217 } else if (!vms->oldmessages && !vms->newmessages) 08218 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08219 return res; 08220 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8319 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().
08320 { 08321 int res = 0; 08322 08323 /* Introduce messages they have */ 08324 if (!res) { 08325 if ((vms->newmessages) || (vms->oldmessages)) { 08326 res = ast_play_and_wait(chan, "vm-youhave"); 08327 } 08328 /* 08329 * The word "shtei" refers to the number 2 in hebrew when performing a count 08330 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08331 * an element, this is one of them. 08332 */ 08333 if (vms->newmessages) { 08334 if (!res) { 08335 if (vms->newmessages == 1) { 08336 res = ast_play_and_wait(chan, "vm-INBOX1"); 08337 } else { 08338 if (vms->newmessages == 2) { 08339 res = ast_play_and_wait(chan, "vm-shtei"); 08340 } else { 08341 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08342 } 08343 res = ast_play_and_wait(chan, "vm-INBOX"); 08344 } 08345 } 08346 if (vms->oldmessages && !res) { 08347 res = ast_play_and_wait(chan, "vm-and"); 08348 if (vms->oldmessages == 1) { 08349 res = ast_play_and_wait(chan, "vm-Old1"); 08350 } else { 08351 if (vms->oldmessages == 2) { 08352 res = ast_play_and_wait(chan, "vm-shtei"); 08353 } else { 08354 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08355 } 08356 res = ast_play_and_wait(chan, "vm-Old"); 08357 } 08358 } 08359 } 08360 if (!res && vms->oldmessages && !vms->newmessages) { 08361 if (!res) { 08362 if (vms->oldmessages == 1) { 08363 res = ast_play_and_wait(chan, "vm-Old1"); 08364 } else { 08365 if (vms->oldmessages == 2) { 08366 res = ast_play_and_wait(chan, "vm-shtei"); 08367 } else { 08368 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08369 } 08370 res = ast_play_and_wait(chan, "vm-Old"); 08371 } 08372 } 08373 } 08374 if (!res) { 08375 if (!vms->oldmessages && !vms->newmessages) { 08376 if (!res) { 08377 res = ast_play_and_wait(chan, "vm-nomessages"); 08378 } 08379 } 08380 } 08381 } 08382 return res; 08383 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8443 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().
08444 { 08445 /* Introduce messages they have */ 08446 int res; 08447 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08448 res = ast_play_and_wait(chan, "vm-no") || 08449 ast_play_and_wait(chan, "vm-message"); 08450 else 08451 res = ast_play_and_wait(chan, "vm-youhave"); 08452 if (!res && vms->newmessages) { 08453 res = (vms->newmessages == 1) ? 08454 ast_play_and_wait(chan, "digits/un") || 08455 ast_play_and_wait(chan, "vm-nuovo") || 08456 ast_play_and_wait(chan, "vm-message") : 08457 /* 2 or more new messages */ 08458 say_and_wait(chan, vms->newmessages, chan->language) || 08459 ast_play_and_wait(chan, "vm-nuovi") || 08460 ast_play_and_wait(chan, "vm-messages"); 08461 if (!res && vms->oldmessages) 08462 res = ast_play_and_wait(chan, "vm-and"); 08463 } 08464 if (!res && vms->oldmessages) { 08465 res = (vms->oldmessages == 1) ? 08466 ast_play_and_wait(chan, "digits/un") || 08467 ast_play_and_wait(chan, "vm-vecchio") || 08468 ast_play_and_wait(chan, "vm-message") : 08469 /* 2 or more old messages */ 08470 say_and_wait(chan, vms->oldmessages, chan->language) || 08471 ast_play_and_wait(chan, "vm-vecchi") || 08472 ast_play_and_wait(chan, "vm-messages"); 08473 } 08474 return res; 08475 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8279 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().
08280 { 08281 int res; 08282 int lastnum = 0; 08283 08284 res = ast_play_and_wait(chan, "vm-youhave"); 08285 08286 if (!res && vms->newmessages) { 08287 lastnum = vms->newmessages; 08288 08289 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08290 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08291 } 08292 08293 if (!res && vms->oldmessages) { 08294 res = ast_play_and_wait(chan, "vm-and"); 08295 } 08296 } 08297 08298 if (!res && vms->oldmessages) { 08299 lastnum = vms->oldmessages; 08300 08301 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08302 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08303 } 08304 } 08305 08306 if (!res) { 08307 if (lastnum == 0) { 08308 res = ast_play_and_wait(chan, "vm-no"); 08309 } 08310 if (!res) { 08311 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08312 } 08313 } 08314 08315 return res; 08316 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8827 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().
08828 { 08829 /* Introduce messages they have */ 08830 int res; 08831 res = ast_play_and_wait(chan, "vm-youhave"); 08832 if (!res) { 08833 if (vms->newmessages) { 08834 res = say_and_wait(chan, vms->newmessages, chan->language); 08835 if (!res) { 08836 if (vms->newmessages == 1) 08837 res = ast_play_and_wait(chan, "vm-INBOXs"); 08838 else 08839 res = ast_play_and_wait(chan, "vm-INBOX"); 08840 } 08841 if (vms->oldmessages && !res) 08842 res = ast_play_and_wait(chan, "vm-and"); 08843 else if (!res) { 08844 if ((vms->newmessages == 1)) 08845 res = ast_play_and_wait(chan, "vm-message"); 08846 else 08847 res = ast_play_and_wait(chan, "vm-messages"); 08848 } 08849 08850 } 08851 if (!res && vms->oldmessages) { 08852 res = say_and_wait(chan, vms->oldmessages, chan->language); 08853 if (!res) { 08854 if (vms->oldmessages == 1) 08855 res = ast_play_and_wait(chan, "vm-Olds"); 08856 else 08857 res = ast_play_and_wait(chan, "vm-Old"); 08858 } 08859 if (!res) { 08860 if (vms->oldmessages == 1) 08861 res = ast_play_and_wait(chan, "vm-message"); 08862 else 08863 res = ast_play_and_wait(chan, "vm-messages"); 08864 } 08865 } 08866 if (!res) { 08867 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08868 res = ast_play_and_wait(chan, "vm-no"); 08869 if (!res) 08870 res = ast_play_and_wait(chan, "vm-messages"); 08871 } 08872 } 08873 } 08874 return res; 08875 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8593 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().
08594 { 08595 /* Introduce messages they have */ 08596 int res; 08597 08598 res = ast_play_and_wait(chan, "vm-youhave"); 08599 if (res) 08600 return res; 08601 08602 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08603 res = ast_play_and_wait(chan, "vm-no"); 08604 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08605 return res; 08606 } 08607 08608 if (vms->newmessages) { 08609 if ((vms->newmessages == 1)) { 08610 res = ast_play_and_wait(chan, "digits/1"); 08611 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08612 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08613 } else { 08614 res = say_and_wait(chan, vms->newmessages, chan->language); 08615 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08616 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08617 } 08618 if (!res && vms->oldmessages) 08619 res = ast_play_and_wait(chan, "vm-and"); 08620 } 08621 if (!res && vms->oldmessages) { 08622 if (vms->oldmessages == 1) { 08623 res = ast_play_and_wait(chan, "digits/1"); 08624 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08625 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08626 } else { 08627 res = say_and_wait(chan, vms->oldmessages, chan->language); 08628 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08629 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08630 } 08631 } 08632 08633 return res; 08634 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8478 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().
08479 { 08480 /* Introduce messages they have */ 08481 int res; 08482 div_t num; 08483 08484 if (!vms->oldmessages && !vms->newmessages) { 08485 res = ast_play_and_wait(chan, "vm-no"); 08486 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08487 return res; 08488 } else { 08489 res = ast_play_and_wait(chan, "vm-youhave"); 08490 } 08491 08492 if (vms->newmessages) { 08493 num = div(vms->newmessages, 10); 08494 if (vms->newmessages == 1) { 08495 res = ast_play_and_wait(chan, "digits/1-a"); 08496 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08497 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08498 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08499 if (num.rem == 2) { 08500 if (!num.quot) { 08501 res = ast_play_and_wait(chan, "digits/2-ie"); 08502 } else { 08503 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08504 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08505 } 08506 } else { 08507 res = say_and_wait(chan, vms->newmessages, chan->language); 08508 } 08509 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08510 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08511 } else { 08512 res = say_and_wait(chan, vms->newmessages, chan->language); 08513 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08514 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08515 } 08516 if (!res && vms->oldmessages) 08517 res = ast_play_and_wait(chan, "vm-and"); 08518 } 08519 if (!res && vms->oldmessages) { 08520 num = div(vms->oldmessages, 10); 08521 if (vms->oldmessages == 1) { 08522 res = ast_play_and_wait(chan, "digits/1-a"); 08523 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08524 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08525 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08526 if (num.rem == 2) { 08527 if (!num.quot) { 08528 res = ast_play_and_wait(chan, "digits/2-ie"); 08529 } else { 08530 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08531 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08532 } 08533 } else { 08534 res = say_and_wait(chan, vms->oldmessages, chan->language); 08535 } 08536 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08537 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08538 } else { 08539 res = say_and_wait(chan, vms->oldmessages, chan->language); 08540 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08541 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08542 } 08543 } 08544 08545 return res; 08546 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8878 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().
08879 { 08880 /* Introduce messages they have */ 08881 int res; 08882 res = ast_play_and_wait(chan, "vm-youhave"); 08883 if (!res) { 08884 if (vms->newmessages) { 08885 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08886 if (!res) { 08887 if ((vms->newmessages == 1)) { 08888 res = ast_play_and_wait(chan, "vm-message"); 08889 if (!res) 08890 res = ast_play_and_wait(chan, "vm-INBOXs"); 08891 } else { 08892 res = ast_play_and_wait(chan, "vm-messages"); 08893 if (!res) 08894 res = ast_play_and_wait(chan, "vm-INBOX"); 08895 } 08896 } 08897 if (vms->oldmessages && !res) 08898 res = ast_play_and_wait(chan, "vm-and"); 08899 } 08900 if (!res && vms->oldmessages) { 08901 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08902 if (!res) { 08903 if (vms->oldmessages == 1) { 08904 res = ast_play_and_wait(chan, "vm-message"); 08905 if (!res) 08906 res = ast_play_and_wait(chan, "vm-Olds"); 08907 } else { 08908 res = ast_play_and_wait(chan, "vm-messages"); 08909 if (!res) 08910 res = ast_play_and_wait(chan, "vm-Old"); 08911 } 08912 } 08913 } 08914 if (!res) { 08915 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08916 res = ast_play_and_wait(chan, "vm-no"); 08917 if (!res) 08918 res = ast_play_and_wait(chan, "vm-messages"); 08919 } 08920 } 08921 } 08922 return res; 08923 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8739 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().
08739 { 08740 /* Introduce messages they have */ 08741 int res; 08742 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08743 res = ast_play_and_wait(chan, "vm-nomessages"); 08744 return res; 08745 } else { 08746 res = ast_play_and_wait(chan, "vm-youhave"); 08747 } 08748 if (vms->newmessages) { 08749 if (!res) 08750 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08751 if ((vms->newmessages == 1)) { 08752 if (!res) 08753 res = ast_play_and_wait(chan, "vm-message"); 08754 if (!res) 08755 res = ast_play_and_wait(chan, "vm-INBOXs"); 08756 } else { 08757 if (!res) 08758 res = ast_play_and_wait(chan, "vm-messages"); 08759 if (!res) 08760 res = ast_play_and_wait(chan, "vm-INBOX"); 08761 } 08762 if (vms->oldmessages && !res) 08763 res = ast_play_and_wait(chan, "vm-and"); 08764 } 08765 if (vms->oldmessages) { 08766 if (!res) 08767 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08768 if (vms->oldmessages == 1) { 08769 if (!res) 08770 res = ast_play_and_wait(chan, "vm-message"); 08771 if (!res) 08772 res = ast_play_and_wait(chan, "vm-Olds"); 08773 } else { 08774 if (!res) 08775 res = ast_play_and_wait(chan, "vm-messages"); 08776 if (!res) 08777 res = ast_play_and_wait(chan, "vm-Old"); 08778 } 08779 } 08780 return res; 08781 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8549 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().
08550 { 08551 /* Introduce messages they have */ 08552 int res; 08553 08554 res = ast_play_and_wait(chan, "vm-youhave"); 08555 if (res) 08556 return res; 08557 08558 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08559 res = ast_play_and_wait(chan, "vm-no"); 08560 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08561 return res; 08562 } 08563 08564 if (vms->newmessages) { 08565 if ((vms->newmessages == 1)) { 08566 res = ast_play_and_wait(chan, "digits/ett"); 08567 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08568 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08569 } else { 08570 res = say_and_wait(chan, vms->newmessages, chan->language); 08571 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08572 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08573 } 08574 if (!res && vms->oldmessages) 08575 res = ast_play_and_wait(chan, "vm-and"); 08576 } 08577 if (!res && vms->oldmessages) { 08578 if (vms->oldmessages == 1) { 08579 res = ast_play_and_wait(chan, "digits/ett"); 08580 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08581 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08582 } else { 08583 res = say_and_wait(chan, vms->oldmessages, chan->language); 08584 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08585 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08586 } 08587 } 08588 08589 return res; 08590 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9041 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().
09042 { 09043 int res; 09044 09045 /* Introduce messages they have */ 09046 res = ast_play_and_wait(chan, "vm-youhave"); 09047 if (!res) { 09048 if (vms->newmessages) { 09049 res = say_and_wait(chan, vms->newmessages, chan->language); 09050 if (!res) 09051 res = ast_play_and_wait(chan, "vm-INBOX"); 09052 if (vms->oldmessages && !res) 09053 res = ast_play_and_wait(chan, "vm-and"); 09054 } 09055 if (!res && vms->oldmessages) { 09056 res = say_and_wait(chan, vms->oldmessages, chan->language); 09057 if (!res) 09058 res = ast_play_and_wait(chan, "vm-Old"); 09059 } 09060 if (!res) { 09061 if (!vms->oldmessages && !vms->newmessages) { 09062 res = ast_play_and_wait(chan, "vm-no"); 09063 if (!res) 09064 res = ast_play_and_wait(chan, "vm-message"); 09065 } 09066 } 09067 } 09068 return res; 09069 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9002 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().
09003 { 09004 int res; 09005 /* Introduce messages they have */ 09006 res = ast_play_and_wait(chan, "vm-you"); 09007 09008 if (!res && vms->newmessages) { 09009 res = ast_play_and_wait(chan, "vm-have"); 09010 if (!res) 09011 res = say_and_wait(chan, vms->newmessages, chan->language); 09012 if (!res) 09013 res = ast_play_and_wait(chan, "vm-tong"); 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 else if (!res) 09019 res = ast_play_and_wait(chan, "vm-messages"); 09020 } 09021 if (!res && vms->oldmessages) { 09022 res = ast_play_and_wait(chan, "vm-have"); 09023 if (!res) 09024 res = say_and_wait(chan, vms->oldmessages, chan->language); 09025 if (!res) 09026 res = ast_play_and_wait(chan, "vm-tong"); 09027 if (!res) 09028 res = ast_play_and_wait(chan, "vm-Old"); 09029 if (!res) 09030 res = ast_play_and_wait(chan, "vm-messages"); 09031 } 09032 if (!res && !vms->oldmessages && !vms->newmessages) { 09033 res = ast_play_and_wait(chan, "vm-haveno"); 09034 if (!res) 09035 res = ast_play_and_wait(chan, "vm-messages"); 09036 } 09037 return res; 09038 }
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 3285 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().
03286 { 03287 switch (ast_lock_path(path)) { 03288 case AST_LOCK_TIMEOUT: 03289 return -1; 03290 default: 03291 return 0; 03292 } 03293 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1656 of file app_voicemail_odbcstorage.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01657 { 01658 FILE *p = NULL; 01659 int pfd = mkstemp(template); 01660 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01661 if (pfd > -1) { 01662 p = fdopen(pfd, "w+"); 01663 if (!p) { 01664 close(pfd); 01665 pfd = -1; 01666 } 01667 } 01668 return p; 01669 }
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 9255 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().
09256 { 09257 int cmd = 0; 09258 int duration = 0; 09259 int tries = 0; 09260 char newpassword[80] = ""; 09261 char newpassword2[80] = ""; 09262 char prefile[PATH_MAX] = ""; 09263 unsigned char buf[256]; 09264 int bytes = 0; 09265 09266 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09267 if (ast_adsi_available(chan)) { 09268 bytes += adsi_logo(buf + bytes); 09269 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09270 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09271 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09272 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09273 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09274 } 09275 09276 /* If forcename is set, have the user record their name */ 09277 if (ast_test_flag(vmu, VM_FORCENAME)) { 09278 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09279 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09280 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09281 if (cmd < 0 || cmd == 't' || cmd == '#') 09282 return cmd; 09283 } 09284 } 09285 09286 /* If forcegreetings is set, have the user record their greetings */ 09287 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09288 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09289 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09290 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09291 if (cmd < 0 || cmd == 't' || cmd == '#') 09292 return cmd; 09293 } 09294 09295 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09296 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09297 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09298 if (cmd < 0 || cmd == 't' || cmd == '#') 09299 return cmd; 09300 } 09301 } 09302 09303 /* 09304 * Change the password last since new users will be able to skip over any steps this one comes before 09305 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09306 */ 09307 for (;;) { 09308 newpassword[1] = '\0'; 09309 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09310 if (cmd == '#') 09311 newpassword[0] = '\0'; 09312 if (cmd < 0 || cmd == 't' || cmd == '#') 09313 return cmd; 09314 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09315 if (cmd < 0 || cmd == 't' || cmd == '#') 09316 return cmd; 09317 cmd = check_password(vmu, newpassword); /* perform password validation */ 09318 if (cmd != 0) { 09319 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09320 cmd = ast_play_and_wait(chan, vm_invalid_password); 09321 } else { 09322 newpassword2[1] = '\0'; 09323 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09324 if (cmd == '#') 09325 newpassword2[0] = '\0'; 09326 if (cmd < 0 || cmd == 't' || cmd == '#') 09327 return cmd; 09328 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09329 if (cmd < 0 || cmd == 't' || cmd == '#') 09330 return cmd; 09331 if (!strcmp(newpassword, newpassword2)) 09332 break; 09333 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09334 cmd = ast_play_and_wait(chan, vm_mismatch); 09335 } 09336 if (++tries == 3) 09337 return -1; 09338 if (cmd != 0) { 09339 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09340 } 09341 } 09342 if (pwdchange & PWDCHANGE_INTERNAL) 09343 vm_change_password(vmu, newpassword); 09344 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09345 vm_change_password_shell(vmu, newpassword); 09346 09347 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09348 cmd = ast_play_and_wait(chan, vm_passchanged); 09349 09350 return cmd; 09351 }
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 9353 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().
09354 { 09355 int cmd = 0; 09356 int retries = 0; 09357 int duration = 0; 09358 char newpassword[80] = ""; 09359 char newpassword2[80] = ""; 09360 char prefile[PATH_MAX] = ""; 09361 unsigned char buf[256]; 09362 int bytes = 0; 09363 09364 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09365 if (ast_adsi_available(chan)) { 09366 bytes += adsi_logo(buf + bytes); 09367 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09368 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09369 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09370 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09371 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09372 } 09373 while ((cmd >= 0) && (cmd != 't')) { 09374 if (cmd) 09375 retries = 0; 09376 switch (cmd) { 09377 case '1': /* Record your unavailable message */ 09378 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09379 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09380 break; 09381 case '2': /* Record your busy message */ 09382 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09383 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09384 break; 09385 case '3': /* Record greeting */ 09386 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09387 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09388 break; 09389 case '4': /* manage the temporary greeting */ 09390 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09391 break; 09392 case '5': /* change password */ 09393 if (vmu->password[0] == '-') { 09394 cmd = ast_play_and_wait(chan, "vm-no"); 09395 break; 09396 } 09397 newpassword[1] = '\0'; 09398 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09399 if (cmd == '#') 09400 newpassword[0] = '\0'; 09401 else { 09402 if (cmd < 0) 09403 break; 09404 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09405 break; 09406 } 09407 } 09408 cmd = check_password(vmu, newpassword); /* perform password validation */ 09409 if (cmd != 0) { 09410 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09411 cmd = ast_play_and_wait(chan, vm_invalid_password); 09412 if (!cmd) { 09413 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09414 } 09415 break; 09416 } 09417 newpassword2[1] = '\0'; 09418 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09419 if (cmd == '#') 09420 newpassword2[0] = '\0'; 09421 else { 09422 if (cmd < 0) 09423 break; 09424 09425 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09426 break; 09427 } 09428 } 09429 if (strcmp(newpassword, newpassword2)) { 09430 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09431 cmd = ast_play_and_wait(chan, vm_mismatch); 09432 if (!cmd) { 09433 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09434 } 09435 break; 09436 } 09437 09438 if (pwdchange & PWDCHANGE_INTERNAL) { 09439 vm_change_password(vmu, newpassword); 09440 } 09441 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09442 vm_change_password_shell(vmu, newpassword); 09443 } 09444 09445 ast_debug(1, "User %s set password to %s of length %d\n", 09446 vms->username, newpassword, (int) strlen(newpassword)); 09447 cmd = ast_play_and_wait(chan, vm_passchanged); 09448 break; 09449 case '*': 09450 cmd = 't'; 09451 break; 09452 default: 09453 cmd = 0; 09454 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09455 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09456 if (ast_fileexists(prefile, NULL, NULL)) { 09457 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09458 } 09459 DISPOSE(prefile, -1); 09460 if (!cmd) { 09461 cmd = ast_play_and_wait(chan, "vm-options"); 09462 } 09463 if (!cmd) { 09464 cmd = ast_waitfordigit(chan, 6000); 09465 } 09466 if (!cmd) { 09467 retries++; 09468 } 09469 if (retries > 3) { 09470 cmd = 't'; 09471 } 09472 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09473 } 09474 } 09475 if (cmd == 't') 09476 cmd = 0; 09477 return cmd; 09478 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8148 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().
08149 { 08150 int cmd; 08151 08152 if ( !strncasecmp(chan->language, "it", 2) || 08153 !strncasecmp(chan->language, "es", 2) || 08154 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08155 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08156 return cmd ? cmd : ast_play_and_wait(chan, box); 08157 } else if (!strncasecmp(chan->language, "gr", 2)) { 08158 return vm_play_folder_name_gr(chan, box); 08159 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08160 return ast_play_and_wait(chan, box); 08161 } else if (!strncasecmp(chan->language, "pl", 2)) { 08162 return vm_play_folder_name_pl(chan, box); 08163 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08164 return vm_play_folder_name_ua(chan, box); 08165 } else if (!strncasecmp(chan->language, "vi", 2)) { 08166 return ast_play_and_wait(chan, box); 08167 } else { /* Default English */ 08168 cmd = ast_play_and_wait(chan, box); 08169 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08170 } 08171 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8101 of file app_voicemail_odbcstorage.c.
References ast_alloca, and ast_play_and_wait().
Referenced by vm_play_folder_name().
08102 { 08103 int cmd; 08104 char *buf; 08105 08106 buf = ast_alloca(strlen(box) + 2); 08107 strcpy(buf, box); 08108 strcat(buf, "s"); 08109 08110 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08111 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08112 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08113 } else { 08114 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08115 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08116 } 08117 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8119 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08120 { 08121 int cmd; 08122 08123 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08124 if (!strcasecmp(box, "vm-INBOX")) 08125 cmd = ast_play_and_wait(chan, "vm-new-e"); 08126 else 08127 cmd = ast_play_and_wait(chan, "vm-old-e"); 08128 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08129 } else { 08130 cmd = ast_play_and_wait(chan, "vm-messages"); 08131 return cmd ? cmd : ast_play_and_wait(chan, box); 08132 } 08133 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8135 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
08136 { 08137 int cmd; 08138 08139 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08140 cmd = ast_play_and_wait(chan, "vm-messages"); 08141 return cmd ? cmd : ast_play_and_wait(chan, box); 08142 } else { 08143 cmd = ast_play_and_wait(chan, box); 08144 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08145 } 08146 }
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 9496 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().
09497 { 09498 int cmd = 0; 09499 int retries = 0; 09500 int duration = 0; 09501 char prefile[PATH_MAX] = ""; 09502 unsigned char buf[256]; 09503 int bytes = 0; 09504 09505 if (ast_adsi_available(chan)) { 09506 bytes += adsi_logo(buf + bytes); 09507 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09508 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09509 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09510 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09511 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09512 } 09513 09514 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09515 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09516 while ((cmd >= 0) && (cmd != 't')) { 09517 if (cmd) 09518 retries = 0; 09519 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09520 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09521 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09522 if (cmd == -1) { 09523 break; 09524 } 09525 cmd = 't'; 09526 } else { 09527 switch (cmd) { 09528 case '1': 09529 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09530 break; 09531 case '2': 09532 DELETE(prefile, -1, prefile, vmu); 09533 ast_play_and_wait(chan, "vm-tempremoved"); 09534 cmd = 't'; 09535 break; 09536 case '*': 09537 cmd = 't'; 09538 break; 09539 default: 09540 cmd = ast_play_and_wait(chan, 09541 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09542 "vm-tempgreeting2" : "vm-tempgreeting"); 09543 if (!cmd) { 09544 cmd = ast_waitfordigit(chan, 6000); 09545 } 09546 if (!cmd) { 09547 retries++; 09548 } 09549 if (retries > 3) { 09550 cmd = 't'; 09551 } 09552 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09553 } 09554 } 09555 DISPOSE(prefile, -1); 09556 } 09557 if (cmd == 't') 09558 cmd = 0; 09559 return cmd; 09560 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11444 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and vm_users_data_provider_get_helper().
11446 { 11447 struct ast_vm_user *user; 11448 11449 AST_LIST_LOCK(&users); 11450 AST_LIST_TRAVERSE(&users, user, list) { 11451 vm_users_data_provider_get_helper(search, data_root, user); 11452 } 11453 AST_LIST_UNLOCK(&users); 11454 11455 return 0; 11456 }
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 11397 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().
11399 { 11400 struct ast_data *data_user, *data_zone; 11401 struct ast_data *data_state; 11402 struct vm_zone *zone = NULL; 11403 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11404 char ext_context[256] = ""; 11405 11406 data_user = ast_data_add_node(data_root, "user"); 11407 if (!data_user) { 11408 return -1; 11409 } 11410 11411 ast_data_add_structure(ast_vm_user, data_user, user); 11412 11413 AST_LIST_LOCK(&zones); 11414 AST_LIST_TRAVERSE(&zones, zone, list) { 11415 if (!strcmp(zone->name, user->zonetag)) { 11416 break; 11417 } 11418 } 11419 AST_LIST_UNLOCK(&zones); 11420 11421 /* state */ 11422 data_state = ast_data_add_node(data_user, "state"); 11423 if (!data_state) { 11424 return -1; 11425 } 11426 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11427 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11428 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11429 ast_data_add_int(data_state, "newmsg", newmsg); 11430 ast_data_add_int(data_state, "oldmsg", oldmsg); 11431 11432 if (zone) { 11433 data_zone = ast_data_add_node(data_user, "zone"); 11434 ast_data_add_structure(vm_zone, data_zone, zone); 11435 } 11436 11437 if (!ast_data_search_match(search, data_user)) { 11438 ast_data_remove_node(data_root, data_user); 11439 } 11440 11441 return 0; 11442 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11083 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().
11084 { 11085 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11086 struct ast_vm_user vmus; 11087 char *options = NULL; 11088 int silent = 0, skipuser = 0; 11089 int res = -1; 11090 11091 if (data) { 11092 s = ast_strdupa(data); 11093 user = strsep(&s, ","); 11094 options = strsep(&s, ","); 11095 if (user) { 11096 s = user; 11097 user = strsep(&s, "@"); 11098 context = strsep(&s, ""); 11099 if (!ast_strlen_zero(user)) 11100 skipuser++; 11101 ast_copy_string(mailbox, user, sizeof(mailbox)); 11102 } 11103 } 11104 11105 if (options) { 11106 silent = (strchr(options, 's')) != NULL; 11107 } 11108 11109 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11110 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11111 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11112 ast_play_and_wait(chan, "auth-thankyou"); 11113 res = 0; 11114 } else if (mailbox[0] == '*') { 11115 /* user entered '*' */ 11116 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11117 res = 0; /* prevent hangup */ 11118 } 11119 } 11120 11121 return res; 11122 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12623 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().
12624 { 12625 char *context; 12626 char *args_copy; 12627 int res; 12628 12629 if (ast_strlen_zero(data)) { 12630 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12631 return -1; 12632 } 12633 12634 args_copy = ast_strdupa(data); 12635 if ((context = strchr(args_copy, '@'))) { 12636 *context++ = '\0'; 12637 } else { 12638 context = "default"; 12639 } 12640 12641 if ((res = sayname(chan, args_copy, context) < 0)) { 12642 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12643 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12644 if (!res) { 12645 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12646 } 12647 } 12648 12649 return res; 12650 }
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 4442 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().
04443 { 04444 const struct vm_zone *z = NULL; 04445 struct timeval t = ast_tvnow(); 04446 04447 /* Does this user have a timezone specified? */ 04448 if (!ast_strlen_zero(vmu->zonetag)) { 04449 /* Find the zone in the list */ 04450 AST_LIST_LOCK(&zones); 04451 AST_LIST_TRAVERSE(&zones, z, list) { 04452 if (!strcmp(z->name, vmu->zonetag)) 04453 break; 04454 } 04455 AST_LIST_UNLOCK(&zones); 04456 } 04457 ast_localtime(&t, tm, z ? z->timezone : NULL); 04458 return tm; 04459 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7497 of file app_voicemail_odbcstorage.c.
References ast_control_streamfile(), and ast_test_suite_event_notify.
Referenced by advanced_options(), and play_message().
07498 { 07499 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07500 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); 07501 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7489 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().
07490 { 07491 int res; 07492 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07493 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07494 return res; 07495 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12590 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().
12590 { 12591 struct ast_config *conf; 12592 struct ast_category *cat; 12593 struct ast_variable *var; 12594 int res = -1; 12595 12596 if (!(conf = ast_config_new())) { 12597 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12598 return res; 12599 } 12600 if (!(cat = ast_category_new("general", "", 1))) { 12601 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12602 ast_config_destroy(conf); 12603 return res; 12604 } 12605 if (!(var = ast_variable_new("password", password, ""))) { 12606 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12607 ast_config_destroy(conf); 12608 ast_category_destroy(cat); 12609 return res; 12610 } 12611 ast_category_append(conf, cat); 12612 ast_variable_append(cat, var); 12613 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12614 res = 0; 12615 } else { 12616 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12617 } 12618 12619 ast_config_destroy(conf); 12620 return res; 12621 }
char* addesc = "Comedian Mail" [static] |
Definition at line 750 of file app_voicemail_odbcstorage.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 877 of file app_voicemail_odbcstorage.c.
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 878 of file app_voicemail_odbcstorage.c.
int adsiver = 1 [static] |
Definition at line 879 of file app_voicemail_odbcstorage.c.
char* app = "VoiceMail" [static] |
Definition at line 753 of file app_voicemail_odbcstorage.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 756 of file app_voicemail_odbcstorage.c.
char* app3 = "MailboxExists" [static] |
Definition at line 758 of file app_voicemail_odbcstorage.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 759 of file app_voicemail_odbcstorage.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 863 of file app_voicemail_odbcstorage.c.
char charset[32] = "ISO-8859-1" [static] |
Definition at line 875 of file app_voicemail_odbcstorage.c.
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 866 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 11322 of file app_voicemail_odbcstorage.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 862 of file app_voicemail_odbcstorage.c.
char* emailbody = NULL [static] |
Definition at line 869 of file app_voicemail_odbcstorage.c.
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 880 of file app_voicemail_odbcstorage.c.
char* emailsubject = NULL [static] |
Definition at line 870 of file app_voicemail_odbcstorage.c.
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 864 of file app_voicemail_odbcstorage.c.
char ext_pass_check_cmd[128] [static] |
Definition at line 730 of file app_voicemail_odbcstorage.c.
char ext_pass_cmd[128] [static] |
Definition at line 729 of file app_voicemail_odbcstorage.c.
char externnotify[160] [static] |
Definition at line 773 of file app_voicemail_odbcstorage.c.
char fromstring[100] [static] |
Definition at line 873 of file app_voicemail_odbcstorage.c.
struct ast_flags globalflags = {0} [static] |
Definition at line 858 of file app_voicemail_odbcstorage.c.
struct ao2_container* inprocess_container |
Definition at line 902 of file app_voicemail_odbcstorage.c.
char listen_control_forward_key[12] [static] |
Definition at line 831 of file app_voicemail_odbcstorage.c.
char listen_control_pause_key[12] [static] |
Definition at line 833 of file app_voicemail_odbcstorage.c.
char listen_control_restart_key[12] [static] |
Definition at line 834 of file app_voicemail_odbcstorage.c.
char listen_control_reverse_key[12] [static] |
Definition at line 832 of file app_voicemail_odbcstorage.c.
char listen_control_stop_key[12] [static] |
Definition at line 835 of file app_voicemail_odbcstorage.c.
char locale[20] [static] |
Definition at line 766 of file app_voicemail_odbcstorage.c.
struct ast_custom_function mailbox_exists_acf [static] |
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11078 of file app_voicemail_odbcstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1692 of file app_voicemail_odbcstorage.c.
char mailcmd[160] [static] |
Definition at line 772 of file app_voicemail_odbcstorage.c.
int maxdeletedmsg [static] |
Definition at line 769 of file app_voicemail_odbcstorage.c.
int maxgreet [static] |
Definition at line 779 of file app_voicemail_odbcstorage.c.
int maxlogins [static] |
Definition at line 781 of file app_voicemail_odbcstorage.c.
int maxmsg [static] |
Definition at line 768 of file app_voicemail_odbcstorage.c.
int maxsilence [static] |
Definition at line 767 of file app_voicemail_odbcstorage.c.
int minpassword [static] |
Definition at line 782 of file app_voicemail_odbcstorage.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 800 of file app_voicemail_odbcstorage.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 826 of file app_voicemail_odbcstorage.c.
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 802 of file app_voicemail_odbcstorage.c.
int my_umask [static] |
Definition at line 732 of file app_voicemail_odbcstorage.c.
char* pagerbody = NULL [static] |
Definition at line 871 of file app_voicemail_odbcstorage.c.
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 881 of file app_voicemail_odbcstorage.c.
char pagerfromstring[100] [static] |
Definition at line 874 of file app_voicemail_odbcstorage.c.
char* pagersubject = NULL [static] |
Definition at line 872 of file app_voicemail_odbcstorage.c.
int passwordlocation [static] |
Definition at line 783 of file app_voicemail_odbcstorage.c.
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 795 of file app_voicemail_odbcstorage.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 790 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 787 of file app_voicemail_odbcstorage.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 796 of file app_voicemail_odbcstorage.c.
unsigned char poll_thread_run [static] |
Definition at line 797 of file app_voicemail_odbcstorage.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 736 of file app_voicemail_odbcstorage.c.
int saydurationminfo [static] |
Definition at line 860 of file app_voicemail_odbcstorage.c.
char* sayname_app = "VMSayName" [static] |
Definition at line 761 of file app_voicemail_odbcstorage.c.
char serveremail[80] [static] |
Definition at line 771 of file app_voicemail_odbcstorage.c.
int silencethreshold = 128 [static] |
Definition at line 770 of file app_voicemail_odbcstorage.c.
int skipms [static] |
Definition at line 780 of file app_voicemail_odbcstorage.c.
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 774 of file app_voicemail_odbcstorage.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 748 of file app_voicemail_odbcstorage.c.
struct ast_data_entry vm_data_providers[] [static] |
{ }
Definition at line 11463 of file app_voicemail_odbcstorage.c.
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 843 of file app_voicemail_odbcstorage.c.
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 842 of file app_voicemail_odbcstorage.c.
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 839 of file app_voicemail_odbcstorage.c.
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 840 of file app_voicemail_odbcstorage.c.
char vm_password[80] = "vm-password" [static] |
Definition at line 838 of file app_voicemail_odbcstorage.c.
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 844 of file app_voicemail_odbcstorage.c.
char vm_prepend_timeout[80] = "vm-then-pound" [static] |
Definition at line 856 of file app_voicemail_odbcstorage.c.
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 841 of file app_voicemail_odbcstorage.c.
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 727 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 11458 of file app_voicemail_odbcstorage.c.
char vmfmts[80] [static] |
Definition at line 775 of file app_voicemail_odbcstorage.c.
int vmmaxsecs [static] |
Definition at line 778 of file app_voicemail_odbcstorage.c.
int vmminsecs [static] |
Definition at line 777 of file app_voicemail_odbcstorage.c.
double volgain [static] |
Definition at line 776 of file app_voicemail_odbcstorage.c.
char zonetag[80] [static] |
Definition at line 765 of file app_voicemail_odbcstorage.c.