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