#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 | mwi_subs |
struct | users |
list of users found in the config file More... | |
struct | vm_state |
struct | vm_zone |
struct | zones |
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 } |
enum | vm_option_args { 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) } |
enum | vm_passwordlocation { 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 void | __reg_module (void) |
static void | __unreg_module (void) |
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_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble) |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. | |
static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
AST_TEST_DEFINE (test_voicemail_vmuser) | |
static int | base_encode (char *filename, FILE *so) |
Performs a base 64 encode algorithm on the contents of a File. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
static int | check_mime (const char *str) |
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. | |
static int | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
static int | close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu) |
static char * | complete_voicemail_show_users (const char *line, const char *word, int pos, int state) |
static int | copy (char *infile, char *outfile) |
Utility function to copy a file. | |
static int | copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag) |
Copies a message from one mailbox to another. | |
static void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
static int | count_messages (struct ast_vm_user *vmu, char *dir) |
Find all .txt files - even if they are not in sequence from 0000. | |
static int | create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder) |
basically mkdir -p $dest/$context/$ext/$folder | |
static int | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the users file or the realtime engine. | |
static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
Finds a voicemail user from the realtime engine. | |
static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent) |
Sends a voicemail message to a mailbox recipient. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
static void | free_zone (struct vm_zone *z) |
static int | get_date (char *s, int len) |
Gets the current date and time, as formatted string. | |
static int | get_folder (struct ast_channel *chan, int start) |
get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
plays a prompt and waits for a keypress. | |
static int | get_folder_by_name (const char *name) |
static int | handle_subscribe (void *datap) |
static int | handle_unsubscribe (void *datap) |
static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload voicemail configuration from the CLI. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
static int | inbuf (struct baseio *bio, FILE *fi) |
utility used by inchar(), for base_encode() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
static int | inprocess_count (const char *context, const char *mailbox, int delta) |
static int | inprocess_hash_fn (const void *obj, const int flags) |
static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
static int | is_valid_dtmf (const char *key) |
Determines if a DTMF key entered is valid. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
static int | load_config (int reload) |
static int | load_module (void) |
static int | make_dir (char *dest, int len, const char *context, const char *ext, const char *folder) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static int | make_file (char *dest, const int len, const char *dir, const int num) |
Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
static void * | mb_poll_thread (void *data) |
static const char * | mbox (struct ast_vm_user *vmu, int id) |
static int | messagecount (const char *context, const char *mailbox, const char *folder) |
static void | mwi_sub_destroy (struct mwi_sub *mwi_sub) |
static void | mwi_sub_event_cb (const struct ast_event *event, void *userdata) |
static void | mwi_unsub_event_cb (const struct ast_event *event, void *userdata) |
static int | notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag) |
Sends email notification that a user has a new voicemail waiting for them. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
static int | play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback) |
static int | play_message_category (struct ast_channel *chan, const char *category) |
static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag) |
static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
static void | poll_subscribed_mailboxes (void) |
static void | populate_defaults (struct ast_vm_user *vmu) |
Sets default voicemail system options to a voicemail user. | |
static void | prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
static FILE * | vm_mkftemp (char *template) |
static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
static int | vm_play_folder_name_gr (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } |
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 struct ast_module_info * | ast_module_info = &__mod_info |
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} |
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 ast_mutex_t | poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
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_app_option | vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} |
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] |
This module requires res_adsi to load. This needs to be optional during compilation.
This file is now almost impossible to work with, due to all #ifdefs. Feels like the database code before realtime. Someone - please come up with a plan to clean this up.
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 | ) |
Value:
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 11305 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 659 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 |
OPT_SILENT | |
OPT_BUSY_GREETING | |
OPT_UNAVAIL_GREETING | |
OPT_RECORDGAIN | |
OPT_PREPEND_MAILBOX | |
OPT_AUTOPLAY | |
OPT_DTMFEXIT | |
OPT_MESSAGE_Urgent | |
OPT_MESSAGE_PRIORITY |
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 |
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 5353 of file app_voicemail_odbcstorage.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
05354 { 05355 DIR *dir; 05356 struct dirent *de; 05357 char fn[256]; 05358 int ret = 0; 05359 05360 /* If no mailbox, return immediately */ 05361 if (ast_strlen_zero(mailbox)) 05362 return 0; 05363 05364 if (ast_strlen_zero(folder)) 05365 folder = "INBOX"; 05366 if (ast_strlen_zero(context)) 05367 context = "default"; 05368 05369 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05370 05371 if (!(dir = opendir(fn))) 05372 return 0; 05373 05374 while ((de = readdir(dir))) { 05375 if (!strncasecmp(de->d_name, "msg", 3)) { 05376 if (shortcircuit) { 05377 ret = 1; 05378 break; 05379 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05380 ret++; 05381 } 05382 } 05383 } 05384 05385 closedir(dir); 05386 05387 return ret; 05388 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13602 of file app_voicemail_odbcstorage.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13602 of file app_voicemail_odbcstorage.c.
static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | args, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10981 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().
10982 { 10983 struct ast_vm_user svm; 10984 AST_DECLARE_APP_ARGS(arg, 10985 AST_APP_ARG(mbox); 10986 AST_APP_ARG(context); 10987 ); 10988 10989 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 10990 10991 if (ast_strlen_zero(arg.mbox)) { 10992 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 10993 return -1; 10994 } 10995 10996 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 10997 return 0; 10998 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11802 of file app_voicemail_odbcstorage.c.
References adsifdn, adsisec, adsiver, 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_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, callcontext, charset, cidinternalcontexts, 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, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, ext_pass_check_cmd, ext_pass_cmd, externnotify, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), vm_zone::list, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, locale, LOG_ERROR, mailcmd, MAX_NUM_CID_CONTEXTS, maxdeletedmsg, maxgreet, maxlogins, MAXMSG, maxmsg, MAXMSGLIMIT, maxsilence, MINPASSWORD, minpassword, vm_zone::msg_format, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, passwordlocation, poll_freq, poll_mailboxes, poll_thread, populate_defaults(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, serveremail, silencethreshold, skipms, smdi_iface, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, userscontext, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, vm_invalid_password, VM_MESSAGEWRAP, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_pls_try_again, vm_prepend_timeout, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SPOOL_DIR, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxsecs, vmminsecs, volgain, and zonetag.
11803 { 11804 struct ast_vm_user *current; 11805 char *cat; 11806 struct ast_variable *var; 11807 const char *val; 11808 char *q, *stringp, *tmp; 11809 int x; 11810 int tmpadsi[4]; 11811 char secretfn[PATH_MAX] = ""; 11812 11813 #ifdef IMAP_STORAGE 11814 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11815 #endif 11816 /* set audio control prompts */ 11817 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11818 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11819 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11820 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11821 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11822 11823 /* Free all the users structure */ 11824 free_vm_users(); 11825 11826 /* Free all the zones structure */ 11827 free_vm_zones(); 11828 11829 AST_LIST_LOCK(&users); 11830 11831 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11832 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11833 11834 if (cfg) { 11835 /* General settings */ 11836 11837 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11838 val = "default"; 11839 ast_copy_string(userscontext, val, sizeof(userscontext)); 11840 /* Attach voice message to mail message ? */ 11841 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11842 val = "yes"; 11843 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11844 11845 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11846 val = "no"; 11847 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11848 11849 volgain = 0.0; 11850 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11851 sscanf(val, "%30lf", &volgain); 11852 11853 #ifdef ODBC_STORAGE 11854 strcpy(odbc_database, "asterisk"); 11855 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11856 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11857 } 11858 strcpy(odbc_table, "voicemessages"); 11859 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11860 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11861 } 11862 #endif 11863 /* Mail command */ 11864 strcpy(mailcmd, SENDMAIL); 11865 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11866 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11867 11868 maxsilence = 0; 11869 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11870 maxsilence = atoi(val); 11871 if (maxsilence > 0) 11872 maxsilence *= 1000; 11873 } 11874 11875 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11876 maxmsg = MAXMSG; 11877 } else { 11878 maxmsg = atoi(val); 11879 if (maxmsg < 0) { 11880 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11881 maxmsg = MAXMSG; 11882 } else if (maxmsg > MAXMSGLIMIT) { 11883 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11884 maxmsg = MAXMSGLIMIT; 11885 } 11886 } 11887 11888 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11889 maxdeletedmsg = 0; 11890 } else { 11891 if (sscanf(val, "%30d", &x) == 1) 11892 maxdeletedmsg = x; 11893 else if (ast_true(val)) 11894 maxdeletedmsg = MAXMSG; 11895 else 11896 maxdeletedmsg = 0; 11897 11898 if (maxdeletedmsg < 0) { 11899 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11900 maxdeletedmsg = MAXMSG; 11901 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11902 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11903 maxdeletedmsg = MAXMSGLIMIT; 11904 } 11905 } 11906 11907 /* Load date format config for voicemail mail */ 11908 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11909 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11910 } 11911 11912 /* Load date format config for voicemail pager mail */ 11913 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11914 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11915 } 11916 11917 /* External password changing command */ 11918 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11919 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11920 pwdchange = PWDCHANGE_EXTERNAL; 11921 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11922 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11923 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11924 } 11925 11926 /* External password validation command */ 11927 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11928 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11929 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11930 } 11931 11932 #ifdef IMAP_STORAGE 11933 /* IMAP server address */ 11934 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11935 ast_copy_string(imapserver, val, sizeof(imapserver)); 11936 } else { 11937 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11938 } 11939 /* IMAP server port */ 11940 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11941 ast_copy_string(imapport, val, sizeof(imapport)); 11942 } else { 11943 ast_copy_string(imapport, "143", sizeof(imapport)); 11944 } 11945 /* IMAP server flags */ 11946 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11947 ast_copy_string(imapflags, val, sizeof(imapflags)); 11948 } 11949 /* IMAP server master username */ 11950 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11951 ast_copy_string(authuser, val, sizeof(authuser)); 11952 } 11953 /* IMAP server master password */ 11954 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11955 ast_copy_string(authpassword, val, sizeof(authpassword)); 11956 } 11957 /* Expunge on exit */ 11958 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11959 if (ast_false(val)) 11960 expungeonhangup = 0; 11961 else 11962 expungeonhangup = 1; 11963 } else { 11964 expungeonhangup = 1; 11965 } 11966 /* IMAP voicemail folder */ 11967 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11968 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 11969 } else { 11970 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 11971 } 11972 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 11973 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 11974 } 11975 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 11976 imapgreetings = ast_true(val); 11977 } else { 11978 imapgreetings = 0; 11979 } 11980 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 11981 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11982 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 11983 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 11984 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11985 } else { 11986 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 11987 } 11988 11989 /* There is some very unorthodox casting done here. This is due 11990 * to the way c-client handles the argument passed in. It expects a 11991 * void pointer and casts the pointer directly to a long without 11992 * first dereferencing it. */ 11993 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 11994 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 11995 } else { 11996 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 11997 } 11998 11999 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12000 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12001 } else { 12002 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12003 } 12004 12005 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12006 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12007 } else { 12008 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12009 } 12010 12011 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12012 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12013 } else { 12014 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12015 } 12016 12017 /* Increment configuration version */ 12018 imapversion++; 12019 #endif 12020 /* External voicemail notify application */ 12021 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12022 ast_copy_string(externnotify, val, sizeof(externnotify)); 12023 ast_debug(1, "found externnotify: %s\n", externnotify); 12024 } else { 12025 externnotify[0] = '\0'; 12026 } 12027 12028 /* SMDI voicemail notification */ 12029 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12030 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12031 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12032 smdi_iface = ast_smdi_interface_find(val); 12033 } else { 12034 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12035 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12036 } 12037 if (!smdi_iface) { 12038 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12039 } 12040 } 12041 12042 /* Silence treshold */ 12043 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12044 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12045 silencethreshold = atoi(val); 12046 12047 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12048 val = ASTERISK_USERNAME; 12049 ast_copy_string(serveremail, val, sizeof(serveremail)); 12050 12051 vmmaxsecs = 0; 12052 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12053 if (sscanf(val, "%30d", &x) == 1) { 12054 vmmaxsecs = x; 12055 } else { 12056 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12057 } 12058 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12059 static int maxmessage_deprecate = 0; 12060 if (maxmessage_deprecate == 0) { 12061 maxmessage_deprecate = 1; 12062 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12063 } 12064 if (sscanf(val, "%30d", &x) == 1) { 12065 vmmaxsecs = x; 12066 } else { 12067 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12068 } 12069 } 12070 12071 vmminsecs = 0; 12072 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12073 if (sscanf(val, "%30d", &x) == 1) { 12074 vmminsecs = x; 12075 if (maxsilence / 1000 >= vmminsecs) { 12076 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12077 } 12078 } else { 12079 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12080 } 12081 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12082 static int maxmessage_deprecate = 0; 12083 if (maxmessage_deprecate == 0) { 12084 maxmessage_deprecate = 1; 12085 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12086 } 12087 if (sscanf(val, "%30d", &x) == 1) { 12088 vmminsecs = x; 12089 if (maxsilence / 1000 >= vmminsecs) { 12090 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12091 } 12092 } else { 12093 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12094 } 12095 } 12096 12097 val = ast_variable_retrieve(cfg, "general", "format"); 12098 if (!val) { 12099 val = "wav"; 12100 } else { 12101 tmp = ast_strdupa(val); 12102 val = ast_format_str_reduce(tmp); 12103 if (!val) { 12104 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12105 val = "wav"; 12106 } 12107 } 12108 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12109 12110 skipms = 3000; 12111 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12112 if (sscanf(val, "%30d", &x) == 1) { 12113 maxgreet = x; 12114 } else { 12115 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12116 } 12117 } 12118 12119 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12120 if (sscanf(val, "%30d", &x) == 1) { 12121 skipms = x; 12122 } else { 12123 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12124 } 12125 } 12126 12127 maxlogins = 3; 12128 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12129 if (sscanf(val, "%30d", &x) == 1) { 12130 maxlogins = x; 12131 } else { 12132 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12133 } 12134 } 12135 12136 minpassword = MINPASSWORD; 12137 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12138 if (sscanf(val, "%30d", &x) == 1) { 12139 minpassword = x; 12140 } else { 12141 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12142 } 12143 } 12144 12145 /* Force new user to record name ? */ 12146 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12147 val = "no"; 12148 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12149 12150 /* Force new user to record greetings ? */ 12151 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12152 val = "no"; 12153 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12154 12155 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12156 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12157 stringp = ast_strdupa(val); 12158 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12159 if (!ast_strlen_zero(stringp)) { 12160 q = strsep(&stringp, ","); 12161 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12162 q++; 12163 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12164 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12165 } else { 12166 cidinternalcontexts[x][0] = '\0'; 12167 } 12168 } 12169 } 12170 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12171 ast_debug(1, "VM Review Option disabled globally\n"); 12172 val = "no"; 12173 } 12174 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12175 12176 /* Temporary greeting reminder */ 12177 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12178 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12179 val = "no"; 12180 } else { 12181 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12182 } 12183 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12184 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12185 ast_debug(1, "VM next message wrap disabled globally\n"); 12186 val = "no"; 12187 } 12188 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12189 12190 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12191 ast_debug(1, "VM Operator break disabled globally\n"); 12192 val = "no"; 12193 } 12194 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12195 12196 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12197 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12198 val = "no"; 12199 } 12200 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12201 12202 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12203 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12204 val = "no"; 12205 } 12206 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12207 12208 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12209 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12210 val = "yes"; 12211 } 12212 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12213 12214 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12215 ast_debug(1, "Move Heard enabled globally\n"); 12216 val = "yes"; 12217 } 12218 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12219 12220 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12221 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12222 val = "no"; 12223 } 12224 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12225 12226 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12227 ast_debug(1, "Duration info before msg enabled globally\n"); 12228 val = "yes"; 12229 } 12230 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12231 12232 saydurationminfo = 2; 12233 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12234 if (sscanf(val, "%30d", &x) == 1) { 12235 saydurationminfo = x; 12236 } else { 12237 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12238 } 12239 } 12240 12241 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12242 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12243 val = "no"; 12244 } 12245 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12246 12247 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12248 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12249 ast_debug(1, "found dialout context: %s\n", dialcontext); 12250 } else { 12251 dialcontext[0] = '\0'; 12252 } 12253 12254 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12255 ast_copy_string(callcontext, val, sizeof(callcontext)); 12256 ast_debug(1, "found callback context: %s\n", callcontext); 12257 } else { 12258 callcontext[0] = '\0'; 12259 } 12260 12261 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12262 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12263 ast_debug(1, "found operator context: %s\n", exitcontext); 12264 } else { 12265 exitcontext[0] = '\0'; 12266 } 12267 12268 /* load password sounds configuration */ 12269 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12270 ast_copy_string(vm_password, val, sizeof(vm_password)); 12271 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12272 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12273 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12274 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12275 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12276 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12277 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12278 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12279 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12280 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12281 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12282 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12283 } 12284 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12285 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12286 } 12287 /* load configurable audio prompts */ 12288 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12289 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12290 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12291 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12292 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12293 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12294 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12295 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12296 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12297 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12298 12299 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12300 val = "no"; 12301 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12302 12303 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12304 val = "voicemail.conf"; 12305 } 12306 if (!(strcmp(val, "spooldir"))) { 12307 passwordlocation = OPT_PWLOC_SPOOLDIR; 12308 } else { 12309 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12310 } 12311 12312 poll_freq = DEFAULT_POLL_FREQ; 12313 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12314 if (sscanf(val, "%30u", &poll_freq) != 1) { 12315 poll_freq = DEFAULT_POLL_FREQ; 12316 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12317 } 12318 } 12319 12320 poll_mailboxes = 0; 12321 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12322 poll_mailboxes = ast_true(val); 12323 12324 memset(fromstring, 0, sizeof(fromstring)); 12325 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12326 strcpy(charset, "ISO-8859-1"); 12327 if (emailbody) { 12328 ast_free(emailbody); 12329 emailbody = NULL; 12330 } 12331 if (emailsubject) { 12332 ast_free(emailsubject); 12333 emailsubject = NULL; 12334 } 12335 if (pagerbody) { 12336 ast_free(pagerbody); 12337 pagerbody = NULL; 12338 } 12339 if (pagersubject) { 12340 ast_free(pagersubject); 12341 pagersubject = NULL; 12342 } 12343 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12344 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12345 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12346 ast_copy_string(fromstring, val, sizeof(fromstring)); 12347 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12348 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12349 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12350 ast_copy_string(charset, val, sizeof(charset)); 12351 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12352 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12353 for (x = 0; x < 4; x++) { 12354 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12355 } 12356 } 12357 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12358 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12359 for (x = 0; x < 4; x++) { 12360 memcpy(&adsisec[x], &tmpadsi[x], 1); 12361 } 12362 } 12363 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12364 if (atoi(val)) { 12365 adsiver = atoi(val); 12366 } 12367 } 12368 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12369 ast_copy_string(zonetag, val, sizeof(zonetag)); 12370 } 12371 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12372 ast_copy_string(locale, val, sizeof(locale)); 12373 } 12374 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12375 emailsubject = ast_strdup(substitute_escapes(val)); 12376 } 12377 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12378 emailbody = ast_strdup(substitute_escapes(val)); 12379 } 12380 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12381 pagersubject = ast_strdup(substitute_escapes(val)); 12382 } 12383 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12384 pagerbody = ast_strdup(substitute_escapes(val)); 12385 } 12386 12387 /* load mailboxes from users.conf */ 12388 if (ucfg) { 12389 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12390 if (!strcasecmp(cat, "general")) { 12391 continue; 12392 } 12393 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12394 continue; 12395 if ((current = find_or_create(userscontext, cat))) { 12396 populate_defaults(current); 12397 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12398 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12399 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12400 current->passwordlocation = OPT_PWLOC_USERSCONF; 12401 } 12402 12403 switch (current->passwordlocation) { 12404 case OPT_PWLOC_SPOOLDIR: 12405 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12406 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12407 } 12408 } 12409 } 12410 } 12411 12412 /* load mailboxes from voicemail.conf */ 12413 cat = ast_category_browse(cfg, NULL); 12414 while (cat) { 12415 if (strcasecmp(cat, "general")) { 12416 var = ast_variable_browse(cfg, cat); 12417 if (strcasecmp(cat, "zonemessages")) { 12418 /* Process mailboxes in this context */ 12419 while (var) { 12420 append_mailbox(cat, var->name, var->value); 12421 var = var->next; 12422 } 12423 } else { 12424 /* Timezones in this context */ 12425 while (var) { 12426 struct vm_zone *z; 12427 if ((z = ast_malloc(sizeof(*z)))) { 12428 char *msg_format, *tzone; 12429 msg_format = ast_strdupa(var->value); 12430 tzone = strsep(&msg_format, "|,"); 12431 if (msg_format) { 12432 ast_copy_string(z->name, var->name, sizeof(z->name)); 12433 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12434 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12435 AST_LIST_LOCK(&zones); 12436 AST_LIST_INSERT_HEAD(&zones, z, list); 12437 AST_LIST_UNLOCK(&zones); 12438 } else { 12439 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12440 ast_free(z); 12441 } 12442 } else { 12443 AST_LIST_UNLOCK(&users); 12444 return -1; 12445 } 12446 var = var->next; 12447 } 12448 } 12449 } 12450 cat = ast_category_browse(cfg, cat); 12451 } 12452 12453 AST_LIST_UNLOCK(&users); 12454 12455 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12456 start_poll_thread(); 12457 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12458 stop_poll_thread();; 12459 12460 return 0; 12461 } else { 12462 AST_LIST_UNLOCK(&users); 12463 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12464 return 0; 12465 } 12466 }
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 4767 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, my_umask, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
04768 { 04769 char tmpdir[256], newtmp[256]; 04770 char fname[256]; 04771 char tmpcmd[256]; 04772 int tmpfd = -1; 04773 int soxstatus = 0; 04774 04775 /* Eww. We want formats to tell us their own MIME type */ 04776 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04777 04778 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04779 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04780 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04781 tmpfd = mkstemp(newtmp); 04782 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04783 ast_debug(3, "newtmp: %s\n", newtmp); 04784 if (tmpfd > -1) { 04785 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04786 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04787 attach = newtmp; 04788 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04789 } else { 04790 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04791 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04792 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04793 } 04794 } 04795 } 04796 fprintf(p, "--%s" ENDL, bound); 04797 if (msgnum > -1) 04798 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04799 else 04800 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04801 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04802 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04803 if (msgnum > -1) 04804 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04805 else 04806 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04807 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04808 base_encode(fname, p); 04809 if (last) 04810 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04811 if (tmpfd > -1) { 04812 if (soxstatus == 0) { 04813 unlink(fname); 04814 } 04815 close(tmpfd); 04816 unlink(newtmp); 04817 } 04818 return 0; 04819 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6371 of file app_voicemail_odbcstorage.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), and ast_log().
06372 { 06373 int x; 06374 if (!ast_adsi_available(chan)) 06375 return; 06376 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06377 if (x < 0) 06378 return; 06379 if (!x) { 06380 if (adsi_load_vmail(chan, useadsi)) { 06381 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06382 return; 06383 } 06384 } else 06385 *useadsi = 1; 06386 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6560 of file app_voicemail_odbcstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
06561 { 06562 int bytes = 0; 06563 unsigned char buf[256]; 06564 unsigned char keys[8]; 06565 06566 int x; 06567 06568 if (!ast_adsi_available(chan)) 06569 return; 06570 06571 /* New meaning for keys */ 06572 for (x = 0; x < 5; x++) 06573 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06574 06575 keys[6] = 0x0; 06576 keys[7] = 0x0; 06577 06578 if (!vms->curmsg) { 06579 /* No prev key, provide "Folder" instead */ 06580 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06581 } 06582 if (vms->curmsg >= vms->lastmsg) { 06583 /* If last message ... */ 06584 if (vms->curmsg) { 06585 /* but not only message, provide "Folder" instead */ 06586 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06587 } else { 06588 /* Otherwise if only message, leave blank */ 06589 keys[3] = 1; 06590 } 06591 } 06592 06593 /* If deleted, show "undeleted" */ 06594 if (vms->deleted[vms->curmsg]) 06595 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06596 06597 /* Except "Exit" */ 06598 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06599 bytes += ast_adsi_set_keys(buf + bytes, keys); 06600 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06601 06602 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06603 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6436 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().
06437 { 06438 unsigned char buf[256]; 06439 int bytes = 0; 06440 unsigned char keys[8]; 06441 int x, y; 06442 06443 if (!ast_adsi_available(chan)) 06444 return; 06445 06446 for (x = 0; x < 5; x++) { 06447 y = ADSI_KEY_APPS + 12 + start + x; 06448 if (y > ADSI_KEY_APPS + 12 + 4) 06449 y = 0; 06450 keys[x] = ADSI_KEY_SKT | y; 06451 } 06452 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06453 keys[6] = 0; 06454 keys[7] = 0; 06455 06456 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06457 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06458 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06459 bytes += ast_adsi_set_keys(buf + bytes, keys); 06460 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06461 06462 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06463 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6708 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().
06709 { 06710 unsigned char buf[256]; 06711 int bytes = 0; 06712 06713 if (!ast_adsi_available(chan)) 06714 return; 06715 bytes += adsi_logo(buf + bytes); 06716 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06717 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06718 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06719 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06720 06721 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06722 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6242 of file app_voicemail_odbcstorage.c.
References addesc, ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsifdn, adsisec, adsiver, 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().
06243 { 06244 unsigned char buf[256]; 06245 int bytes = 0; 06246 int x; 06247 char num[5]; 06248 06249 *useadsi = 0; 06250 bytes += ast_adsi_data_mode(buf + bytes); 06251 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06252 06253 bytes = 0; 06254 bytes += adsi_logo(buf); 06255 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06256 #ifdef DISPLAY 06257 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06258 #endif 06259 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06260 bytes += ast_adsi_data_mode(buf + bytes); 06261 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06262 06263 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06264 bytes = 0; 06265 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06266 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06267 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06268 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06269 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06270 return 0; 06271 } 06272 06273 #ifdef DISPLAY 06274 /* Add a dot */ 06275 bytes = 0; 06276 bytes += ast_adsi_logo(buf); 06277 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06278 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06279 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06280 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06281 #endif 06282 bytes = 0; 06283 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06284 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06285 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06286 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06287 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06288 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06289 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06290 06291 #ifdef DISPLAY 06292 /* Add another dot */ 06293 bytes = 0; 06294 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06295 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06296 06297 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06298 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06299 #endif 06300 06301 bytes = 0; 06302 /* These buttons we load but don't use yet */ 06303 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06304 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06305 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06306 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06307 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06308 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06309 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06310 06311 #ifdef DISPLAY 06312 /* Add another dot */ 06313 bytes = 0; 06314 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06315 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06316 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06317 #endif 06318 06319 bytes = 0; 06320 for (x = 0; x < 5; x++) { 06321 snprintf(num, sizeof(num), "%d", x); 06322 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06323 } 06324 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06325 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06326 06327 #ifdef DISPLAY 06328 /* Add another dot */ 06329 bytes = 0; 06330 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06331 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06332 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06333 #endif 06334 06335 if (ast_adsi_end_download(chan)) { 06336 bytes = 0; 06337 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06338 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06339 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06340 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06341 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06342 return 0; 06343 } 06344 bytes = 0; 06345 bytes += ast_adsi_download_disconnect(buf + bytes); 06346 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06347 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06348 06349 ast_debug(1, "Done downloading scripts...\n"); 06350 06351 #ifdef DISPLAY 06352 /* Add last dot */ 06353 bytes = 0; 06354 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06355 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06356 #endif 06357 ast_debug(1, "Restarting session...\n"); 06358 06359 bytes = 0; 06360 /* Load the session now */ 06361 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06362 *useadsi = 1; 06363 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06364 } else 06365 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06366 06367 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06368 return 0; 06369 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6388 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().
06389 { 06390 unsigned char buf[256]; 06391 int bytes = 0; 06392 unsigned char keys[8]; 06393 int x; 06394 if (!ast_adsi_available(chan)) 06395 return; 06396 06397 for (x = 0; x < 8; x++) 06398 keys[x] = 0; 06399 /* Set one key for next */ 06400 keys[3] = ADSI_KEY_APPS + 3; 06401 06402 bytes += adsi_logo(buf + bytes); 06403 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06404 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06405 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06406 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06407 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06408 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06409 bytes += ast_adsi_set_keys(buf + bytes, keys); 06410 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06411 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06412 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6234 of file app_voicemail_odbcstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().
06235 { 06236 int bytes = 0; 06237 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06238 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06239 return bytes; 06240 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6465 of file app_voicemail_odbcstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), ast_copy_string(), ast_strlen_zero(), buf1, buf2, vm_state::curmsg, vm_state::fn, name, and strsep().
06466 { 06467 int bytes = 0; 06468 unsigned char buf[256]; 06469 char buf1[256], buf2[256]; 06470 char fn2[PATH_MAX]; 06471 06472 char cid[256] = ""; 06473 char *val; 06474 char *name, *num; 06475 char datetime[21] = ""; 06476 FILE *f; 06477 06478 unsigned char keys[8]; 06479 06480 int x; 06481 06482 if (!ast_adsi_available(chan)) 06483 return; 06484 06485 /* Retrieve important info */ 06486 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06487 f = fopen(fn2, "r"); 06488 if (f) { 06489 while (!feof(f)) { 06490 if (!fgets((char *) buf, sizeof(buf), f)) { 06491 continue; 06492 } 06493 if (!feof(f)) { 06494 char *stringp = NULL; 06495 stringp = (char *) buf; 06496 strsep(&stringp, "="); 06497 val = strsep(&stringp, "="); 06498 if (!ast_strlen_zero(val)) { 06499 if (!strcmp((char *) buf, "callerid")) 06500 ast_copy_string(cid, val, sizeof(cid)); 06501 if (!strcmp((char *) buf, "origdate")) 06502 ast_copy_string(datetime, val, sizeof(datetime)); 06503 } 06504 } 06505 } 06506 fclose(f); 06507 } 06508 /* New meaning for keys */ 06509 for (x = 0; x < 5; x++) 06510 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06511 keys[6] = 0x0; 06512 keys[7] = 0x0; 06513 06514 if (!vms->curmsg) { 06515 /* No prev key, provide "Folder" instead */ 06516 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06517 } 06518 if (vms->curmsg >= vms->lastmsg) { 06519 /* If last message ... */ 06520 if (vms->curmsg) { 06521 /* but not only message, provide "Folder" instead */ 06522 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06523 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06524 06525 } else { 06526 /* Otherwise if only message, leave blank */ 06527 keys[3] = 1; 06528 } 06529 } 06530 06531 if (!ast_strlen_zero(cid)) { 06532 ast_callerid_parse(cid, &name, &num); 06533 if (!name) 06534 name = num; 06535 } else 06536 name = "Unknown Caller"; 06537 06538 /* If deleted, show "undeleted" */ 06539 06540 if (vms->deleted[vms->curmsg]) 06541 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06542 06543 /* Except "Exit" */ 06544 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06545 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06546 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06547 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06548 06549 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06550 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06551 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06552 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06553 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06554 bytes += ast_adsi_set_keys(buf + bytes, keys); 06555 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06556 06557 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06558 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6414 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().
06415 { 06416 unsigned char buf[256]; 06417 int bytes = 0; 06418 unsigned char keys[8]; 06419 int x; 06420 if (!ast_adsi_available(chan)) 06421 return; 06422 06423 for (x = 0; x < 8; x++) 06424 keys[x] = 0; 06425 /* Set one key for next */ 06426 keys[3] = ADSI_KEY_APPS + 3; 06427 06428 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06429 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06430 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06431 bytes += ast_adsi_set_keys(buf + bytes, keys); 06432 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06433 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06434 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6605 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.
06606 { 06607 unsigned char buf[256] = ""; 06608 char buf1[256] = "", buf2[256] = ""; 06609 int bytes = 0; 06610 unsigned char keys[8]; 06611 int x; 06612 06613 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06614 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06615 if (!ast_adsi_available(chan)) 06616 return; 06617 if (vms->newmessages) { 06618 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06619 if (vms->oldmessages) { 06620 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06621 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06622 } else { 06623 snprintf(buf2, sizeof(buf2), "%s.", newm); 06624 } 06625 } else if (vms->oldmessages) { 06626 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06627 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06628 } else { 06629 strcpy(buf1, "You have no messages."); 06630 buf2[0] = ' '; 06631 buf2[1] = '\0'; 06632 } 06633 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06634 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06635 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06636 06637 for (x = 0; x < 6; x++) 06638 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06639 keys[6] = 0; 06640 keys[7] = 0; 06641 06642 /* Don't let them listen if there are none */ 06643 if (vms->lastmsg < 0) 06644 keys[0] = 1; 06645 bytes += ast_adsi_set_keys(buf + bytes, keys); 06646 06647 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06648 06649 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06650 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6652 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.
06653 { 06654 unsigned char buf[256] = ""; 06655 char buf1[256] = "", buf2[256] = ""; 06656 int bytes = 0; 06657 unsigned char keys[8]; 06658 int x; 06659 06660 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06661 06662 if (!ast_adsi_available(chan)) 06663 return; 06664 06665 /* Original command keys */ 06666 for (x = 0; x < 6; x++) 06667 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06668 06669 keys[6] = 0; 06670 keys[7] = 0; 06671 06672 if ((vms->lastmsg + 1) < 1) 06673 keys[0] = 0; 06674 06675 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06676 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06677 06678 if (vms->lastmsg + 1) 06679 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06680 else 06681 strcpy(buf2, "no messages."); 06682 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06683 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06684 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06685 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06686 bytes += ast_adsi_set_keys(buf + bytes, keys); 06687 06688 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06689 06690 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06691 06692 }
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 13164 of file app_voicemail_odbcstorage.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), name, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, and wait_file().
13165 { 13166 int res = 0; 13167 char filename[PATH_MAX]; 13168 struct ast_config *msg_cfg = NULL; 13169 const char *origtime, *context; 13170 char *name, *num; 13171 int retries = 0; 13172 char *cid; 13173 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13174 13175 vms->starting = 0; 13176 13177 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13178 13179 /* Retrieve info from VM attribute file */ 13180 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13181 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13182 msg_cfg = ast_config_load(filename, config_flags); 13183 DISPOSE(vms->curdir, vms->curmsg); 13184 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13185 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13186 return 0; 13187 } 13188 13189 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13190 ast_config_destroy(msg_cfg); 13191 return 0; 13192 } 13193 13194 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13195 13196 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13197 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13198 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13199 switch (option) { 13200 case 3: /* Play message envelope */ 13201 if (!res) 13202 res = play_message_datetime(chan, vmu, origtime, filename); 13203 if (!res) 13204 res = play_message_callerid(chan, vms, cid, context, 0); 13205 13206 res = 't'; 13207 break; 13208 13209 case 2: /* Call back */ 13210 13211 if (ast_strlen_zero(cid)) 13212 break; 13213 13214 ast_callerid_parse(cid, &name, &num); 13215 while ((res > -1) && (res != 't')) { 13216 switch (res) { 13217 case '1': 13218 if (num) { 13219 /* Dial the CID number */ 13220 res = dialout(chan, vmu, num, vmu->callback); 13221 if (res) { 13222 ast_config_destroy(msg_cfg); 13223 return 9; 13224 } 13225 } else { 13226 res = '2'; 13227 } 13228 break; 13229 13230 case '2': 13231 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13232 if (!ast_strlen_zero(vmu->dialout)) { 13233 res = dialout(chan, vmu, NULL, vmu->dialout); 13234 if (res) { 13235 ast_config_destroy(msg_cfg); 13236 return 9; 13237 } 13238 } else { 13239 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13240 res = ast_play_and_wait(chan, "vm-sorry"); 13241 } 13242 ast_config_destroy(msg_cfg); 13243 return res; 13244 case '*': 13245 res = 't'; 13246 break; 13247 case '3': 13248 case '4': 13249 case '5': 13250 case '6': 13251 case '7': 13252 case '8': 13253 case '9': 13254 case '0': 13255 13256 res = ast_play_and_wait(chan, "vm-sorry"); 13257 retries++; 13258 break; 13259 default: 13260 if (num) { 13261 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13262 res = ast_play_and_wait(chan, "vm-num-i-have"); 13263 if (!res) 13264 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13265 if (!res) 13266 res = ast_play_and_wait(chan, "vm-tocallnum"); 13267 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13268 if (!ast_strlen_zero(vmu->dialout)) { 13269 if (!res) 13270 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13271 } 13272 } else { 13273 res = ast_play_and_wait(chan, "vm-nonumber"); 13274 if (!ast_strlen_zero(vmu->dialout)) { 13275 if (!res) 13276 res = ast_play_and_wait(chan, "vm-toenternumber"); 13277 } 13278 } 13279 if (!res) { 13280 res = ast_play_and_wait(chan, "vm-star-cancel"); 13281 } 13282 if (!res) { 13283 res = ast_waitfordigit(chan, 6000); 13284 } 13285 if (!res) { 13286 retries++; 13287 if (retries > 3) { 13288 res = 't'; 13289 } 13290 } 13291 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13292 break; 13293 13294 } 13295 if (res == 't') 13296 res = 0; 13297 else if (res == '*') 13298 res = -1; 13299 } 13300 break; 13301 13302 case 1: /* Reply */ 13303 /* Send reply directly to sender */ 13304 if (ast_strlen_zero(cid)) 13305 break; 13306 13307 ast_callerid_parse(cid, &name, &num); 13308 if (!num) { 13309 ast_verb(3, "No CID number available, no reply sent\n"); 13310 if (!res) 13311 res = ast_play_and_wait(chan, "vm-nonumber"); 13312 ast_config_destroy(msg_cfg); 13313 return res; 13314 } else { 13315 struct ast_vm_user vmu2; 13316 if (find_user(&vmu2, vmu->context, num)) { 13317 struct leave_vm_options leave_options; 13318 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13319 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13320 13321 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13322 13323 memset(&leave_options, 0, sizeof(leave_options)); 13324 leave_options.record_gain = record_gain; 13325 res = leave_voicemail(chan, mailbox, &leave_options); 13326 if (!res) 13327 res = 't'; 13328 ast_config_destroy(msg_cfg); 13329 return res; 13330 } else { 13331 /* Sender has no mailbox, can't reply */ 13332 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13333 ast_play_and_wait(chan, "vm-nobox"); 13334 res = 't'; 13335 ast_config_destroy(msg_cfg); 13336 return res; 13337 } 13338 } 13339 res = 0; 13340 13341 break; 13342 } 13343 13344 #ifndef IMAP_STORAGE 13345 ast_config_destroy(msg_cfg); 13346 13347 if (!res) { 13348 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13349 vms->heard[msg] = 1; 13350 res = wait_file(chan, vms, vms->fn); 13351 } 13352 #endif 13353 return res; 13354 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10708 of file app_voicemail_odbcstorage.c.
References apply_options(), 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(), read_password_from_file(), strsep(), and VM_SPOOL_DIR.
10709 { 10710 /* Assumes lock is already held */ 10711 char *tmp; 10712 char *stringp; 10713 char *s; 10714 struct ast_vm_user *vmu; 10715 char *mailbox_full; 10716 int new = 0, old = 0, urgent = 0; 10717 char secretfn[PATH_MAX] = ""; 10718 10719 tmp = ast_strdupa(data); 10720 10721 if (!(vmu = find_or_create(context, box))) 10722 return -1; 10723 10724 populate_defaults(vmu); 10725 10726 stringp = tmp; 10727 if ((s = strsep(&stringp, ","))) { 10728 if (!ast_strlen_zero(s) && s[0] == '*') { 10729 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10730 "\n\tmust be reset in voicemail.conf.\n", box); 10731 } 10732 /* assign password regardless of validity to prevent NULL password from being assigned */ 10733 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10734 } 10735 if (stringp && (s = strsep(&stringp, ","))) { 10736 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10737 } 10738 if (stringp && (s = strsep(&stringp, ","))) { 10739 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10740 } 10741 if (stringp && (s = strsep(&stringp, ","))) { 10742 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10743 } 10744 if (stringp && (s = strsep(&stringp, ","))) { 10745 apply_options(vmu, s); 10746 } 10747 10748 switch (vmu->passwordlocation) { 10749 case OPT_PWLOC_SPOOLDIR: 10750 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10751 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10752 } 10753 10754 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10755 strcpy(mailbox_full, box); 10756 strcat(mailbox_full, "@"); 10757 strcat(mailbox_full, context); 10758 10759 inboxcount2(mailbox_full, &urgent, &new, &old); 10760 queue_mwi_event(mailbox_full, urgent, new, old); 10761 10762 return 0; 10763 }
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. |
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.
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, strsep(), value, and var.
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 ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_WARNING, ast_vm_user::mailbox, ast_vm_user::password, and var.
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_DATA_STRUCTURE | ( | vm_zone | , | |
DATA_EXPORT_VM_ZONES | ||||
) |
AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
DATA_EXPORT_VM_USERS | ||||
) |
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 4442 of file app_voicemail_odbcstorage.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), and charset.
04443 { 04444 struct ast_str *tmp = ast_str_alloca(80); 04445 int first_section = 1; 04446 04447 ast_str_reset(*end); 04448 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04449 for (; *start; start++) { 04450 int need_encoding = 0; 04451 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04452 need_encoding = 1; 04453 } 04454 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04455 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04456 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04457 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04458 /* Start new line */ 04459 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04460 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04461 first_section = 0; 04462 } 04463 if (need_encoding && *start == ' ') { 04464 ast_str_append(&tmp, -1, "_"); 04465 } else if (need_encoding) { 04466 ast_str_append(&tmp, -1, "=%hhX", *start); 04467 } else { 04468 ast_str_append(&tmp, -1, "%c", *start); 04469 } 04470 } 04471 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04472 return ast_str_buffer(*end); 04473 }
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 4370 of file app_voicemail_odbcstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04371 { 04372 const char *ptr; 04373 04374 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04375 ast_str_set(buf, maxlen, "\""); 04376 for (ptr = from; *ptr; ptr++) { 04377 if (*ptr == '"' || *ptr == '\\') { 04378 ast_str_append(buf, maxlen, "\\%c", *ptr); 04379 } else { 04380 ast_str_append(buf, maxlen, "%c", *ptr); 04381 } 04382 } 04383 ast_str_append(buf, maxlen, "\""); 04384 04385 return ast_str_buffer(*buf); 04386 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10765 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, free_user(), OPT_PWLOC_SPOOLDIR, populate_defaults(), 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, and VM_TEMPGREETWARN.
10766 { 10767 int res = 0; 10768 struct ast_vm_user *vmu; 10769 /* language parameter seems to only be used for display in manager action */ 10770 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10771 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10772 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10773 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10774 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10775 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10776 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10777 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10778 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10779 #ifdef IMAP_STORAGE 10780 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10781 "imapfolder=INBOX|imapvmshareid=6000"; 10782 #endif 10783 10784 switch (cmd) { 10785 case TEST_INIT: 10786 info->name = "vmuser"; 10787 info->category = "/apps/app_voicemail/"; 10788 info->summary = "Vmuser unit test"; 10789 info->description = 10790 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10791 return AST_TEST_NOT_RUN; 10792 case TEST_EXECUTE: 10793 break; 10794 } 10795 10796 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10797 return AST_TEST_NOT_RUN; 10798 } 10799 ast_set_flag(vmu, VM_ALLOCED); 10800 populate_defaults(vmu); 10801 10802 apply_options(vmu, options_string); 10803 10804 if (!ast_test_flag(vmu, VM_ATTACH)) { 10805 ast_test_status_update(test, "Parse failure for attach option\n"); 10806 res = 1; 10807 } 10808 if (strcasecmp(vmu->attachfmt, "wav49")) { 10809 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10810 res = 1; 10811 } 10812 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10813 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10814 res = 1; 10815 } 10816 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10817 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10818 res = 1; 10819 } 10820 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10821 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10822 res = 1; 10823 } 10824 if (strcasecmp(vmu->zonetag, "central")) { 10825 ast_test_status_update(test, "Parse failure for tz option\n"); 10826 res = 1; 10827 } 10828 if (!ast_test_flag(vmu, VM_DELETE)) { 10829 ast_test_status_update(test, "Parse failure for delete option\n"); 10830 res = 1; 10831 } 10832 if (!ast_test_flag(vmu, VM_SAYCID)) { 10833 ast_test_status_update(test, "Parse failure for saycid option\n"); 10834 res = 1; 10835 } 10836 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10837 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10838 res = 1; 10839 } 10840 if (!ast_test_flag(vmu, VM_REVIEW)) { 10841 ast_test_status_update(test, "Parse failure for review option\n"); 10842 res = 1; 10843 } 10844 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10845 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10846 res = 1; 10847 } 10848 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10849 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10850 res = 1; 10851 } 10852 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10853 ast_test_status_update(test, "Parse failure for operator option\n"); 10854 res = 1; 10855 } 10856 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10857 ast_test_status_update(test, "Parse failure for envelope option\n"); 10858 res = 1; 10859 } 10860 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10861 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10862 res = 1; 10863 } 10864 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10865 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10866 res = 1; 10867 } 10868 if (vmu->saydurationm != 5) { 10869 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10870 res = 1; 10871 } 10872 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10873 ast_test_status_update(test, "Parse failure for forcename option\n"); 10874 res = 1; 10875 } 10876 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10877 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10878 res = 1; 10879 } 10880 if (strcasecmp(vmu->callback, "somecontext")) { 10881 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10882 res = 1; 10883 } 10884 if (strcasecmp(vmu->dialout, "somecontext2")) { 10885 ast_test_status_update(test, "Parse failure for dialout option\n"); 10886 res = 1; 10887 } 10888 if (strcasecmp(vmu->exit, "somecontext3")) { 10889 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10890 res = 1; 10891 } 10892 if (vmu->minsecs != 10) { 10893 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10894 res = 1; 10895 } 10896 if (vmu->maxsecs != 100) { 10897 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10898 res = 1; 10899 } 10900 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10901 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10902 res = 1; 10903 } 10904 if (vmu->maxdeletedmsg != 50) { 10905 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10906 res = 1; 10907 } 10908 if (vmu->volgain != 1.3) { 10909 ast_test_status_update(test, "Parse failure for volgain option\n"); 10910 res = 1; 10911 } 10912 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10913 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10914 res = 1; 10915 } 10916 #ifdef IMAP_STORAGE 10917 apply_options(vmu, option_string2); 10918 10919 if (strcasecmp(vmu->imapuser, "imapuser")) { 10920 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10921 res = 1; 10922 } 10923 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10924 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10925 res = 1; 10926 } 10927 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10928 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10929 res = 1; 10930 } 10931 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10932 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10933 res = 1; 10934 } 10935 #endif 10936 10937 free_user(vmu); 10938 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10939 }
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. |
Definition at line 4246 of file app_voicemail_odbcstorage.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04247 { 04248 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04249 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04250 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04251 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04252 int i, hiteof = 0; 04253 FILE *fi; 04254 struct baseio bio; 04255 04256 memset(&bio, 0, sizeof(bio)); 04257 bio.iocp = BASEMAXINLINE; 04258 04259 if (!(fi = fopen(filename, "rb"))) { 04260 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04261 return -1; 04262 } 04263 04264 while (!hiteof){ 04265 unsigned char igroup[3], ogroup[4]; 04266 int c, n; 04267 04268 memset(igroup, 0, sizeof(igroup)); 04269 04270 for (n = 0; n < 3; n++) { 04271 if ((c = inchar(&bio, fi)) == EOF) { 04272 hiteof = 1; 04273 break; 04274 } 04275 04276 igroup[n] = (unsigned char) c; 04277 } 04278 04279 if (n > 0) { 04280 ogroup[0]= dtable[igroup[0] >> 2]; 04281 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04282 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04283 ogroup[3]= dtable[igroup[2] & 0x3F]; 04284 04285 if (n < 3) { 04286 ogroup[3] = '='; 04287 04288 if (n < 2) 04289 ogroup[2] = '='; 04290 } 04291 04292 for (i = 0; i < 4; i++) 04293 ochar(&bio, ogroup[i], so); 04294 } 04295 } 04296 04297 fclose(fi); 04298 04299 if (fputs(ENDL, so) == EOF) { 04300 return 0; 04301 } 04302 04303 return 1; 04304 }
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. |
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.
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 4415 of file app_voicemail_odbcstorage.c.
04416 { 04417 for (; *str; str++) { 04418 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04419 return 1; 04420 } 04421 } 04422 return 0; 04423 }
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().
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 7911 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_log(), AST_LOG_NOTICE, ast_test_flag, ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, 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.
07912 { 07913 int x = 0; 07914 07915 #ifndef IMAP_STORAGE 07916 int last_msg_idx; 07917 int res = 0, nummsg; 07918 char fn2[PATH_MAX]; 07919 #endif 07920 07921 if (vms->lastmsg <= -1) { 07922 goto done; 07923 } 07924 07925 vms->curmsg = -1; 07926 #ifndef IMAP_STORAGE 07927 /* Get the deleted messages fixed */ 07928 if (vm_lock_path(vms->curdir)) { 07929 return ERROR_LOCK_PATH; 07930 } 07931 07932 /* update count as message may have arrived while we've got mailbox open */ 07933 last_msg_idx = last_message_index(vmu, vms->curdir); 07934 if (last_msg_idx != vms->lastmsg) { 07935 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07936 } 07937 07938 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07939 for (x = 0; x < last_msg_idx + 1; x++) { 07940 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07941 /* Save this message. It's not in INBOX or hasn't been heard */ 07942 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07943 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07944 break; 07945 } 07946 vms->curmsg++; 07947 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07948 if (strcmp(vms->fn, fn2)) { 07949 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07950 } 07951 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07952 /* Move to old folder before deleting */ 07953 res = save_to_folder(vmu, vms, x, 1); 07954 if (res == ERROR_LOCK_PATH) { 07955 /* If save failed do not delete the message */ 07956 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07957 vms->deleted[x] = 0; 07958 vms->heard[x] = 0; 07959 --x; 07960 } 07961 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07962 /* Move to deleted folder */ 07963 res = save_to_folder(vmu, vms, x, 10); 07964 if (res == ERROR_LOCK_PATH) { 07965 /* If save failed do not delete the message */ 07966 vms->deleted[x] = 0; 07967 vms->heard[x] = 0; 07968 --x; 07969 } 07970 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07971 /* If realtime storage enabled - we should explicitly delete this message, 07972 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07973 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07974 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07975 DELETE(vms->curdir, x, vms->fn, vmu); 07976 } 07977 } 07978 } 07979 07980 /* Delete ALL remaining messages */ 07981 nummsg = x - 1; 07982 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07983 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07984 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07985 DELETE(vms->curdir, x, vms->fn, vmu); 07986 } 07987 } 07988 ast_unlock_path(vms->curdir); 07989 #else /* defined(IMAP_STORAGE) */ 07990 if (vms->deleted) { 07991 /* Since we now expunge after each delete, deleting in reverse order 07992 * ensures that no reordering occurs between each step. */ 07993 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 07994 if (vms->deleted[x]) { 07995 ast_debug(3, "IMAP delete of %d\n", x); 07996 DELETE(vms->curdir, x, vms->fn, vmu); 07997 } 07998 } 07999 } 08000 #endif 08001 08002 done: 08003 if (vms->deleted && vmu->maxmsg) { 08004 memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 08005 } 08006 if (vms->heard && vmu->maxmsg) { 08007 memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 08008 } 08009 08010 return 0; 08011 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11085 of file app_voicemail_odbcstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.
11086 { 11087 int which = 0; 11088 int wordlen; 11089 struct ast_vm_user *vmu; 11090 const char *context = ""; 11091 11092 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11093 if (pos > 4) 11094 return NULL; 11095 if (pos == 3) 11096 return (state == 0) ? ast_strdup("for") : NULL; 11097 wordlen = strlen(word); 11098 AST_LIST_TRAVERSE(&users, vmu, list) { 11099 if (!strncasecmp(word, vmu->context, wordlen)) { 11100 if (context && strcmp(context, vmu->context) && ++which > state) 11101 return ast_strdup(vmu->context); 11102 /* ignore repeated contexts ? */ 11103 context = vmu->context; 11104 } 11105 } 11106 return NULL; 11107 }
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. |
Definition at line 4050 of file app_voicemail_odbcstorage.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
04051 { 04052 int ifd; 04053 int ofd; 04054 int res; 04055 int len; 04056 char buf[4096]; 04057 04058 #ifdef HARDLINK_WHEN_POSSIBLE 04059 /* Hard link if possible; saves disk space & is faster */ 04060 if (link(infile, outfile)) { 04061 #endif 04062 if ((ifd = open(infile, O_RDONLY)) < 0) { 04063 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04064 return -1; 04065 } 04066 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04067 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04068 close(ifd); 04069 return -1; 04070 } 04071 do { 04072 len = read(ifd, buf, sizeof(buf)); 04073 if (len < 0) { 04074 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04075 close(ifd); 04076 close(ofd); 04077 unlink(outfile); 04078 } 04079 if (len) { 04080 res = write(ofd, buf, len); 04081 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04082 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04083 close(ifd); 04084 close(ofd); 04085 unlink(outfile); 04086 } 04087 } 04088 } while (len); 04089 close(ifd); 04090 close(ofd); 04091 return 0; 04092 #ifdef HARDLINK_WHEN_POSSIBLE 04093 } else { 04094 /* Hard link succeeded */ 04095 return 0; 04096 } 04097 #endif 04098 }
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 5287 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(), ast_channel::language, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), maxmsg, 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().
05288 { 05289 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05290 const char *frombox = mbox(vmu, imbox); 05291 const char *userfolder; 05292 int recipmsgnum; 05293 int res = 0; 05294 05295 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05296 05297 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05298 userfolder = "Urgent"; 05299 } else { 05300 userfolder = "INBOX"; 05301 } 05302 05303 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05304 05305 if (!dir) 05306 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05307 else 05308 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05309 05310 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05311 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05312 05313 if (vm_lock_path(todir)) 05314 return ERROR_LOCK_PATH; 05315 05316 recipmsgnum = last_message_index(recip, todir) + 1; 05317 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05318 make_file(topath, sizeof(topath), todir, recipmsgnum); 05319 #ifndef ODBC_STORAGE 05320 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05321 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05322 } else { 05323 #endif 05324 /* If we are prepending a message for ODBC, then the message already 05325 * exists in the database, but we want to force copying from the 05326 * filesystem (since only the FS contains the prepend). */ 05327 copy_plain_file(frompath, topath); 05328 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05329 vm_delete(topath); 05330 #ifndef ODBC_STORAGE 05331 } 05332 #endif 05333 } else { 05334 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05335 res = -1; 05336 } 05337 ast_unlock_path(todir); 05338 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05339 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05340 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05341 flag); 05342 05343 return res; 05344 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4109 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), exten, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04110 { 04111 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04112 struct ast_variable *tmp,*var = NULL; 04113 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04114 ast_filecopy(frompath, topath, NULL); 04115 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04116 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04117 if (ast_check_realtime("voicemail_data")) { 04118 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04119 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04120 for (tmp = var; tmp; tmp = tmp->next) { 04121 if (!strcasecmp(tmp->name, "origmailbox")) { 04122 origmailbox = tmp->value; 04123 } else if (!strcasecmp(tmp->name, "context")) { 04124 context = tmp->value; 04125 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04126 macrocontext = tmp->value; 04127 } else if (!strcasecmp(tmp->name, "exten")) { 04128 exten = tmp->value; 04129 } else if (!strcasecmp(tmp->name, "priority")) { 04130 priority = tmp->value; 04131 } else if (!strcasecmp(tmp->name, "callerchan")) { 04132 callerchan = tmp->value; 04133 } else if (!strcasecmp(tmp->name, "callerid")) { 04134 callerid = tmp->value; 04135 } else if (!strcasecmp(tmp->name, "origdate")) { 04136 origdate = tmp->value; 04137 } else if (!strcasecmp(tmp->name, "origtime")) { 04138 origtime = tmp->value; 04139 } else if (!strcasecmp(tmp->name, "category")) { 04140 category = tmp->value; 04141 } else if (!strcasecmp(tmp->name, "duration")) { 04142 duration = tmp->value; 04143 } 04144 } 04145 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); 04146 } 04147 copy(frompath2, topath2); 04148 ast_variables_destroy(var); 04149 }
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 3945 of file app_voicemail_odbcstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
03946 { 03947 03948 int vmcount = 0; 03949 DIR *vmdir = NULL; 03950 struct dirent *vment = NULL; 03951 03952 if (vm_lock_path(dir)) 03953 return ERROR_LOCK_PATH; 03954 03955 if ((vmdir = opendir(dir))) { 03956 while ((vment = readdir(vmdir))) { 03957 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03958 vmcount++; 03959 } 03960 } 03961 closedir(vmdir); 03962 } 03963 ast_unlock_path(dir); 03964 03965 return vmcount; 03966 }
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 1662 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01663 { 01664 mode_t mode = VOICEMAIL_DIR_MODE; 01665 int res; 01666 01667 make_dir(dest, len, context, ext, folder); 01668 if ((res = ast_mkdir(dest, mode))) { 01669 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01670 return -1; 01671 } 01672 return 0; 01673 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13091 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.
13092 { 13093 int cmd = 0; 13094 char destination[80] = ""; 13095 int retries = 0; 13096 13097 if (!num) { 13098 ast_verb(3, "Destination number will be entered manually\n"); 13099 while (retries < 3 && cmd != 't') { 13100 destination[1] = '\0'; 13101 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13102 if (!cmd) 13103 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13104 if (!cmd) 13105 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13106 if (!cmd) { 13107 cmd = ast_waitfordigit(chan, 6000); 13108 if (cmd) 13109 destination[0] = cmd; 13110 } 13111 if (!cmd) { 13112 retries++; 13113 } else { 13114 13115 if (cmd < 0) 13116 return 0; 13117 if (cmd == '*') { 13118 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13119 return 0; 13120 } 13121 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13122 retries++; 13123 else 13124 cmd = 't'; 13125 } 13126 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13127 } 13128 if (retries >= 3) { 13129 return 0; 13130 } 13131 13132 } else { 13133 if (option_verbose > 2) 13134 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13135 ast_copy_string(destination, num, sizeof(destination)); 13136 } 13137 13138 if (!ast_strlen_zero(destination)) { 13139 if (destination[strlen(destination) -1 ] == '*') 13140 return 0; 13141 if (option_verbose > 2) 13142 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13143 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13144 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13145 chan->priority = 0; 13146 return 9; 13147 } 13148 return 0; 13149 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10668 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, globalflags, ast_vm_user::list, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
10669 { 10670 struct ast_vm_user *vmu; 10671 10672 if (!ast_strlen_zero(box) && box[0] == '*') { 10673 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10674 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10675 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10676 "\n\tand will be ignored.\n", box, context); 10677 return NULL; 10678 } 10679 10680 AST_LIST_TRAVERSE(&users, vmu, list) { 10681 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10682 if (strcasecmp(vmu->context, context)) { 10683 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10684 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10685 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10686 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10687 } 10688 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10689 return NULL; 10690 } 10691 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10692 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10693 return NULL; 10694 } 10695 } 10696 10697 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10698 return NULL; 10699 10700 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10701 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10702 10703 AST_LIST_INSERT_TAIL(&users, vmu, list); 10704 10705 return vmu; 10706 }
static struct ast_vm_user* find_user | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static] |
Finds a voicemail user from the users file or the realtime engine.
ivm | ||
context | ||
mailbox |
Definition at line 1414 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, find_user_realtime(), globalflags, ast_vm_user::list, VM_ALLOCED, and VM_SEARCH.
01415 { 01416 /* This function could be made to generate one from a database, too */ 01417 struct ast_vm_user *vmu = NULL, *cur; 01418 AST_LIST_LOCK(&users); 01419 01420 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01421 context = "default"; 01422 01423 AST_LIST_TRAVERSE(&users, cur, list) { 01424 #ifdef IMAP_STORAGE 01425 if (cur->imapversion != imapversion) { 01426 continue; 01427 } 01428 #endif 01429 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01430 break; 01431 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01432 break; 01433 } 01434 if (cur) { 01435 /* Make a copy, so that on a reload, we have no race */ 01436 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01437 *vmu = *cur; 01438 if (!ivm) { 01439 vmu->emailbody = ast_strdup(cur->emailbody); 01440 vmu->emailsubject = ast_strdup(cur->emailsubject); 01441 } 01442 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01443 AST_LIST_NEXT(vmu, list) = NULL; 01444 } 01445 } else 01446 vmu = find_user_realtime(ivm, context, mailbox); 01447 AST_LIST_UNLOCK(&users); 01448 return vmu; 01449 }
static struct ast_vm_user* find_user_realtime | ( | struct ast_vm_user * | ivm, | |
const char * | context, | |||
const char * | mailbox | |||
) | [static] |
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(), globalflags, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
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 ast_set_flag(retval, VM_ALLOCED); 01385 else 01386 memset(retval, 0, sizeof(*retval)); 01387 if (mailbox) 01388 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01389 populate_defaults(retval); 01390 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01391 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01392 else 01393 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01394 if (var) { 01395 apply_options_full(retval, var); 01396 ast_variables_destroy(var); 01397 } else { 01398 if (!ivm) 01399 free_user(retval); 01400 retval = NULL; 01401 } 01402 } 01403 return retval; 01404 }
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 forward message mode (is_new_message == 0):
Definition at line 7116 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_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(), free_user(), globalflags, ast_party_caller::id, inboxcount(), inprocess_count(), ast_channel::language, leave_voicemail(), ast_app::list, 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, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), serveremail, STORE, ast_party_name::str, ast_party_number::str, strsep(), vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), VM_FWDURGAUTO, VM_SPOOL_DIR, and vmfmts.
07117 { 07118 #ifdef IMAP_STORAGE 07119 int todircount = 0; 07120 struct vm_state *dstvms; 07121 #endif 07122 char username[70]=""; 07123 char fn[PATH_MAX]; /* for playback of name greeting */ 07124 char ecodes[16] = "#"; 07125 int res = 0, cmd = 0; 07126 struct ast_vm_user *receiver = NULL, *vmtmp; 07127 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07128 char *stringp; 07129 const char *s; 07130 int saved_messages = 0; 07131 int valid_extensions = 0; 07132 char *dir; 07133 int curmsg; 07134 char urgent_str[7] = ""; 07135 int prompt_played = 0; 07136 #ifndef IMAP_STORAGE 07137 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07138 #endif 07139 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07140 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07141 } 07142 07143 if (vms == NULL) return -1; 07144 dir = vms->curdir; 07145 curmsg = vms->curmsg; 07146 07147 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07148 while (!res && !valid_extensions) { 07149 int use_directory = 0; 07150 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07151 int done = 0; 07152 int retries = 0; 07153 cmd = 0; 07154 while ((cmd >= 0) && !done ){ 07155 if (cmd) 07156 retries = 0; 07157 switch (cmd) { 07158 case '1': 07159 use_directory = 0; 07160 done = 1; 07161 break; 07162 case '2': 07163 use_directory = 1; 07164 done = 1; 07165 break; 07166 case '*': 07167 cmd = 't'; 07168 done = 1; 07169 break; 07170 default: 07171 /* Press 1 to enter an extension press 2 to use the directory */ 07172 cmd = ast_play_and_wait(chan, "vm-forward"); 07173 if (!cmd) { 07174 cmd = ast_waitfordigit(chan, 3000); 07175 } 07176 if (!cmd) { 07177 retries++; 07178 } 07179 if (retries > 3) { 07180 cmd = 't'; 07181 done = 1; 07182 } 07183 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07184 } 07185 } 07186 if (cmd < 0 || cmd == 't') 07187 break; 07188 } 07189 07190 if (use_directory) { 07191 /* use app_directory */ 07192 07193 char old_context[sizeof(chan->context)]; 07194 char old_exten[sizeof(chan->exten)]; 07195 int old_priority; 07196 struct ast_app* directory_app; 07197 07198 directory_app = pbx_findapp("Directory"); 07199 if (directory_app) { 07200 char vmcontext[256]; 07201 /* make backup copies */ 07202 memcpy(old_context, chan->context, sizeof(chan->context)); 07203 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07204 old_priority = chan->priority; 07205 07206 /* call the the Directory, changes the channel */ 07207 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07208 res = pbx_exec(chan, directory_app, vmcontext); 07209 07210 ast_copy_string(username, chan->exten, sizeof(username)); 07211 07212 /* restore the old context, exten, and priority */ 07213 memcpy(chan->context, old_context, sizeof(chan->context)); 07214 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07215 chan->priority = old_priority; 07216 } else { 07217 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07218 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07219 } 07220 } else { 07221 /* Ask for an extension */ 07222 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07223 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07224 prompt_played++; 07225 if (res || prompt_played > 4) 07226 break; 07227 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07228 break; 07229 } 07230 07231 /* start all over if no username */ 07232 if (ast_strlen_zero(username)) 07233 continue; 07234 stringp = username; 07235 s = strsep(&stringp, "*"); 07236 /* start optimistic */ 07237 valid_extensions = 1; 07238 while (s) { 07239 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07240 int oldmsgs; 07241 int newmsgs; 07242 int capacity; 07243 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07244 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07245 /* Shouldn't happen, but allow trying another extension if it does */ 07246 res = ast_play_and_wait(chan, "pbx-invalid"); 07247 valid_extensions = 0; 07248 break; 07249 } 07250 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07251 if ((newmsgs + oldmsgs) >= capacity) { 07252 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07253 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07254 valid_extensions = 0; 07255 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07256 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07257 free_user(vmtmp); 07258 } 07259 inprocess_count(receiver->mailbox, receiver->context, -1); 07260 break; 07261 } 07262 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07263 } else { 07264 /* XXX Optimization for the future. When we encounter a single bad extension, 07265 * bailing out on all of the extensions may not be the way to go. We should 07266 * probably just bail on that single extension, then allow the user to enter 07267 * several more. XXX 07268 */ 07269 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07270 free_user(receiver); 07271 } 07272 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07273 /* "I am sorry, that's not a valid extension. Please try again." */ 07274 res = ast_play_and_wait(chan, "pbx-invalid"); 07275 valid_extensions = 0; 07276 break; 07277 } 07278 07279 /* play name if available, else play extension number */ 07280 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07281 RETRIEVE(fn, -1, s, receiver->context); 07282 if (ast_fileexists(fn, NULL, NULL) > 0) { 07283 res = ast_stream_and_wait(chan, fn, ecodes); 07284 if (res) { 07285 DISPOSE(fn, -1); 07286 return res; 07287 } 07288 } else { 07289 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07290 } 07291 DISPOSE(fn, -1); 07292 07293 s = strsep(&stringp, "*"); 07294 } 07295 /* break from the loop of reading the extensions */ 07296 if (valid_extensions) 07297 break; 07298 } 07299 /* check if we're clear to proceed */ 07300 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07301 return res; 07302 if (is_new_message == 1) { 07303 struct leave_vm_options leave_options; 07304 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07305 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07306 07307 /* Send VoiceMail */ 07308 memset(&leave_options, 0, sizeof(leave_options)); 07309 leave_options.record_gain = record_gain; 07310 cmd = leave_voicemail(chan, mailbox, &leave_options); 07311 } else { 07312 /* Forward VoiceMail */ 07313 long duration = 0; 07314 struct vm_state vmstmp; 07315 int copy_msg_result = 0; 07316 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07317 07318 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07319 07320 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07321 if (!cmd) { 07322 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07323 #ifdef IMAP_STORAGE 07324 int attach_user_voicemail; 07325 char *myserveremail = serveremail; 07326 07327 /* get destination mailbox */ 07328 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07329 if (!dstvms) { 07330 dstvms = create_vm_state_from_user(vmtmp); 07331 } 07332 if (dstvms) { 07333 init_mailstream(dstvms, 0); 07334 if (!dstvms->mailstream) { 07335 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07336 } else { 07337 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07338 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07339 } 07340 } else { 07341 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07342 } 07343 if (!ast_strlen_zero(vmtmp->serveremail)) 07344 myserveremail = vmtmp->serveremail; 07345 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07346 /* NULL category for IMAP storage */ 07347 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07348 dstvms->curbox, 07349 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07350 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07351 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07352 NULL, urgent_str); 07353 #else 07354 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07355 #endif 07356 saved_messages++; 07357 AST_LIST_REMOVE_CURRENT(list); 07358 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07359 free_user(vmtmp); 07360 if (res) 07361 break; 07362 } 07363 AST_LIST_TRAVERSE_SAFE_END; 07364 if (saved_messages > 0 && !copy_msg_result) { 07365 /* give confirmation that the message was saved */ 07366 /* commented out since we can't forward batches yet 07367 if (saved_messages == 1) 07368 res = ast_play_and_wait(chan, "vm-message"); 07369 else 07370 res = ast_play_and_wait(chan, "vm-messages"); 07371 if (!res) 07372 res = ast_play_and_wait(chan, "vm-saved"); */ 07373 #ifdef IMAP_STORAGE 07374 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07375 if (ast_strlen_zero(vmstmp.introfn)) 07376 #endif 07377 res = ast_play_and_wait(chan, "vm-msgsaved"); 07378 } 07379 #ifndef IMAP_STORAGE 07380 else { 07381 /* with IMAP, mailbox full warning played by imap_check_limits */ 07382 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07383 } 07384 /* Restore original message without prepended message if backup exists */ 07385 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07386 strcpy(textfile, msgfile); 07387 strcpy(backup, msgfile); 07388 strcpy(backup_textfile, msgfile); 07389 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07390 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07391 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07392 if (ast_fileexists(backup, NULL, NULL) > 0) { 07393 ast_filerename(backup, msgfile, NULL); 07394 rename(backup_textfile, textfile); 07395 } 07396 #endif 07397 } 07398 DISPOSE(dir, curmsg); 07399 #ifndef IMAP_STORAGE 07400 if (cmd) { /* assuming hangup, cleanup backup file */ 07401 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07402 strcpy(textfile, msgfile); 07403 strcpy(backup_textfile, msgfile); 07404 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07405 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07406 rename(backup_textfile, textfile); 07407 } 07408 #endif 07409 } 07410 07411 /* If anything failed above, we still have this list to free */ 07412 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07413 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07414 free_user(vmtmp); 07415 } 07416 return res ? res : cmd; 07417 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1717 of file app_voicemail_odbcstorage.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01718 { 01719 if (ast_test_flag(vmu, VM_ALLOCED)) { 01720 01721 ast_free(vmu->emailbody); 01722 vmu->emailbody = NULL; 01723 01724 ast_free(vmu->emailsubject); 01725 vmu->emailsubject = NULL; 01726 01727 ast_free(vmu); 01728 } 01729 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11684 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), ast_vm_user::list, and VM_ALLOCED.
11685 { 11686 struct ast_vm_user *current; 11687 AST_LIST_LOCK(&users); 11688 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11689 ast_set_flag(current, VM_ALLOCED); 11690 free_user(current); 11691 } 11692 AST_LIST_UNLOCK(&users); 11693 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11696 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and vm_zone::list.
11697 { 11698 struct vm_zone *zcur; 11699 AST_LIST_LOCK(&zones); 11700 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11701 free_zone(zcur); 11702 AST_LIST_UNLOCK(&zones); 11703 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5055 of file app_voicemail_odbcstorage.c.
References ast_free.
05056 { 05057 ast_free(z); 05058 }
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. |
Definition at line 5011 of file app_voicemail_odbcstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05012 { 05013 struct ast_tm tm; 05014 struct timeval t = ast_tvnow(); 05015 05016 ast_localtime(&t, &tm, "UTC"); 05017 05018 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05019 }
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 6728 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(), ast_channel::language, mbox(), and vm_play_folder_name().
06729 { 06730 int x; 06731 int d; 06732 char fn[PATH_MAX]; 06733 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06734 if (d) 06735 return d; 06736 for (x = start; x < 5; x++) { /* For all folders */ 06737 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06738 return d; 06739 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06740 if (d) 06741 return d; 06742 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06743 06744 /* The inbox folder can have its name changed under certain conditions 06745 * so this checks if the sound file exists for the inbox folder name and 06746 * if it doesn't, plays the default name instead. */ 06747 if (x == 0) { 06748 if (ast_fileexists(fn, NULL, NULL)) { 06749 d = vm_play_folder_name(chan, fn); 06750 } else { 06751 ast_verb(1, "failed to find %s\n", fn); 06752 d = vm_play_folder_name(chan, "vm-INBOX"); 06753 } 06754 } else { 06755 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06756 d = vm_play_folder_name(chan, fn); 06757 } 06758 06759 if (d) 06760 return d; 06761 d = ast_waitfordigit(chan, 500); 06762 if (d) 06763 return d; 06764 } 06765 06766 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06767 if (d) 06768 return d; 06769 d = ast_waitfordigit(chan, 4000); 06770 return d; 06771 }
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. |
Definition at line 6785 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
06786 { 06787 int res = 0; 06788 int loops = 0; 06789 06790 res = ast_play_and_wait(chan, fn); /* Folder name */ 06791 while (((res < '0') || (res > '9')) && 06792 (res != '#') && (res >= 0) && 06793 loops < 4) { 06794 res = get_folder(chan, 0); 06795 loops++; 06796 } 06797 if (loops == 4) { /* give up */ 06798 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06799 return '#'; 06800 } 06801 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06802 return res; 06803 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1704 of file app_voicemail_odbcstorage.c.
References ARRAY_LEN.
01705 { 01706 size_t i; 01707 01708 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01709 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01710 return i; 01711 } 01712 } 01713 01714 return -1; 01715 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11467 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, mwi_sub, poll_subscribed_mailbox(), mwi_sub_task::uniqueid, and ast_event_sub::uniqueid.
11468 { 11469 unsigned int len; 11470 struct mwi_sub *mwi_sub; 11471 struct mwi_sub_task *p = datap; 11472 11473 len = sizeof(*mwi_sub); 11474 if (!ast_strlen_zero(p->mailbox)) 11475 len += strlen(p->mailbox); 11476 11477 if (!ast_strlen_zero(p->context)) 11478 len += strlen(p->context) + 1; /* Allow for seperator */ 11479 11480 if (!(mwi_sub = ast_calloc(1, len))) 11481 return -1; 11482 11483 mwi_sub->uniqueid = p->uniqueid; 11484 if (!ast_strlen_zero(p->mailbox)) 11485 strcpy(mwi_sub->mailbox, p->mailbox); 11486 11487 if (!ast_strlen_zero(p->context)) { 11488 strcat(mwi_sub->mailbox, "@"); 11489 strcat(mwi_sub->mailbox, p->context); 11490 } 11491 11492 AST_RWLIST_WRLOCK(&mwi_subs); 11493 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11494 AST_RWLIST_UNLOCK(&mwi_subs); 11495 ast_free((void *) p->mailbox); 11496 ast_free((void *) p->context); 11497 ast_free(p); 11498 poll_subscribed_mailbox(mwi_sub); 11499 return 0; 11500 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11445 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, mwi_sub::entry, mwi_sub, mwi_sub_destroy(), ast_event_sub::uniqueid, and mwi_sub::uniqueid.
11446 { 11447 struct mwi_sub *mwi_sub; 11448 uint32_t *uniqueid = datap; 11449 11450 AST_RWLIST_WRLOCK(&mwi_subs); 11451 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11452 if (mwi_sub->uniqueid == *uniqueid) { 11453 AST_LIST_REMOVE_CURRENT(entry); 11454 break; 11455 } 11456 } 11457 AST_RWLIST_TRAVERSE_SAFE_END 11458 AST_RWLIST_UNLOCK(&mwi_subs); 11459 11460 if (mwi_sub) 11461 mwi_sub_destroy(mwi_sub); 11462 11463 ast_free(uniqueid); 11464 return 0; 11465 }
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 11220 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.
11221 { 11222 switch (cmd) { 11223 case CLI_INIT: 11224 e->command = "voicemail reload"; 11225 e->usage = 11226 "Usage: voicemail reload\n" 11227 " Reload voicemail configuration\n"; 11228 return NULL; 11229 case CLI_GENERATE: 11230 return NULL; 11231 } 11232 11233 if (a->argc != 2) 11234 return CLI_SHOWUSAGE; 11235 11236 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11237 load_config(1); 11238 11239 return CLI_SUCCESS; 11240 }
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 11110 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::list, 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.
11111 { 11112 struct ast_vm_user *vmu; 11113 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11114 const char *context = NULL; 11115 int users_counter = 0; 11116 11117 switch (cmd) { 11118 case CLI_INIT: 11119 e->command = "voicemail show users"; 11120 e->usage = 11121 "Usage: voicemail show users [for <context>]\n" 11122 " Lists all mailboxes currently set up\n"; 11123 return NULL; 11124 case CLI_GENERATE: 11125 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11126 } 11127 11128 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11129 return CLI_SHOWUSAGE; 11130 if (a->argc == 5) { 11131 if (strcmp(a->argv[3],"for")) 11132 return CLI_SHOWUSAGE; 11133 context = a->argv[4]; 11134 } 11135 11136 if (ast_check_realtime("voicemail")) { 11137 if (!context) { 11138 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11139 return CLI_SHOWUSAGE; 11140 } 11141 return show_users_realtime(a->fd, context); 11142 } 11143 11144 AST_LIST_LOCK(&users); 11145 if (AST_LIST_EMPTY(&users)) { 11146 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11147 AST_LIST_UNLOCK(&users); 11148 return CLI_FAILURE; 11149 } 11150 if (a->argc == 3) 11151 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11152 else { 11153 int count = 0; 11154 AST_LIST_TRAVERSE(&users, vmu, list) { 11155 if (!strcmp(context, vmu->context)) 11156 count++; 11157 } 11158 if (count) { 11159 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11160 } else { 11161 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11162 AST_LIST_UNLOCK(&users); 11163 return CLI_FAILURE; 11164 } 11165 } 11166 AST_LIST_TRAVERSE(&users, vmu, list) { 11167 int newmsgs = 0, oldmsgs = 0; 11168 char count[12], tmp[256] = ""; 11169 11170 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 11171 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11172 inboxcount(tmp, &newmsgs, &oldmsgs); 11173 snprintf(count, sizeof(count), "%d", newmsgs); 11174 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11175 users_counter++; 11176 } 11177 } 11178 AST_LIST_UNLOCK(&users); 11179 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11180 return CLI_SUCCESS; 11181 }
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 11184 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, vm_zone::list, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.
11185 { 11186 struct vm_zone *zone; 11187 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11188 char *res = CLI_SUCCESS; 11189 11190 switch (cmd) { 11191 case CLI_INIT: 11192 e->command = "voicemail show zones"; 11193 e->usage = 11194 "Usage: voicemail show zones\n" 11195 " Lists zone message formats\n"; 11196 return NULL; 11197 case CLI_GENERATE: 11198 return NULL; 11199 } 11200 11201 if (a->argc != 3) 11202 return CLI_SHOWUSAGE; 11203 11204 AST_LIST_LOCK(&zones); 11205 if (!AST_LIST_EMPTY(&zones)) { 11206 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11207 AST_LIST_TRAVERSE(&zones, zone, list) { 11208 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11209 } 11210 } else { 11211 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11212 res = CLI_FAILURE; 11213 } 11214 AST_LIST_UNLOCK(&zones); 11215 11216 return res; 11217 }
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 |
Definition at line 5399 of file app_voicemail_odbcstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
05400 { 05401 char tmp[256], *tmp2 = tmp, *box, *context; 05402 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05403 if (ast_strlen_zero(folder)) { 05404 folder = "INBOX"; 05405 } 05406 while ((box = strsep(&tmp2, ",&"))) { 05407 if ((context = strchr(box, '@'))) 05408 *context++ = '\0'; 05409 else 05410 context = "default"; 05411 if (__has_voicemail(context, box, folder, 1)) 05412 return 1; 05413 /* If we are checking INBOX, we should check Urgent as well */ 05414 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05415 return 1; 05416 } 05417 } 05418 return 0; 05419 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5481 of file app_voicemail_odbcstorage.c.
References inboxcount2().
05482 { 05483 int urgentmsgs = 0; 05484 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05485 if (newmsgs) { 05486 *newmsgs += urgentmsgs; 05487 } 05488 return res; 05489 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5422 of file app_voicemail_odbcstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), inboxcount2(), and strsep().
05423 { 05424 char tmp[256]; 05425 char *context; 05426 05427 /* If no mailbox, return immediately */ 05428 if (ast_strlen_zero(mailbox)) 05429 return 0; 05430 05431 if (newmsgs) 05432 *newmsgs = 0; 05433 if (oldmsgs) 05434 *oldmsgs = 0; 05435 if (urgentmsgs) 05436 *urgentmsgs = 0; 05437 05438 if (strchr(mailbox, ',')) { 05439 int tmpnew, tmpold, tmpurgent; 05440 char *mb, *cur; 05441 05442 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05443 mb = tmp; 05444 while ((cur = strsep(&mb, ", "))) { 05445 if (!ast_strlen_zero(cur)) { 05446 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05447 return -1; 05448 else { 05449 if (newmsgs) 05450 *newmsgs += tmpnew; 05451 if (oldmsgs) 05452 *oldmsgs += tmpold; 05453 if (urgentmsgs) 05454 *urgentmsgs += tmpurgent; 05455 } 05456 } 05457 } 05458 return 0; 05459 } 05460 05461 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05462 05463 if ((context = strchr(tmp, '@'))) 05464 *context++ = '\0'; 05465 else 05466 context = "default"; 05467 05468 if (newmsgs) 05469 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05470 if (oldmsgs) 05471 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05472 if (urgentmsgs) 05473 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05474 05475 return 0; 05476 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4181 of file app_voicemail_odbcstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
04182 { 04183 int l; 04184 04185 if (bio->ateof) 04186 return 0; 04187 04188 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04189 if (ferror(fi)) 04190 return -1; 04191 04192 bio->ateof = 1; 04193 return 0; 04194 } 04195 04196 bio->iolen = l; 04197 bio->iocp = 0; 04198 04199 return 1; 04200 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4205 of file app_voicemail_odbcstorage.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
04206 { 04207 if (bio->iocp>=bio->iolen) { 04208 if (!inbuf(bio, fi)) 04209 return EOF; 04210 } 04211 04212 return bio->iobuf[bio->iocp++]; 04213 }
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.
00917 { 00918 struct inprocess *i = obj, *j = arg; 00919 if (strcmp(i->mailbox, j->mailbox)) { 00920 return 0; 00921 } 00922 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 00923 }
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_atomic_fetchadd_int(), ast_log(), inprocess::count, inprocess_container, and LOG_WARNING.
00926 { 00927 struct inprocess *i, *arg = 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] |
static int invent_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | ext, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 5021 of file app_voicemail_odbcstorage.c.
References ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, ast_channel::language, RETRIEVE, and VM_SPOOL_DIR.
05022 { 05023 int res; 05024 char fn[PATH_MAX]; 05025 char dest[PATH_MAX]; 05026 05027 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05028 05029 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05030 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05031 return -1; 05032 } 05033 05034 RETRIEVE(fn, -1, ext, context); 05035 if (ast_fileexists(fn, NULL, NULL) > 0) { 05036 res = ast_stream_and_wait(chan, fn, ecodes); 05037 if (res) { 05038 DISPOSE(fn, -1); 05039 return res; 05040 } 05041 } else { 05042 /* Dispose just in case */ 05043 DISPOSE(fn, -1); 05044 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05045 if (res) 05046 return res; 05047 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05048 if (res) 05049 return res; 05050 } 05051 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05052 return res; 05053 }
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. |
Definition at line 1352 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
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. |
Definition at line 3999 of file app_voicemail_odbcstorage.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
04000 { 04001 int x; 04002 unsigned char map[MAXMSGLIMIT] = ""; 04003 DIR *msgdir; 04004 struct dirent *msgdirent; 04005 int msgdirint; 04006 char extension[4]; 04007 int stopcount = 0; 04008 04009 /* Reading the entire directory into a file map scales better than 04010 * doing a stat repeatedly on a predicted sequence. I suspect this 04011 * is partially due to stat(2) internally doing a readdir(2) itself to 04012 * find each file. */ 04013 if (!(msgdir = opendir(dir))) { 04014 return -1; 04015 } 04016 04017 while ((msgdirent = readdir(msgdir))) { 04018 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04019 map[msgdirint] = 1; 04020 stopcount++; 04021 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04022 } 04023 } 04024 closedir(msgdir); 04025 04026 for (x = 0; x < vmu->maxmsg; x++) { 04027 if (map[x] == 1) { 04028 stopcount--; 04029 } else if (map[x] == 0 && !stopcount) { 04030 break; 04031 } 04032 } 04033 04034 return x - 1; 04035 }
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 5554 of file app_voicemail_odbcstorage.c.
References ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_exists_extension(), ast_fileexists(), ast_free, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::caller, ast_channel::context, ast_vm_user::context, create_dirpath(), DISPOSE, errno, ast_vm_user::exit, find_user(), ast_party_caller::id, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, ast_party_id::number, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), RETRIEVE, S_COR, ast_party_number::str, ast_party_number::valid, VM_OPERATOR, VM_SPOOL_DIR, and VOICEMAIL_DIR_MODE.
05555 { 05556 #ifdef IMAP_STORAGE 05557 int newmsgs, oldmsgs; 05558 #else 05559 char urgdir[PATH_MAX]; 05560 #endif 05561 char txtfile[PATH_MAX]; 05562 char tmptxtfile[PATH_MAX]; 05563 struct vm_state *vms = NULL; 05564 char callerid[256]; 05565 FILE *txt; 05566 char date[256]; 05567 int txtdes; 05568 int res = 0; 05569 int msgnum; 05570 int duration = 0; 05571 int sound_duration = 0; 05572 int ausemacro = 0; 05573 int ousemacro = 0; 05574 int ouseexten = 0; 05575 char tmpdur[16]; 05576 char priority[16]; 05577 char origtime[16]; 05578 char dir[PATH_MAX]; 05579 char tmpdir[PATH_MAX]; 05580 char fn[PATH_MAX]; 05581 char prefile[PATH_MAX] = ""; 05582 char tempfile[PATH_MAX] = ""; 05583 char ext_context[256] = ""; 05584 char fmt[80]; 05585 char *context; 05586 char ecodes[17] = "#"; 05587 struct ast_str *tmp = ast_str_create(16); 05588 char *tmpptr; 05589 struct ast_vm_user *vmu; 05590 struct ast_vm_user svm; 05591 const char *category = NULL; 05592 const char *code; 05593 const char *alldtmf = "0123456789ABCD*#"; 05594 char flag[80]; 05595 05596 if (!tmp) { 05597 return -1; 05598 } 05599 05600 ast_str_set(&tmp, 0, "%s", ext); 05601 ext = ast_str_buffer(tmp); 05602 if ((context = strchr(ext, '@'))) { 05603 *context++ = '\0'; 05604 tmpptr = strchr(context, '&'); 05605 } else { 05606 tmpptr = strchr(ext, '&'); 05607 } 05608 05609 if (tmpptr) 05610 *tmpptr++ = '\0'; 05611 05612 ast_channel_lock(chan); 05613 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05614 category = ast_strdupa(category); 05615 } 05616 ast_channel_unlock(chan); 05617 05618 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05619 ast_copy_string(flag, "Urgent", sizeof(flag)); 05620 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05621 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05622 } else { 05623 flag[0] = '\0'; 05624 } 05625 05626 ast_debug(3, "Before find_user\n"); 05627 if (!(vmu = find_user(&svm, context, ext))) { 05628 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05629 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05630 ast_free(tmp); 05631 return res; 05632 } 05633 /* Setup pre-file if appropriate */ 05634 if (strcmp(vmu->context, "default")) 05635 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05636 else 05637 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05638 05639 /* Set the path to the prefile. Will be one of 05640 VM_SPOOL_DIRcontext/ext/busy 05641 VM_SPOOL_DIRcontext/ext/unavail 05642 Depending on the flag set in options. 05643 */ 05644 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05645 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05646 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05647 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05648 } 05649 /* Set the path to the tmpfile as 05650 VM_SPOOL_DIR/context/ext/temp 05651 and attempt to create the folder structure. 05652 */ 05653 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05654 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05655 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05656 ast_free(tmp); 05657 return -1; 05658 } 05659 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05660 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05661 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05662 05663 DISPOSE(tempfile, -1); 05664 /* It's easier just to try to make it than to check for its existence */ 05665 #ifndef IMAP_STORAGE 05666 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05667 #else 05668 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05669 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05670 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05671 } 05672 #endif 05673 05674 /* Check current or macro-calling context for special extensions */ 05675 if (ast_test_flag(vmu, VM_OPERATOR)) { 05676 if (!ast_strlen_zero(vmu->exit)) { 05677 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05678 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05679 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05680 ouseexten = 1; 05681 } 05682 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05683 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05684 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05685 ouseexten = 1; 05686 } else if (!ast_strlen_zero(chan->macrocontext) 05687 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05688 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05689 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05690 ousemacro = 1; 05691 } 05692 } 05693 05694 if (!ast_strlen_zero(vmu->exit)) { 05695 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05696 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05697 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05698 } 05699 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05700 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05701 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05702 } else if (!ast_strlen_zero(chan->macrocontext) 05703 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05704 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05705 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05706 ausemacro = 1; 05707 } 05708 05709 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05710 for (code = alldtmf; *code; code++) { 05711 char e[2] = ""; 05712 e[0] = *code; 05713 if (strchr(ecodes, e[0]) == NULL 05714 && ast_canmatch_extension(chan, chan->context, e, 1, 05715 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05716 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05717 } 05718 } 05719 } 05720 05721 /* Play the beginning intro if desired */ 05722 if (!ast_strlen_zero(prefile)) { 05723 #ifdef ODBC_STORAGE 05724 int success = 05725 #endif 05726 RETRIEVE(prefile, -1, ext, context); 05727 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05728 if (ast_streamfile(chan, prefile, chan->language) > -1) 05729 res = ast_waitstream(chan, ecodes); 05730 #ifdef ODBC_STORAGE 05731 if (success == -1) { 05732 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05733 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05734 store_file(prefile, vmu->mailbox, vmu->context, -1); 05735 } 05736 #endif 05737 } else { 05738 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05739 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05740 } 05741 DISPOSE(prefile, -1); 05742 if (res < 0) { 05743 ast_debug(1, "Hang up during prefile playback\n"); 05744 free_user(vmu); 05745 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05746 ast_free(tmp); 05747 return -1; 05748 } 05749 } 05750 if (res == '#') { 05751 /* On a '#' we skip the instructions */ 05752 ast_set_flag(options, OPT_SILENT); 05753 res = 0; 05754 } 05755 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05756 if (vmu->maxmsg == 0) { 05757 if (option_debug > 2) 05758 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05759 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05760 goto leave_vm_out; 05761 } 05762 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05763 res = ast_stream_and_wait(chan, INTRO, ecodes); 05764 if (res == '#') { 05765 ast_set_flag(options, OPT_SILENT); 05766 res = 0; 05767 } 05768 } 05769 if (res > 0) 05770 ast_stopstream(chan); 05771 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05772 other than the operator -- an automated attendant or mailbox login for example */ 05773 if (res == '*') { 05774 chan->exten[0] = 'a'; 05775 chan->exten[1] = '\0'; 05776 if (!ast_strlen_zero(vmu->exit)) { 05777 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05778 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05779 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05780 } 05781 chan->priority = 0; 05782 free_user(vmu); 05783 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05784 ast_free(tmp); 05785 return 0; 05786 } 05787 05788 /* Check for a '0' here */ 05789 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05790 transfer: 05791 if (ouseexten || ousemacro) { 05792 chan->exten[0] = 'o'; 05793 chan->exten[1] = '\0'; 05794 if (!ast_strlen_zero(vmu->exit)) { 05795 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05796 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05797 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05798 } 05799 ast_play_and_wait(chan, "transfer"); 05800 chan->priority = 0; 05801 free_user(vmu); 05802 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05803 } 05804 ast_free(tmp); 05805 return OPERATOR_EXIT; 05806 } 05807 05808 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05809 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05810 if (!ast_strlen_zero(options->exitcontext)) 05811 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05812 free_user(vmu); 05813 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05814 ast_free(tmp); 05815 return res; 05816 } 05817 05818 if (res < 0) { 05819 free_user(vmu); 05820 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05821 ast_free(tmp); 05822 return -1; 05823 } 05824 /* The meat of recording the message... All the announcements and beeps have been played*/ 05825 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05826 if (!ast_strlen_zero(fmt)) { 05827 msgnum = 0; 05828 05829 #ifdef IMAP_STORAGE 05830 /* Is ext a mailbox? */ 05831 /* must open stream for this user to get info! */ 05832 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05833 if (res < 0) { 05834 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05835 ast_free(tmp); 05836 return -1; 05837 } 05838 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05839 /* It is possible under certain circumstances that inboxcount did not 05840 * create a vm_state when it was needed. This is a catchall which will 05841 * rarely be used. 05842 */ 05843 if (!(vms = create_vm_state_from_user(vmu))) { 05844 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05845 ast_free(tmp); 05846 return -1; 05847 } 05848 } 05849 vms->newmessages++; 05850 05851 /* here is a big difference! We add one to it later */ 05852 msgnum = newmsgs + oldmsgs; 05853 ast_debug(3, "Messagecount set to %d\n", msgnum); 05854 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05855 /* set variable for compatibility */ 05856 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05857 05858 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05859 goto leave_vm_out; 05860 } 05861 #else 05862 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05863 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05864 if (!res) 05865 res = ast_waitstream(chan, ""); 05866 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05867 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05868 inprocess_count(vmu->mailbox, vmu->context, -1); 05869 goto leave_vm_out; 05870 } 05871 05872 #endif 05873 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05874 txtdes = mkstemp(tmptxtfile); 05875 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05876 if (txtdes < 0) { 05877 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05878 if (!res) 05879 res = ast_waitstream(chan, ""); 05880 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05881 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05882 inprocess_count(vmu->mailbox, vmu->context, -1); 05883 goto leave_vm_out; 05884 } 05885 05886 /* Now play the beep once we have the message number for our next message. */ 05887 if (res >= 0) { 05888 /* Unless we're *really* silent, try to send the beep */ 05889 res = ast_stream_and_wait(chan, "beep", ""); 05890 } 05891 05892 /* Store information in real-time storage */ 05893 if (ast_check_realtime("voicemail_data")) { 05894 snprintf(priority, sizeof(priority), "%d", chan->priority); 05895 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05896 get_date(date, sizeof(date)); 05897 ast_callerid_merge(callerid, sizeof(callerid), 05898 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05899 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05900 "Unknown"); 05901 ast_store_realtime("voicemail_data", 05902 "origmailbox", ext, 05903 "context", chan->context, 05904 "macrocontext", chan->macrocontext, 05905 "exten", chan->exten, 05906 "priority", priority, 05907 "callerchan", chan->name, 05908 "callerid", callerid, 05909 "origdate", date, 05910 "origtime", origtime, 05911 "category", S_OR(category, ""), 05912 "filename", tmptxtfile, 05913 SENTINEL); 05914 } 05915 05916 /* Store information */ 05917 txt = fdopen(txtdes, "w+"); 05918 if (txt) { 05919 get_date(date, sizeof(date)); 05920 ast_callerid_merge(callerid, sizeof(callerid), 05921 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05922 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05923 "Unknown"); 05924 fprintf(txt, 05925 ";\n" 05926 "; Message Information file\n" 05927 ";\n" 05928 "[message]\n" 05929 "origmailbox=%s\n" 05930 "context=%s\n" 05931 "macrocontext=%s\n" 05932 "exten=%s\n" 05933 "rdnis=%s\n" 05934 "priority=%d\n" 05935 "callerchan=%s\n" 05936 "callerid=%s\n" 05937 "origdate=%s\n" 05938 "origtime=%ld\n" 05939 "category=%s\n", 05940 ext, 05941 chan->context, 05942 chan->macrocontext, 05943 chan->exten, 05944 S_COR(chan->redirecting.from.number.valid, 05945 chan->redirecting.from.number.str, "unknown"), 05946 chan->priority, 05947 chan->name, 05948 callerid, 05949 date, (long) time(NULL), 05950 category ? category : ""); 05951 } else { 05952 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05953 inprocess_count(vmu->mailbox, vmu->context, -1); 05954 if (ast_check_realtime("voicemail_data")) { 05955 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05956 } 05957 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05958 goto leave_vm_out; 05959 } 05960 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05961 05962 if (txt) { 05963 fprintf(txt, "flag=%s\n", flag); 05964 if (sound_duration < vmu->minsecs) { 05965 fclose(txt); 05966 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 05967 ast_filedelete(tmptxtfile, NULL); 05968 unlink(tmptxtfile); 05969 if (ast_check_realtime("voicemail_data")) { 05970 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05971 } 05972 inprocess_count(vmu->mailbox, vmu->context, -1); 05973 } else { 05974 fprintf(txt, "duration=%d\n", duration); 05975 fclose(txt); 05976 if (vm_lock_path(dir)) { 05977 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05978 /* Delete files */ 05979 ast_filedelete(tmptxtfile, NULL); 05980 unlink(tmptxtfile); 05981 inprocess_count(vmu->mailbox, vmu->context, -1); 05982 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05983 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05984 unlink(tmptxtfile); 05985 ast_unlock_path(dir); 05986 inprocess_count(vmu->mailbox, vmu->context, -1); 05987 if (ast_check_realtime("voicemail_data")) { 05988 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05989 } 05990 } else { 05991 #ifndef IMAP_STORAGE 05992 msgnum = last_message_index(vmu, dir) + 1; 05993 #endif 05994 make_file(fn, sizeof(fn), dir, msgnum); 05995 05996 /* assign a variable with the name of the voicemail file */ 05997 #ifndef IMAP_STORAGE 05998 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05999 #else 06000 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06001 #endif 06002 06003 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06004 ast_filerename(tmptxtfile, fn, NULL); 06005 rename(tmptxtfile, txtfile); 06006 inprocess_count(vmu->mailbox, vmu->context, -1); 06007 06008 /* Properly set permissions on voicemail text descriptor file. 06009 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06010 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06011 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06012 06013 ast_unlock_path(dir); 06014 if (ast_check_realtime("voicemail_data")) { 06015 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06016 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06017 } 06018 /* We must store the file first, before copying the message, because 06019 * ODBC storage does the entire copy with SQL. 06020 */ 06021 if (ast_fileexists(fn, NULL, NULL) > 0) { 06022 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06023 } 06024 06025 /* Are there to be more recipients of this message? */ 06026 while (tmpptr) { 06027 struct ast_vm_user recipu, *recip; 06028 char *exten, *cntx; 06029 06030 exten = strsep(&tmpptr, "&"); 06031 cntx = strchr(exten, '@'); 06032 if (cntx) { 06033 *cntx = '\0'; 06034 cntx++; 06035 } 06036 if ((recip = find_user(&recipu, cntx, exten))) { 06037 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06038 free_user(recip); 06039 } 06040 } 06041 #ifndef IMAP_STORAGE 06042 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06043 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06044 char sfn[PATH_MAX]; 06045 char dfn[PATH_MAX]; 06046 int x; 06047 /* It's easier just to try to make it than to check for its existence */ 06048 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06049 x = last_message_index(vmu, urgdir) + 1; 06050 make_file(sfn, sizeof(sfn), dir, msgnum); 06051 make_file(dfn, sizeof(dfn), urgdir, x); 06052 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06053 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06054 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06055 ast_copy_string(fn, dfn, sizeof(fn)); 06056 msgnum = x; 06057 } 06058 #endif 06059 /* Notification needs to happen after the copy, though. */ 06060 if (ast_fileexists(fn, NULL, NULL)) { 06061 #ifdef IMAP_STORAGE 06062 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06063 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06064 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06065 flag); 06066 #else 06067 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06068 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06069 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06070 flag); 06071 #endif 06072 } 06073 06074 /* Disposal needs to happen after the optional move and copy */ 06075 if (ast_fileexists(fn, NULL, NULL)) { 06076 DISPOSE(dir, msgnum); 06077 } 06078 } 06079 } 06080 } else { 06081 inprocess_count(vmu->mailbox, vmu->context, -1); 06082 } 06083 if (res == '0') { 06084 goto transfer; 06085 } else if (res > 0 && res != 't') 06086 res = 0; 06087 06088 if (sound_duration < vmu->minsecs) 06089 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06090 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06091 else 06092 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06093 } else 06094 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06095 leave_vm_out: 06096 free_user(vmu); 06097 06098 #ifdef IMAP_STORAGE 06099 /* expunge message - use UID Expunge if supported on IMAP server*/ 06100 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06101 if (expungeonhangup == 1) { 06102 ast_mutex_lock(&vms->lock); 06103 #ifdef HAVE_IMAP_TK2006 06104 if (LEVELUIDPLUS (vms->mailstream)) { 06105 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06106 } else 06107 #endif 06108 mail_expunge(vms->mailstream); 06109 ast_mutex_unlock(&vms->lock); 06110 } 06111 #endif 06112 06113 ast_free(tmp); 06114 return res; 06115 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11752 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_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
11753 { 11754 struct ast_config *cfg, *ucfg; 11755 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11756 int res; 11757 11758 ast_unload_realtime("voicemail"); 11759 ast_unload_realtime("voicemail_data"); 11760 11761 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11762 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11763 return 0; 11764 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11765 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11766 ucfg = NULL; 11767 } 11768 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11769 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11770 ast_config_destroy(ucfg); 11771 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11772 return 0; 11773 } 11774 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11775 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11776 return 0; 11777 } else { 11778 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11779 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11780 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11781 ucfg = NULL; 11782 } 11783 } 11784 11785 res = actual_load_config(reload, cfg, ucfg); 11786 11787 ast_config_destroy(cfg); 11788 ast_config_destroy(ucfg); 11789 11790 return res; 11791 }
static int load_module | ( | void | ) | [static] |
Definition at line 13043 of file app_voicemail_odbcstorage.c.
References ao2_container_alloc, app, app2, app3, app4, 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_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_container, inprocess_hash_fn(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, my_umask, RQ_CHAR, RQ_UINTEGER3, sayname(), sayname_app, SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), VM_SPOOL_DIR, vmauthenticate(), and vmsayname_exec().
13044 { 13045 int res; 13046 my_umask = umask(0); 13047 umask(my_umask); 13048 13049 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13050 return AST_MODULE_LOAD_DECLINE; 13051 } 13052 13053 /* compute the location of the voicemail spool directory */ 13054 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13055 13056 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13057 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13058 } 13059 13060 if ((res = load_config(0))) 13061 return res; 13062 13063 res = ast_register_application_xml(app, vm_exec); 13064 res |= ast_register_application_xml(app2, vm_execmain); 13065 res |= ast_register_application_xml(app3, vm_box_exists); 13066 res |= ast_register_application_xml(app4, vmauthenticate); 13067 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13068 res |= ast_custom_function_register(&mailbox_exists_acf); 13069 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13070 #ifdef TEST_FRAMEWORK 13071 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13072 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13073 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13074 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13075 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13076 #endif 13077 13078 if (res) 13079 return res; 13080 13081 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13082 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13083 13084 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13085 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13086 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13087 13088 return res; 13089 }
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 |
Definition at line 1616 of file app_voicemail_odbcstorage.c.
References VM_SPOOL_DIR.
01617 { 01618 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01619 }
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 4498 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_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_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
04499 { 04500 char date[256]; 04501 char host[MAXHOSTNAMELEN] = ""; 04502 char who[256]; 04503 char bound[256]; 04504 char dur[256]; 04505 struct ast_tm tm; 04506 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04507 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04508 char *greeting_attachment; 04509 char filename[256]; 04510 04511 if (!str1 || !str2) { 04512 ast_free(str1); 04513 ast_free(str2); 04514 return; 04515 } 04516 04517 if (cidnum) { 04518 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04519 } 04520 if (cidname) { 04521 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04522 } 04523 gethostname(host, sizeof(host) - 1); 04524 04525 if (strchr(srcemail, '@')) { 04526 ast_copy_string(who, srcemail, sizeof(who)); 04527 } else { 04528 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04529 } 04530 04531 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04532 if (greeting_attachment) { 04533 *greeting_attachment++ = '\0'; 04534 } 04535 04536 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04537 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04538 fprintf(p, "Date: %s" ENDL, date); 04539 04540 /* Set date format for voicemail mail */ 04541 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04542 04543 if (!ast_strlen_zero(fromstring)) { 04544 struct ast_channel *ast; 04545 if ((ast = ast_dummy_channel_alloc())) { 04546 char *ptr; 04547 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04548 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04549 04550 if (check_mime(ast_str_buffer(str1))) { 04551 int first_line = 1; 04552 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04553 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04554 *ptr = '\0'; 04555 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04556 first_line = 0; 04557 /* Substring is smaller, so this will never grow */ 04558 ast_str_set(&str2, 0, "%s", ptr + 1); 04559 } 04560 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04561 } else { 04562 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04563 } 04564 ast = ast_channel_unref(ast); 04565 } else { 04566 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04567 } 04568 } else { 04569 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04570 } 04571 04572 if (check_mime(vmu->fullname)) { 04573 int first_line = 1; 04574 char *ptr; 04575 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04576 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04577 *ptr = '\0'; 04578 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04579 first_line = 0; 04580 /* Substring is smaller, so this will never grow */ 04581 ast_str_set(&str2, 0, "%s", ptr + 1); 04582 } 04583 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04584 } else { 04585 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04586 } 04587 04588 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04589 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04590 struct ast_channel *ast; 04591 if ((ast = ast_dummy_channel_alloc())) { 04592 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04593 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04594 if (check_mime(ast_str_buffer(str1))) { 04595 int first_line = 1; 04596 char *ptr; 04597 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04598 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04599 *ptr = '\0'; 04600 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04601 first_line = 0; 04602 /* Substring is smaller, so this will never grow */ 04603 ast_str_set(&str2, 0, "%s", ptr + 1); 04604 } 04605 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04606 } else { 04607 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04608 } 04609 ast = ast_channel_unref(ast); 04610 } else { 04611 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04612 } 04613 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04614 if (ast_strlen_zero(flag)) { 04615 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04616 } else { 04617 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04618 } 04619 } else { 04620 if (ast_strlen_zero(flag)) { 04621 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04622 } else { 04623 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04624 } 04625 } 04626 04627 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04628 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04629 if (imap) { 04630 /* additional information needed for IMAP searching */ 04631 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04632 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04633 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04634 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04635 #ifdef IMAP_STORAGE 04636 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04637 #else 04638 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04639 #endif 04640 /* flag added for Urgent */ 04641 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04642 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04643 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04644 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04645 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04646 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04647 if (!ast_strlen_zero(category)) { 04648 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04649 } else { 04650 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04651 } 04652 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04653 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04654 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04655 } 04656 if (!ast_strlen_zero(cidnum)) { 04657 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04658 } 04659 if (!ast_strlen_zero(cidname)) { 04660 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04661 } 04662 fprintf(p, "MIME-Version: 1.0" ENDL); 04663 if (attach_user_voicemail) { 04664 /* Something unique. */ 04665 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04666 (int) getpid(), (unsigned int) ast_random()); 04667 04668 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04669 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04670 fprintf(p, "--%s" ENDL, bound); 04671 } 04672 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04673 if (emailbody || vmu->emailbody) { 04674 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04675 struct ast_channel *ast; 04676 if ((ast = ast_dummy_channel_alloc())) { 04677 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04678 ast_str_substitute_variables(&str1, 0, ast, e_body); 04679 #ifdef IMAP_STORAGE 04680 { 04681 /* Convert body to native line terminators for IMAP backend */ 04682 char *line = ast_str_buffer(str1), *next; 04683 do { 04684 /* Terminate line before outputting it to the file */ 04685 if ((next = strchr(line, '\n'))) { 04686 *next++ = '\0'; 04687 } 04688 fprintf(p, "%s" ENDL, line); 04689 line = next; 04690 } while (!ast_strlen_zero(line)); 04691 } 04692 #else 04693 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04694 #endif 04695 ast = ast_channel_unref(ast); 04696 } else { 04697 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04698 } 04699 } else if (msgnum > -1) { 04700 if (strcmp(vmu->mailbox, mailbox)) { 04701 /* Forwarded type */ 04702 struct ast_config *msg_cfg; 04703 const char *v; 04704 int inttime; 04705 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04706 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04707 /* Retrieve info from VM attribute file */ 04708 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04709 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04710 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04711 strcat(fromfile, ".txt"); 04712 } 04713 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04714 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04715 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04716 } 04717 04718 /* You might be tempted to do origdate, except that a) it's in the wrong 04719 * format, and b) it's missing for IMAP recordings. */ 04720 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04721 struct timeval tv = { inttime, }; 04722 struct ast_tm tm; 04723 ast_localtime(&tv, &tm, NULL); 04724 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04725 } 04726 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04727 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04728 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04729 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04730 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04731 date, origcallerid, origdate); 04732 ast_config_destroy(msg_cfg); 04733 } else { 04734 goto plain_message; 04735 } 04736 } else { 04737 plain_message: 04738 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04739 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04740 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04741 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04742 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04743 } 04744 } else { 04745 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04746 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04747 } 04748 04749 if (imap || attach_user_voicemail) { 04750 if (!ast_strlen_zero(attach2)) { 04751 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04752 ast_debug(5, "creating second attachment filename %s\n", filename); 04753 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04754 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04755 ast_debug(5, "creating attachment filename %s\n", filename); 04756 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04757 } else { 04758 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04759 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04760 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04761 } 04762 } 04763 ast_free(str1); 04764 ast_free(str2); 04765 }
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 |
Definition at line 1633 of file app_voicemail_odbcstorage.c.
01634 { 01635 return snprintf(dest, len, "%s/msg%04d", dir, num); 01636 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11583 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::list, ast_vm_user::mailbox, ast_vm_user::mailcmd, 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.
11584 { 11585 struct ast_vm_user *vmu = NULL; 11586 const char *id = astman_get_header(m, "ActionID"); 11587 char actionid[128] = ""; 11588 11589 if (!ast_strlen_zero(id)) 11590 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11591 11592 AST_LIST_LOCK(&users); 11593 11594 if (AST_LIST_EMPTY(&users)) { 11595 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11596 AST_LIST_UNLOCK(&users); 11597 return RESULT_SUCCESS; 11598 } 11599 11600 astman_send_ack(s, m, "Voicemail user list will follow"); 11601 11602 AST_LIST_TRAVERSE(&users, vmu, list) { 11603 char dirname[256]; 11604 11605 #ifdef IMAP_STORAGE 11606 int new, old; 11607 inboxcount(vmu->mailbox, &new, &old); 11608 #endif 11609 11610 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11611 astman_append(s, 11612 "%s" 11613 "Event: VoicemailUserEntry\r\n" 11614 "VMContext: %s\r\n" 11615 "VoiceMailbox: %s\r\n" 11616 "Fullname: %s\r\n" 11617 "Email: %s\r\n" 11618 "Pager: %s\r\n" 11619 "ServerEmail: %s\r\n" 11620 "MailCommand: %s\r\n" 11621 "Language: %s\r\n" 11622 "TimeZone: %s\r\n" 11623 "Callback: %s\r\n" 11624 "Dialout: %s\r\n" 11625 "UniqueID: %s\r\n" 11626 "ExitContext: %s\r\n" 11627 "SayDurationMinimum: %d\r\n" 11628 "SayEnvelope: %s\r\n" 11629 "SayCID: %s\r\n" 11630 "AttachMessage: %s\r\n" 11631 "AttachmentFormat: %s\r\n" 11632 "DeleteMessage: %s\r\n" 11633 "VolumeGain: %.2f\r\n" 11634 "CanReview: %s\r\n" 11635 "CallOperator: %s\r\n" 11636 "MaxMessageCount: %d\r\n" 11637 "MaxMessageLength: %d\r\n" 11638 "NewMessageCount: %d\r\n" 11639 #ifdef IMAP_STORAGE 11640 "OldMessageCount: %d\r\n" 11641 "IMAPUser: %s\r\n" 11642 #endif 11643 "\r\n", 11644 actionid, 11645 vmu->context, 11646 vmu->mailbox, 11647 vmu->fullname, 11648 vmu->email, 11649 vmu->pager, 11650 vmu->serveremail, 11651 vmu->mailcmd, 11652 vmu->language, 11653 vmu->zonetag, 11654 vmu->callback, 11655 vmu->dialout, 11656 vmu->uniqueid, 11657 vmu->exit, 11658 vmu->saydurationm, 11659 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11660 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11661 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11662 vmu->attachfmt, 11663 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11664 vmu->volgain, 11665 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11666 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11667 vmu->maxmsg, 11668 vmu->maxsecs, 11669 #ifdef IMAP_STORAGE 11670 new, old, vmu->imapuser 11671 #else 11672 count_messages(vmu, dirname) 11673 #endif 11674 ); 11675 } 11676 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11677 11678 AST_LIST_UNLOCK(&users); 11679 11680 return RESULT_SUCCESS; 11681 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11417 of file app_voicemail_odbcstorage.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_cond, poll_freq, poll_lock, poll_subscribed_mailboxes(), and poll_thread_run.
11418 { 11419 while (poll_thread_run) { 11420 struct timespec ts = { 0, }; 11421 struct timeval wait; 11422 11423 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11424 ts.tv_sec = wait.tv_sec; 11425 ts.tv_nsec = wait.tv_usec * 1000; 11426 11427 ast_mutex_lock(&poll_lock); 11428 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11429 ast_mutex_unlock(&poll_lock); 11430 11431 if (!poll_thread_run) 11432 break; 11433 11434 poll_subscribed_mailboxes(); 11435 } 11436 11437 return NULL; 11438 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1694 of file app_voicemail_odbcstorage.c.
References ARRAY_LEN.
01695 { 01696 #ifdef IMAP_STORAGE 01697 if (vmu && id == 0) { 01698 return vmu->imapfolder; 01699 } 01700 #endif 01701 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01702 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5348 of file app_voicemail_odbcstorage.c.
References __has_voicemail().
05349 { 05350 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05351 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11518 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(), handle_subscribe(), LOG_ERROR, and mwi_subscription_tps.
11519 { 11520 struct mwi_sub_task *mwist; 11521 11522 if (ast_event_get_type(event) != AST_EVENT_SUB) 11523 return; 11524 11525 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11526 return; 11527 11528 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11529 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11530 return; 11531 } 11532 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11533 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11534 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11535 11536 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11537 ast_free(mwist); 11538 } 11539 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11502 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_taskprocessor_push(), handle_unsubscribe(), mwi_subscription_tps, and mwi_sub_task::uniqueid.
11503 { 11504 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11505 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11506 return; 11507 11508 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11509 return; 11510 11511 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11512 *uniqueid = u; 11513 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11514 ast_free(uniqueid); 11515 } 11516 }
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 7013 of file app_voicemail_odbcstorage.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), 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, serveremail, strsep(), VM_ATTACH, vm_delete(), VM_DELETE, and VM_SPOOL_DIR.
07014 { 07015 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07016 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07017 const char *category; 07018 char *myserveremail = serveremail; 07019 07020 ast_channel_lock(chan); 07021 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07022 category = ast_strdupa(category); 07023 } 07024 ast_channel_unlock(chan); 07025 07026 #ifndef IMAP_STORAGE 07027 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07028 #else 07029 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07030 #endif 07031 make_file(fn, sizeof(fn), todir, msgnum); 07032 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07033 07034 if (!ast_strlen_zero(vmu->attachfmt)) { 07035 if (strstr(fmt, vmu->attachfmt)) 07036 fmt = vmu->attachfmt; 07037 else 07038 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); 07039 } 07040 07041 /* Attach only the first format */ 07042 fmt = ast_strdupa(fmt); 07043 stringp = fmt; 07044 strsep(&stringp, "|"); 07045 07046 if (!ast_strlen_zero(vmu->serveremail)) 07047 myserveremail = vmu->serveremail; 07048 07049 if (!ast_strlen_zero(vmu->email)) { 07050 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07051 07052 if (attach_user_voicemail) 07053 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07054 07055 /* XXX possible imap issue, should category be NULL XXX */ 07056 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07057 07058 if (attach_user_voicemail) 07059 DISPOSE(todir, msgnum); 07060 } 07061 07062 if (!ast_strlen_zero(vmu->pager)) { 07063 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07064 } 07065 07066 if (ast_test_flag(vmu, VM_DELETE)) 07067 DELETE(todir, msgnum, fn, vmu); 07068 07069 /* Leave voicemail for someone */ 07070 if (ast_app_has_voicemail(ext_context, NULL)) 07071 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07072 07073 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07074 07075 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); 07076 run_externnotify(vmu->context, vmu->mailbox, flag); 07077 07078 #ifdef IMAP_STORAGE 07079 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07080 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07081 vm_imap_delete(NULL, vms->curmsg, vmu); 07082 vms->newmessages--; /* Fix new message count */ 07083 } 07084 #endif 07085 07086 return 0; 07087 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4218 of file app_voicemail_odbcstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
04219 { 04220 if (bio->linelength >= BASELINELEN) { 04221 if (fputs(ENDL, so) == EOF) { 04222 return -1; 04223 } 04224 04225 bio->linelength = 0; 04226 } 04227 04228 if (putc(((unsigned char) c), so) == EOF) { 04229 return -1; 04230 } 04231 04232 bio->linelength++; 04233 04234 return 1; 04235 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7858 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.
07859 { 07860 int count_msg, last_msg; 07861 07862 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07863 07864 /* Rename the member vmbox HERE so that we don't try to return before 07865 * we know what's going on. 07866 */ 07867 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07868 07869 /* Faster to make the directory than to check if it exists. */ 07870 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07871 07872 /* traverses directory using readdir (or select query for ODBC) */ 07873 count_msg = count_messages(vmu, vms->curdir); 07874 if (count_msg < 0) { 07875 return count_msg; 07876 } else { 07877 vms->lastmsg = count_msg - 1; 07878 } 07879 07880 if (vm_allocate_dh(vms, vmu, count_msg)) { 07881 return -1; 07882 } 07883 07884 /* 07885 The following test is needed in case sequencing gets messed up. 07886 There appears to be more than one way to mess up sequence, so 07887 we will not try to find all of the root causes--just fix it when 07888 detected. 07889 */ 07890 07891 if (vm_lock_path(vms->curdir)) { 07892 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07893 return ERROR_LOCK_PATH; 07894 } 07895 07896 /* for local storage, checks directory for messages up to maxmsg limit */ 07897 last_msg = last_message_index(vmu, vms->curdir); 07898 ast_unlock_path(vms->curdir); 07899 07900 if (last_msg < -1) { 07901 return last_msg; 07902 } else if (vms->lastmsg != last_msg) { 07903 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); 07904 resequence_mailbox(vmu, vms->curdir, count_msg); 07905 } 07906 07907 return 0; 07908 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7636 of file app_voicemail_odbcstorage.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, ast_channel::language, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
07637 { 07638 int res = 0; 07639 char filename[256], *cid; 07640 const char *origtime, *context, *category, *duration, *flag; 07641 struct ast_config *msg_cfg; 07642 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07643 07644 vms->starting = 0; 07645 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07646 adsi_message(chan, vms); 07647 if (!vms->curmsg) { 07648 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07649 } else if (vms->curmsg == vms->lastmsg) { 07650 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07651 } 07652 07653 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07654 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07655 msg_cfg = ast_config_load(filename, config_flags); 07656 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07657 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07658 return 0; 07659 } 07660 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07661 07662 /* Play the word urgent if we are listening to urgent messages */ 07663 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07664 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07665 } 07666 07667 if (!res) { 07668 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07669 /* POLISH syntax */ 07670 if (!strncasecmp(chan->language, "pl", 2)) { 07671 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07672 int ten, one; 07673 char nextmsg[256]; 07674 ten = (vms->curmsg + 1) / 10; 07675 one = (vms->curmsg + 1) % 10; 07676 07677 if (vms->curmsg < 20) { 07678 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07679 res = wait_file2(chan, vms, nextmsg); 07680 } else { 07681 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07682 res = wait_file2(chan, vms, nextmsg); 07683 if (one > 0) { 07684 if (!res) { 07685 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07686 res = wait_file2(chan, vms, nextmsg); 07687 } 07688 } 07689 } 07690 } 07691 if (!res) 07692 res = wait_file2(chan, vms, "vm-message"); 07693 /* HEBREW syntax */ 07694 } else if (!strncasecmp(chan->language, "he", 2)) { 07695 if (!vms->curmsg) { 07696 res = wait_file2(chan, vms, "vm-message"); 07697 res = wait_file2(chan, vms, "vm-first"); 07698 } else if (vms->curmsg == vms->lastmsg) { 07699 res = wait_file2(chan, vms, "vm-message"); 07700 res = wait_file2(chan, vms, "vm-last"); 07701 } else { 07702 res = wait_file2(chan, vms, "vm-message"); 07703 res = wait_file2(chan, vms, "vm-number"); 07704 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07705 } 07706 /* VIETNAMESE syntax */ 07707 } else if (!strncasecmp(chan->language, "vi", 2)) { 07708 if (!vms->curmsg) { 07709 res = wait_file2(chan, vms, "vm-message"); 07710 res = wait_file2(chan, vms, "vm-first"); 07711 } else if (vms->curmsg == vms->lastmsg) { 07712 res = wait_file2(chan, vms, "vm-message"); 07713 res = wait_file2(chan, vms, "vm-last"); 07714 } else { 07715 res = wait_file2(chan, vms, "vm-message"); 07716 res = wait_file2(chan, vms, "vm-number"); 07717 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07718 } 07719 } else { 07720 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07721 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07722 } else { /* DEFAULT syntax */ 07723 res = wait_file2(chan, vms, "vm-message"); 07724 } 07725 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07726 if (!res) { 07727 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07728 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07729 } 07730 } 07731 } 07732 } 07733 07734 if (!msg_cfg) { 07735 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07736 return 0; 07737 } 07738 07739 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07740 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07741 DISPOSE(vms->curdir, vms->curmsg); 07742 ast_config_destroy(msg_cfg); 07743 return 0; 07744 } 07745 07746 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07747 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07748 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07749 07750 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07751 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07752 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07753 if (!res) { 07754 res = play_message_category(chan, category); 07755 } 07756 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07757 res = play_message_datetime(chan, vmu, origtime, filename); 07758 } 07759 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07760 res = play_message_callerid(chan, vms, cid, context, 0); 07761 } 07762 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07763 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07764 } 07765 /* Allow pressing '1' to skip envelope / callerid */ 07766 if (res == '1') { 07767 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07768 res = 0; 07769 } 07770 ast_config_destroy(msg_cfg); 07771 07772 if (!res) { 07773 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07774 vms->heard[vms->curmsg] = 1; 07775 #ifdef IMAP_STORAGE 07776 /*IMAP storage stores any prepended message from a forward 07777 * as a separate file from the rest of the message 07778 */ 07779 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07780 wait_file(chan, vms, vms->introfn); 07781 } 07782 #endif 07783 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07784 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07785 res = 0; 07786 } 07787 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07788 } 07789 DISPOSE(vms->curdir, vms->curmsg); 07790 return res; 07791 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7522 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, cidinternalcontexts, ast_channel::language, MAX_NUM_CID_CONTEXTS, name, VM_SPOOL_DIR, and wait_file2().
07523 { 07524 int res = 0; 07525 int i; 07526 char *callerid, *name; 07527 char prefile[PATH_MAX] = ""; 07528 07529 07530 /* If voicemail cid is not enabled, or we didn't get cid or context from 07531 * the attribute file, leave now. 07532 * 07533 * TODO Still need to change this so that if this function is called by the 07534 * message envelope (and someone is explicitly requesting to hear the CID), 07535 * it does not check to see if CID is enabled in the config file. 07536 */ 07537 if ((cid == NULL)||(context == NULL)) 07538 return res; 07539 07540 /* Strip off caller ID number from name */ 07541 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07542 ast_callerid_parse(cid, &name, &callerid); 07543 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07544 /* Check for internal contexts and only */ 07545 /* say extension when the call didn't come from an internal context in the list */ 07546 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07547 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07548 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07549 break; 07550 } 07551 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07552 if (!res) { 07553 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07554 if (!ast_strlen_zero(prefile)) { 07555 /* See if we can find a recorded name for this person instead of their extension number */ 07556 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07557 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07558 if (!callback) 07559 res = wait_file2(chan, vms, "vm-from"); 07560 res = ast_stream_and_wait(chan, prefile, ""); 07561 } else { 07562 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07563 /* Say "from extension" as one saying to sound smoother */ 07564 if (!callback) 07565 res = wait_file2(chan, vms, "vm-from-extension"); 07566 res = ast_say_digit_str(chan, callerid, "", chan->language); 07567 } 07568 } 07569 } 07570 } else if (!res) { 07571 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07572 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07573 if (!callback) 07574 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07575 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07576 } 07577 } else { 07578 /* Number unknown */ 07579 ast_debug(1, "VM-CID: From an unknown number\n"); 07580 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07581 res = wait_file2(chan, vms, "vm-unknown-caller"); 07582 } 07583 return res; 07584 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7433 of file app_voicemail_odbcstorage.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
07434 { 07435 int res = 0; 07436 07437 if (!ast_strlen_zero(category)) 07438 res = ast_play_and_wait(chan, category); 07439 07440 if (res) { 07441 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07442 res = 0; 07443 } 07444 07445 return res; 07446 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7448 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_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, vm_zone::list, vm_zone::msg_format, vm_zone::name, pbx_builtin_setvar_helper(), vm_zone::timezone, and ast_vm_user::zonetag.
07449 { 07450 int res = 0; 07451 struct vm_zone *the_zone = NULL; 07452 time_t t; 07453 07454 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07455 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07456 return 0; 07457 } 07458 07459 /* Does this user have a timezone specified? */ 07460 if (!ast_strlen_zero(vmu->zonetag)) { 07461 /* Find the zone in the list */ 07462 struct vm_zone *z; 07463 AST_LIST_LOCK(&zones); 07464 AST_LIST_TRAVERSE(&zones, z, list) { 07465 if (!strcmp(z->name, vmu->zonetag)) { 07466 the_zone = z; 07467 break; 07468 } 07469 } 07470 AST_LIST_UNLOCK(&zones); 07471 } 07472 07473 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07474 #if 0 07475 /* Set the DIFF_* variables */ 07476 ast_localtime(&t, &time_now, NULL); 07477 tv_now = ast_tvnow(); 07478 ast_localtime(&tv_now, &time_then, NULL); 07479 07480 /* Day difference */ 07481 if (time_now.tm_year == time_then.tm_year) 07482 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07483 else 07484 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07485 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07486 07487 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07488 #endif 07489 if (the_zone) { 07490 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07491 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07492 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07493 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07494 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07495 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07496 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); 07497 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07498 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07499 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07500 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07501 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07502 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07503 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07504 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); 07505 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07506 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07507 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07508 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07509 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07510 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); 07511 } else { 07512 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07513 } 07514 #if 0 07515 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07516 #endif 07517 return res; 07518 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7586 of file app_voicemail_odbcstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, say_and_wait(), and wait_file2().
07587 { 07588 int res = 0; 07589 int durationm; 07590 int durations; 07591 /* Verify that we have a duration for the message */ 07592 if (duration == NULL) 07593 return res; 07594 07595 /* Convert from seconds to minutes */ 07596 durations = atoi(duration); 07597 durationm = (durations / 60); 07598 07599 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07600 07601 if ((!res) && (durationm >= minduration)) { 07602 res = wait_file2(chan, vms, "vm-duration"); 07603 07604 /* POLISH syntax */ 07605 if (!strncasecmp(chan->language, "pl", 2)) { 07606 div_t num = div(durationm, 10); 07607 07608 if (durationm == 1) { 07609 res = ast_play_and_wait(chan, "digits/1z"); 07610 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07611 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07612 if (num.rem == 2) { 07613 if (!num.quot) { 07614 res = ast_play_and_wait(chan, "digits/2-ie"); 07615 } else { 07616 res = say_and_wait(chan, durationm - 2 , chan->language); 07617 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07618 } 07619 } else { 07620 res = say_and_wait(chan, durationm, chan->language); 07621 } 07622 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07623 } else { 07624 res = say_and_wait(chan, durationm, chan->language); 07625 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07626 } 07627 /* DEFAULT syntax */ 07628 } else { 07629 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07630 res = wait_file2(chan, vms, "vm-minutes"); 07631 } 07632 } 07633 return res; 07634 }
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 13356 of file app_voicemail_odbcstorage.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), 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, maxsilence, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
13359 { 13360 /* Record message & let caller review or re-record it, or set options if applicable */ 13361 int res = 0; 13362 int cmd = 0; 13363 int max_attempts = 3; 13364 int attempts = 0; 13365 int recorded = 0; 13366 int msg_exists = 0; 13367 signed char zero_gain = 0; 13368 char tempfile[PATH_MAX]; 13369 char *acceptdtmf = "#"; 13370 char *canceldtmf = ""; 13371 int canceleddtmf = 0; 13372 13373 /* Note that urgent and private are for flagging messages as such in the future */ 13374 13375 /* barf if no pointer passed to store duration in */ 13376 if (duration == NULL) { 13377 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13378 return -1; 13379 } 13380 13381 if (!outsidecaller) 13382 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13383 else 13384 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13385 13386 cmd = '3'; /* Want to start by recording */ 13387 13388 while ((cmd >= 0) && (cmd != 't')) { 13389 switch (cmd) { 13390 case '1': 13391 if (!msg_exists) { 13392 /* In this case, 1 is to record a message */ 13393 cmd = '3'; 13394 break; 13395 } else { 13396 /* Otherwise 1 is to save the existing message */ 13397 ast_verb(3, "Saving message as is\n"); 13398 if (!outsidecaller) 13399 ast_filerename(tempfile, recordfile, NULL); 13400 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13401 if (!outsidecaller) { 13402 /* Saves to IMAP server only if imapgreeting=yes */ 13403 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13404 DISPOSE(recordfile, -1); 13405 } 13406 cmd = 't'; 13407 return res; 13408 } 13409 case '2': 13410 /* Review */ 13411 ast_verb(3, "Reviewing the message\n"); 13412 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13413 break; 13414 case '3': 13415 msg_exists = 0; 13416 /* Record */ 13417 if (recorded == 1) 13418 ast_verb(3, "Re-recording the message\n"); 13419 else 13420 ast_verb(3, "Recording the message\n"); 13421 13422 if (recorded && outsidecaller) { 13423 cmd = ast_play_and_wait(chan, INTRO); 13424 cmd = ast_play_and_wait(chan, "beep"); 13425 } 13426 recorded = 1; 13427 /* 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 */ 13428 if (record_gain) 13429 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13430 if (ast_test_flag(vmu, VM_OPERATOR)) 13431 canceldtmf = "0"; 13432 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13433 if (strchr(canceldtmf, cmd)) { 13434 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13435 canceleddtmf = 1; 13436 } 13437 if (record_gain) 13438 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13439 if (cmd == -1) { 13440 /* User has hung up, no options to give */ 13441 if (!outsidecaller) { 13442 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13443 ast_filedelete(tempfile, NULL); 13444 } 13445 return cmd; 13446 } 13447 if (cmd == '0') { 13448 break; 13449 } else if (cmd == '*') { 13450 break; 13451 #if 0 13452 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13453 /* Message is too short */ 13454 ast_verb(3, "Message too short\n"); 13455 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13456 cmd = ast_filedelete(tempfile, NULL); 13457 break; 13458 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13459 /* Message is all silence */ 13460 ast_verb(3, "Nothing recorded\n"); 13461 cmd = ast_filedelete(tempfile, NULL); 13462 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13463 if (!cmd) 13464 cmd = ast_play_and_wait(chan, "vm-speakup"); 13465 break; 13466 #endif 13467 } else { 13468 /* If all is well, a message exists */ 13469 msg_exists = 1; 13470 cmd = 0; 13471 } 13472 break; 13473 case '4': 13474 if (outsidecaller) { /* only mark vm messages */ 13475 /* Mark Urgent */ 13476 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13477 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13478 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13479 strcpy(flag, "Urgent"); 13480 } else if (flag) { 13481 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13482 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13483 strcpy(flag, ""); 13484 } else { 13485 ast_play_and_wait(chan, "vm-sorry"); 13486 } 13487 cmd = 0; 13488 } else { 13489 cmd = ast_play_and_wait(chan, "vm-sorry"); 13490 } 13491 break; 13492 case '5': 13493 case '6': 13494 case '7': 13495 case '8': 13496 case '9': 13497 case '*': 13498 case '#': 13499 cmd = ast_play_and_wait(chan, "vm-sorry"); 13500 break; 13501 #if 0 13502 /* XXX Commented out for the moment because of the dangers of deleting 13503 a message while recording (can put the message numbers out of sync) */ 13504 case '*': 13505 /* Cancel recording, delete message, offer to take another message*/ 13506 cmd = ast_play_and_wait(chan, "vm-deleted"); 13507 cmd = ast_filedelete(tempfile, NULL); 13508 if (outsidecaller) { 13509 res = vm_exec(chan, NULL); 13510 return res; 13511 } 13512 else 13513 return 1; 13514 #endif 13515 case '0': 13516 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13517 cmd = ast_play_and_wait(chan, "vm-sorry"); 13518 break; 13519 } 13520 if (msg_exists || recorded) { 13521 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13522 if (!cmd) 13523 cmd = ast_waitfordigit(chan, 3000); 13524 if (cmd == '1') { 13525 ast_filerename(tempfile, recordfile, NULL); 13526 ast_play_and_wait(chan, "vm-msgsaved"); 13527 cmd = '0'; 13528 } else if (cmd == '4') { 13529 if (flag) { 13530 ast_play_and_wait(chan, "vm-marked-urgent"); 13531 strcpy(flag, "Urgent"); 13532 } 13533 ast_play_and_wait(chan, "vm-msgsaved"); 13534 cmd = '0'; 13535 } else { 13536 ast_play_and_wait(chan, "vm-deleted"); 13537 DELETE(tempfile, -1, tempfile, vmu); 13538 cmd = '0'; 13539 } 13540 } 13541 return cmd; 13542 default: 13543 /* If the caller is an ouside caller, and the review option is enabled, 13544 allow them to review the message, but let the owner of the box review 13545 their OGM's */ 13546 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13547 return cmd; 13548 if (msg_exists) { 13549 cmd = ast_play_and_wait(chan, "vm-review"); 13550 if (!cmd && outsidecaller) { 13551 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13552 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13553 } else if (flag) { 13554 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13555 } 13556 } 13557 } else { 13558 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13559 if (!cmd) 13560 cmd = ast_waitfordigit(chan, 600); 13561 } 13562 13563 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13564 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13565 if (!cmd) 13566 cmd = ast_waitfordigit(chan, 600); 13567 } 13568 #if 0 13569 if (!cmd) 13570 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13571 #endif 13572 if (!cmd) 13573 cmd = ast_waitfordigit(chan, 6000); 13574 if (!cmd) { 13575 attempts++; 13576 } 13577 if (attempts > max_attempts) { 13578 cmd = 't'; 13579 } 13580 } 13581 } 13582 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13583 /* Hang up or timeout, so delete the recording. */ 13584 ast_filedelete(tempfile, NULL); 13585 } 13586 13587 if (cmd != 't' && outsidecaller) 13588 ast_play_and_wait(chan, "vm-goodbye"); 13589 13590 return cmd; 13591 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11389 of file app_voicemail_odbcstorage.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
11390 { 11391 int new = 0, old = 0, urgent = 0; 11392 11393 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11394 11395 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11396 mwi_sub->old_urgent = urgent; 11397 mwi_sub->old_new = new; 11398 mwi_sub->old_old = old; 11399 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11400 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11401 } 11402 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11404 of file app_voicemail_odbcstorage.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub, and poll_subscribed_mailbox().
11405 { 11406 struct mwi_sub *mwi_sub; 11407 11408 AST_RWLIST_RDLOCK(&mwi_subs); 11409 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11410 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11411 poll_subscribed_mailbox(mwi_sub); 11412 } 11413 } 11414 AST_RWLIST_UNLOCK(&mwi_subs); 11415 }
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, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, exitcontext, globalflags, 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, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.
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 4306 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, config_flags, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
04307 { 04308 char callerid[256]; 04309 char num[12]; 04310 char fromdir[256], fromfile[256]; 04311 struct ast_config *msg_cfg; 04312 const char *origcallerid, *origtime; 04313 char origcidname[80], origcidnum[80], origdate[80]; 04314 int inttime; 04315 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04316 04317 /* Prepare variables for substitution in email body and subject */ 04318 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04319 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04320 snprintf(num, sizeof(num), "%d", msgnum); 04321 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04322 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04323 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04324 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04325 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04326 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04327 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04328 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04329 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04330 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04331 04332 /* Retrieve info from VM attribute file */ 04333 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04334 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04335 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04336 strcat(fromfile, ".txt"); 04337 } 04338 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04339 if (option_debug > 0) { 04340 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04341 } 04342 return; 04343 } 04344 04345 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04346 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04347 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04348 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04349 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04350 } 04351 04352 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04353 struct timeval tv = { inttime, }; 04354 struct ast_tm tm; 04355 ast_localtime(&tv, &tm, NULL); 04356 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04357 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04358 } 04359 ast_config_destroy(msg_cfg); 04360 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6976 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, ast_strlen_zero(), and strsep().
06977 { 06978 struct ast_event *event; 06979 char *mailbox, *context; 06980 06981 /* Strip off @default */ 06982 context = mailbox = ast_strdupa(box); 06983 strsep(&context, "@"); 06984 if (ast_strlen_zero(context)) 06985 context = "default"; 06986 06987 if (!(event = ast_event_new(AST_EVENT_MWI, 06988 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06989 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06990 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06991 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06992 AST_EVENT_IE_END))) { 06993 return; 06994 } 06995 06996 ast_event_queue_and_cache(event); 06997 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12482 of file app_voicemail_odbcstorage.c.
References ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), config_flags, and LOG_NOTICE.
12482 { 12483 struct ast_config *pwconf; 12484 struct ast_flags config_flags = { 0 }; 12485 12486 pwconf = ast_config_load(secretfn, config_flags); 12487 if (pwconf) { 12488 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12489 if (val) { 12490 ast_copy_string(password, val, passwordlen); 12491 return; 12492 } 12493 } 12494 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12495 }
static int reload | ( | void | ) | [static] |
Definition at line 13003 of file app_voicemail_odbcstorage.c.
References load_config().
13004 { 13005 return load_config(1); 13006 }
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. |
Definition at line 3975 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03976 { 03977 char stxt[PATH_MAX]; 03978 char dtxt[PATH_MAX]; 03979 ast_filerename(sfn, dfn, NULL); 03980 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03981 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03982 if (ast_check_realtime("voicemail_data")) { 03983 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 03984 } 03985 rename(stxt, dtxt); 03986 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6118 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().
06119 { 06120 /* we know the actual number of messages, so stop process when number is hit */ 06121 06122 int x, dest; 06123 char sfn[PATH_MAX]; 06124 char dfn[PATH_MAX]; 06125 06126 if (vm_lock_path(dir)) { 06127 return ERROR_LOCK_PATH; 06128 } 06129 06130 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06131 make_file(sfn, sizeof(sfn), dir, x); 06132 if (EXISTS(dir, x, sfn, NULL)) { 06133 06134 if (x != dest) { 06135 make_file(dfn, sizeof(dfn), dir, dest); 06136 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06137 } 06138 06139 dest++; 06140 } 06141 } 06142 ast_unlock_path(dir); 06143 06144 return dest; 06145 }
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 1461 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::list, ast_vm_user::mailbox, and ast_vm_user::password.
01462 { 01463 /* This function could be made to generate one from a database, too */ 01464 struct ast_vm_user *cur; 01465 int res = -1; 01466 AST_LIST_LOCK(&users); 01467 AST_LIST_TRAVERSE(&users, cur, list) { 01468 if ((!context || !strcasecmp(context, cur->context)) && 01469 (!strcasecmp(mailbox, cur->mailbox))) 01470 break; 01471 } 01472 if (cur) { 01473 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01474 res = 0; 01475 } 01476 AST_LIST_UNLOCK(&users); 01477 return res; 01478 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5491 of file app_voicemail_odbcstorage.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, 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, externnotify, ast_smdi_mwi_message::fwd_st, inboxcount2(), smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
05492 { 05493 char arguments[255]; 05494 char ext_context[256] = ""; 05495 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05496 struct ast_smdi_mwi_message *mwi_msg; 05497 05498 if (!ast_strlen_zero(context)) 05499 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05500 else 05501 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05502 05503 if (smdi_iface) { 05504 if (ast_app_has_voicemail(ext_context, NULL)) 05505 ast_smdi_mwi_set(smdi_iface, extension); 05506 else 05507 ast_smdi_mwi_unset(smdi_iface, extension); 05508 05509 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05510 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05511 if (!strncmp(mwi_msg->cause, "INV", 3)) 05512 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05513 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05514 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05515 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05516 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05517 } else { 05518 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05519 } 05520 } 05521 05522 if (!ast_strlen_zero(externnotify)) { 05523 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05524 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05525 } else { 05526 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05527 ast_debug(1, "Executing %s\n", arguments); 05528 ast_safe_system(arguments); 05529 } 05530 } 05531 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6155 of file app_voicemail_odbcstorage.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock, ast_mutex_unlock, ast_unlock_path(), COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), make_file(), mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().
06156 { 06157 #ifdef IMAP_STORAGE 06158 /* we must use mbox(x) folder names, and copy the message there */ 06159 /* simple. huh? */ 06160 char sequence[10]; 06161 char mailbox[256]; 06162 int res; 06163 06164 /* get the real IMAP message number for this message */ 06165 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06166 06167 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06168 ast_mutex_lock(&vms->lock); 06169 /* if save to Old folder, put in INBOX as read */ 06170 if (box == OLD_FOLDER) { 06171 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06172 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06173 } else if (box == NEW_FOLDER) { 06174 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06175 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06176 } 06177 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06178 ast_mutex_unlock(&vms->lock); 06179 return 0; 06180 } 06181 /* Create the folder if it don't exist */ 06182 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06183 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06184 if (mail_create(vms->mailstream, mailbox) == NIL) 06185 ast_debug(5, "Folder exists.\n"); 06186 else 06187 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06188 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06189 ast_mutex_unlock(&vms->lock); 06190 return res; 06191 #else 06192 char *dir = vms->curdir; 06193 char *username = vms->username; 06194 char *context = vmu->context; 06195 char sfn[PATH_MAX]; 06196 char dfn[PATH_MAX]; 06197 char ddir[PATH_MAX]; 06198 const char *dbox = mbox(vmu, box); 06199 int x, i; 06200 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06201 06202 if (vm_lock_path(ddir)) 06203 return ERROR_LOCK_PATH; 06204 06205 x = last_message_index(vmu, ddir) + 1; 06206 06207 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06208 x--; 06209 for (i = 1; i <= x; i++) { 06210 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06211 make_file(sfn, sizeof(sfn), ddir, i); 06212 make_file(dfn, sizeof(dfn), ddir, i - 1); 06213 if (EXISTS(ddir, i, sfn, NULL)) { 06214 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06215 } else 06216 break; 06217 } 06218 } else { 06219 if (x >= vmu->maxmsg) { 06220 ast_unlock_path(ddir); 06221 return -1; 06222 } 06223 } 06224 make_file(sfn, sizeof(sfn), dir, msg); 06225 make_file(dfn, sizeof(dfn), ddir, x); 06226 if (strcmp(sfn, dfn)) { 06227 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06228 } 06229 ast_unlock_path(ddir); 06230 #endif 06231 return 0; 06232 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6148 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, and ast_say_number().
06149 { 06150 int d; 06151 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06152 return d; 06153 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12468 of file app_voicemail_odbcstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
12469 { 12470 int res = -1; 12471 char dir[PATH_MAX]; 12472 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12473 ast_debug(2, "About to try retrieving name file %s\n", dir); 12474 RETRIEVE(dir, -1, mailbox, context); 12475 if (ast_fileexists(dir, NULL, NULL)) { 12476 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12477 } 12478 DISPOSE(dir, -1); 12479 return res; 12480 }
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 4821 of file app_voicemail_odbcstorage.c.
References ast_debug, ast_log(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, ast_vm_user::mailbox, mailcmd, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().
04822 { 04823 FILE *p = NULL; 04824 char tmp[80] = "/tmp/astmail-XXXXXX"; 04825 char tmp2[256]; 04826 char *stringp; 04827 04828 if (vmu && ast_strlen_zero(vmu->email)) { 04829 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04830 return(0); 04831 } 04832 04833 /* Mail only the first format */ 04834 format = ast_strdupa(format); 04835 stringp = format; 04836 strsep(&stringp, "|"); 04837 04838 if (!strcmp(format, "wav49")) 04839 format = "WAV"; 04840 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04841 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04842 command hangs */ 04843 if ((p = vm_mkftemp(tmp)) == NULL) { 04844 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04845 return -1; 04846 } else { 04847 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04848 fclose(p); 04849 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04850 ast_safe_system(tmp2); 04851 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04852 } 04853 return 0; 04854 }
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 4856 of file app_voicemail_odbcstorage.c.
References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_log(), 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_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, mailcmd, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
04857 { 04858 char enc_cidnum[256], enc_cidname[256]; 04859 char date[256]; 04860 char host[MAXHOSTNAMELEN] = ""; 04861 char who[256]; 04862 char dur[PATH_MAX]; 04863 char tmp[80] = "/tmp/astmail-XXXXXX"; 04864 char tmp2[PATH_MAX]; 04865 struct ast_tm tm; 04866 FILE *p; 04867 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04868 04869 if (!str1 || !str2) { 04870 ast_free(str1); 04871 ast_free(str2); 04872 return -1; 04873 } 04874 04875 if (cidnum) { 04876 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04877 } 04878 if (cidname) { 04879 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04880 } 04881 04882 if ((p = vm_mkftemp(tmp)) == NULL) { 04883 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04884 ast_free(str1); 04885 ast_free(str2); 04886 return -1; 04887 } 04888 gethostname(host, sizeof(host)-1); 04889 if (strchr(srcemail, '@')) { 04890 ast_copy_string(who, srcemail, sizeof(who)); 04891 } else { 04892 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04893 } 04894 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04895 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04896 fprintf(p, "Date: %s\n", date); 04897 04898 /* Reformat for custom pager format */ 04899 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04900 04901 if (!ast_strlen_zero(pagerfromstring)) { 04902 struct ast_channel *ast; 04903 if ((ast = ast_dummy_channel_alloc())) { 04904 char *ptr; 04905 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04906 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04907 04908 if (check_mime(ast_str_buffer(str1))) { 04909 int first_line = 1; 04910 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04911 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04912 *ptr = '\0'; 04913 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04914 first_line = 0; 04915 /* Substring is smaller, so this will never grow */ 04916 ast_str_set(&str2, 0, "%s", ptr + 1); 04917 } 04918 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04919 } else { 04920 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04921 } 04922 ast = ast_channel_unref(ast); 04923 } else { 04924 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04925 } 04926 } else { 04927 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04928 } 04929 04930 if (check_mime(vmu->fullname)) { 04931 int first_line = 1; 04932 char *ptr; 04933 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04934 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04935 *ptr = '\0'; 04936 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04937 first_line = 0; 04938 /* Substring is smaller, so this will never grow */ 04939 ast_str_set(&str2, 0, "%s", ptr + 1); 04940 } 04941 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04942 } else { 04943 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04944 } 04945 04946 if (!ast_strlen_zero(pagersubject)) { 04947 struct ast_channel *ast; 04948 if ((ast = ast_dummy_channel_alloc())) { 04949 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04950 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04951 if (check_mime(ast_str_buffer(str1))) { 04952 int first_line = 1; 04953 char *ptr; 04954 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04955 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04956 *ptr = '\0'; 04957 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04958 first_line = 0; 04959 /* Substring is smaller, so this will never grow */ 04960 ast_str_set(&str2, 0, "%s", ptr + 1); 04961 } 04962 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04963 } else { 04964 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04965 } 04966 ast = ast_channel_unref(ast); 04967 } else { 04968 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04969 } 04970 } else { 04971 if (ast_strlen_zero(flag)) { 04972 fprintf(p, "Subject: New VM\n\n"); 04973 } else { 04974 fprintf(p, "Subject: New %s VM\n\n", flag); 04975 } 04976 } 04977 04978 if (pagerbody) { 04979 struct ast_channel *ast; 04980 if ((ast = ast_dummy_channel_alloc())) { 04981 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04982 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 04983 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04984 ast = ast_channel_unref(ast); 04985 } else { 04986 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04987 } 04988 } else { 04989 fprintf(p, "New %s long %s msg in box %s\n" 04990 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04991 } 04992 04993 fclose(p); 04994 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04995 ast_safe_system(tmp2); 04996 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04997 ast_free(str1); 04998 ast_free(str2); 04999 return 0; 05000 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11046 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, SENTINEL, and var.
11047 { 11048 struct ast_config *cfg; 11049 const char *cat = NULL; 11050 11051 if (!(cfg = ast_load_realtime_multientry("voicemail", 11052 "context", context, SENTINEL))) { 11053 return CLI_FAILURE; 11054 } 11055 11056 ast_cli(fd, 11057 "\n" 11058 "=============================================================\n" 11059 "=== Configured Voicemail Users ==============================\n" 11060 "=============================================================\n" 11061 "===\n"); 11062 11063 while ((cat = ast_category_browse(cfg, cat))) { 11064 struct ast_variable *var = NULL; 11065 ast_cli(fd, 11066 "=== Mailbox ...\n" 11067 "===\n"); 11068 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11069 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11070 ast_cli(fd, 11071 "===\n" 11072 "=== ---------------------------------------------------------\n" 11073 "===\n"); 11074 } 11075 11076 ast_cli(fd, 11077 "=============================================================\n" 11078 "\n"); 11079 11080 ast_config_destroy(cfg); 11081 11082 return CLI_SUCCESS; 11083 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11541 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_pthread_create, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), mwi_unsub_sub, poll_thread, and poll_thread_run.
11542 { 11543 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11544 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11545 AST_EVENT_IE_END); 11546 11547 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11548 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11549 AST_EVENT_IE_END); 11550 11551 if (mwi_sub_sub) 11552 ast_event_report_subs(mwi_sub_sub); 11553 11554 poll_thread_run = 1; 11555 11556 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11557 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11559 of file app_voicemail_odbcstorage.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, mwi_sub_sub, mwi_unsub_sub, poll_cond, poll_lock, poll_thread, and poll_thread_run.
11560 { 11561 poll_thread_run = 0; 11562 11563 if (mwi_sub_sub) { 11564 ast_event_unsubscribe(mwi_sub_sub); 11565 mwi_sub_sub = NULL; 11566 } 11567 11568 if (mwi_unsub_sub) { 11569 ast_event_unsubscribe(mwi_unsub_sub); 11570 mwi_unsub_sub = NULL; 11571 } 11572 11573 ast_mutex_lock(&poll_lock); 11574 ast_cond_signal(&poll_cond); 11575 ast_mutex_unlock(&poll_lock); 11576 11577 pthread_join(poll_thread, NULL); 11578 11579 poll_thread = AST_PTHREADT_NULL; 11580 }
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.
00966 { 00967 char *bufptr = buf; 00968 for (; *input; input++) { 00969 if (*input < 32) { 00970 continue; 00971 } 00972 *bufptr++ = *input; 00973 if (bufptr == buf + buflen - 1) { 00974 break; 00975 } 00976 } 00977 *bufptr = '\0'; 00978 return buf; 00979 }
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11705 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), and str.
11706 { 11707 char *current; 11708 11709 /* Add 16 for fudge factor */ 11710 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11711 11712 ast_str_reset(str); 11713 11714 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11715 for (current = (char *) value; *current; current++) { 11716 if (*current == '\\') { 11717 current++; 11718 if (!*current) { 11719 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11720 break; 11721 } 11722 switch (*current) { 11723 case '\\': 11724 ast_str_append(&str, 0, "\\"); 11725 break; 11726 case 'r': 11727 ast_str_append(&str, 0, "\r"); 11728 break; 11729 case 'n': 11730 #ifdef IMAP_STORAGE 11731 if (!str->used || str->str[str->used - 1] != '\r') { 11732 ast_str_append(&str, 0, "\r"); 11733 } 11734 #endif 11735 ast_str_append(&str, 0, "\n"); 11736 break; 11737 case 't': 11738 ast_str_append(&str, 0, "\t"); 11739 break; 11740 default: 11741 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11742 break; 11743 } 11744 } else { 11745 ast_str_append(&str, 0, "%c", *current); 11746 } 11747 } 11748 11749 return ast_str_buffer(str); 11750 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13008 of file app_voicemail_odbcstorage.c.
References ao2_ref, app, app2, app3, app4, 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(), cli_voicemail, free_vm_users(), free_vm_zones(), inprocess_container, mailbox_exists_acf, mwi_subscription_tps, poll_thread, sayname_app, and stop_poll_thread().
13009 { 13010 int res; 13011 13012 res = ast_unregister_application(app); 13013 res |= ast_unregister_application(app2); 13014 res |= ast_unregister_application(app3); 13015 res |= ast_unregister_application(app4); 13016 res |= ast_unregister_application(sayname_app); 13017 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13018 res |= ast_manager_unregister("VoicemailUsersList"); 13019 res |= ast_data_unregister(NULL); 13020 #ifdef TEST_FRAMEWORK 13021 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13022 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13023 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13024 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13025 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13026 #endif 13027 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13028 ast_uninstall_vm_functions(); 13029 ao2_ref(inprocess_container, -1); 13030 13031 if (poll_thread != AST_PTHREADT_NULL) 13032 stop_poll_thread(); 13033 13034 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13035 ast_unload_realtime("voicemail"); 13036 ast_unload_realtime("voicemail_data"); 13037 13038 free_vm_users(); 13039 free_vm_zones(); 13040 return res; 13041 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1731 of file app_voicemail_odbcstorage.c.
References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
01731 { 01732 01733 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01734 if (!vms->dh_arraysize) { 01735 /* initial allocation */ 01736 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01737 return -1; 01738 } 01739 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01740 return -1; 01741 } 01742 vms->dh_arraysize = arraysize; 01743 } else if (vms->dh_arraysize < arraysize) { 01744 if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) { 01745 return -1; 01746 } 01747 if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) { 01748 return -1; 01749 } 01750 memset(vms->deleted, 0, arraysize * sizeof(int)); 01751 memset(vms->heard, 0, arraysize * sizeof(int)); 01752 vms->dh_arraysize = arraysize; 01753 } 01754 01755 return 0; 01756 }
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 9708 of file app_voicemail_odbcstorage.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_waitstream(), find_user(), ast_vm_user::password, S_COR, and vm_password.
09711 { 09712 int useadsi = 0, valid = 0, logretries = 0; 09713 char password[AST_MAX_EXTENSION]="", *passptr; 09714 struct ast_vm_user vmus, *vmu = NULL; 09715 09716 /* If ADSI is supported, setup login screen */ 09717 adsi_begin(chan, &useadsi); 09718 if (!skipuser && useadsi) 09719 adsi_login(chan); 09720 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09721 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09722 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09723 return -1; 09724 } 09725 09726 /* Authenticate them and get their mailbox/password */ 09727 09728 while (!valid && (logretries < max_logins)) { 09729 /* Prompt for, and read in the username */ 09730 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09731 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09732 return -1; 09733 } 09734 if (ast_strlen_zero(mailbox)) { 09735 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09736 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09737 } else { 09738 ast_verb(3, "Username not entered\n"); 09739 return -1; 09740 } 09741 } else if (mailbox[0] == '*') { 09742 /* user entered '*' */ 09743 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09744 if (ast_exists_extension(chan, chan->context, "a", 1, 09745 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09746 return -1; 09747 } 09748 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09749 mailbox[0] = '\0'; 09750 } 09751 09752 if (useadsi) 09753 adsi_password(chan); 09754 09755 if (!ast_strlen_zero(prefix)) { 09756 char fullusername[80] = ""; 09757 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09758 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09759 ast_copy_string(mailbox, fullusername, mailbox_size); 09760 } 09761 09762 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09763 vmu = find_user(&vmus, context, mailbox); 09764 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09765 /* saved password is blank, so don't bother asking */ 09766 password[0] = '\0'; 09767 } else { 09768 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09769 if (ast_streamfile(chan, vm_password, chan->language)) { 09770 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09771 return -1; 09772 } 09773 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09774 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09775 return -1; 09776 } else if (password[0] == '*') { 09777 /* user entered '*' */ 09778 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09779 if (ast_exists_extension(chan, chan->context, "a", 1, 09780 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09781 mailbox[0] = '*'; 09782 return -1; 09783 } 09784 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09785 mailbox[0] = '\0'; 09786 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09787 vmu = NULL; 09788 } 09789 } 09790 09791 if (vmu) { 09792 passptr = vmu->password; 09793 if (passptr[0] == '-') passptr++; 09794 } 09795 if (vmu && !strcmp(passptr, password)) 09796 valid++; 09797 else { 09798 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09799 if (!ast_strlen_zero(prefix)) 09800 mailbox[0] = '\0'; 09801 } 09802 logretries++; 09803 if (!valid) { 09804 if (skipuser || logretries >= max_logins) { 09805 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09806 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09807 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09808 return -1; 09809 } 09810 } else { 09811 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09812 if (useadsi) 09813 adsi_login(chan); 09814 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09815 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09816 return -1; 09817 } 09818 } 09819 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09820 return -1; 09821 } 09822 } 09823 if (!valid && (logretries >= max_logins)) { 09824 ast_stopstream(chan); 09825 ast_play_and_wait(chan, "vm-goodbye"); 09826 return -1; 09827 } 09828 if (vmu && !skipuser) { 09829 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09830 } 09831 return 0; 09832 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10941 of file app_voicemail_odbcstorage.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), find_user(), mbox(), and pbx_builtin_setvar_helper().
10942 { 10943 struct ast_vm_user svm; 10944 char *context, *box; 10945 AST_DECLARE_APP_ARGS(args, 10946 AST_APP_ARG(mbox); 10947 AST_APP_ARG(options); 10948 ); 10949 static int dep_warning = 0; 10950 10951 if (ast_strlen_zero(data)) { 10952 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10953 return -1; 10954 } 10955 10956 if (!dep_warning) { 10957 dep_warning = 1; 10958 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10959 } 10960 10961 box = ast_strdupa(data); 10962 10963 AST_STANDARD_APP_ARGS(args, box); 10964 10965 if (args.options) { 10966 } 10967 10968 if ((context = strchr(args.mbox, '@'))) { 10969 *context = '\0'; 10970 context++; 10971 } 10972 10973 if (find_user(&svm, context, args.mbox)) { 10974 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 10975 } else 10976 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 10977 10978 return 0; 10979 }
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. |
Definition at line 9687 of file app_voicemail_odbcstorage.c.
References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), and vm_browse_messages_zh().
09688 { 09689 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09690 return vm_browse_messages_es(chan, vms, vmu); 09691 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09692 return vm_browse_messages_gr(chan, vms, vmu); 09693 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09694 return vm_browse_messages_he(chan, vms, vmu); 09695 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09696 return vm_browse_messages_it(chan, vms, vmu); 09697 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09698 return vm_browse_messages_pt(chan, vms, vmu); 09699 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09700 return vm_browse_messages_vi(chan, vms, vmu); 09701 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09702 return vm_browse_messages_zh(chan, vms, vmu); 09703 } else { /* Default to English syntax */ 09704 return vm_browse_messages_en(chan, vms, vmu); 09705 } 09706 }
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 9526 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09527 { 09528 int cmd = 0; 09529 09530 if (vms->lastmsg > -1) { 09531 cmd = play_message(chan, vmu, vms); 09532 } else { 09533 cmd = ast_play_and_wait(chan, "vm-youhave"); 09534 if (!cmd) 09535 cmd = ast_play_and_wait(chan, "vm-no"); 09536 if (!cmd) { 09537 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09538 cmd = ast_play_and_wait(chan, vms->fn); 09539 } 09540 if (!cmd) 09541 cmd = ast_play_and_wait(chan, "vm-messages"); 09542 } 09543 return cmd; 09544 }
static int vm_browse_messages_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Spanish syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9580 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09581 { 09582 int cmd; 09583 09584 if (vms->lastmsg > -1) { 09585 cmd = play_message(chan, vmu, vms); 09586 } else { 09587 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09588 if (!cmd) 09589 cmd = ast_play_and_wait(chan, "vm-messages"); 09590 if (!cmd) { 09591 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09592 cmd = ast_play_and_wait(chan, vms->fn); 09593 } 09594 } 09595 return cmd; 09596 }
static int vm_browse_messages_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Greek syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9474 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.
09475 { 09476 int cmd = 0; 09477 09478 if (vms->lastmsg > -1) { 09479 cmd = play_message(chan, vmu, vms); 09480 } else { 09481 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09482 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09483 if (!cmd) { 09484 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09485 cmd = ast_play_and_wait(chan, vms->fn); 09486 } 09487 if (!cmd) 09488 cmd = ast_play_and_wait(chan, "vm-messages"); 09489 } else { 09490 if (!cmd) 09491 cmd = ast_play_and_wait(chan, "vm-messages"); 09492 if (!cmd) { 09493 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09494 cmd = ast_play_and_wait(chan, vms->fn); 09495 } 09496 } 09497 } 09498 return cmd; 09499 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9502 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
09503 { 09504 int cmd = 0; 09505 09506 if (vms->lastmsg > -1) { 09507 cmd = play_message(chan, vmu, vms); 09508 } else { 09509 if (!strcasecmp(vms->fn, "INBOX")) { 09510 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09511 } else { 09512 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09513 } 09514 } 09515 return cmd; 09516 }
static int vm_browse_messages_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Italian syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9554 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09555 { 09556 int cmd; 09557 09558 if (vms->lastmsg > -1) { 09559 cmd = play_message(chan, vmu, vms); 09560 } else { 09561 cmd = ast_play_and_wait(chan, "vm-no"); 09562 if (!cmd) 09563 cmd = ast_play_and_wait(chan, "vm-message"); 09564 if (!cmd) { 09565 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09566 cmd = ast_play_and_wait(chan, vms->fn); 09567 } 09568 } 09569 return cmd; 09570 }
static int vm_browse_messages_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Portuguese syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9606 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09607 { 09608 int cmd; 09609 09610 if (vms->lastmsg > -1) { 09611 cmd = play_message(chan, vmu, vms); 09612 } else { 09613 cmd = ast_play_and_wait(chan, "vm-no"); 09614 if (!cmd) { 09615 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09616 cmd = ast_play_and_wait(chan, vms->fn); 09617 } 09618 if (!cmd) 09619 cmd = ast_play_and_wait(chan, "vm-messages"); 09620 } 09621 return cmd; 09622 }
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 9660 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09661 { 09662 int cmd = 0; 09663 09664 if (vms->lastmsg > -1) { 09665 cmd = play_message(chan, vmu, vms); 09666 } else { 09667 cmd = ast_play_and_wait(chan, "vm-no"); 09668 if (!cmd) { 09669 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09670 cmd = ast_play_and_wait(chan, vms->fn); 09671 } 09672 } 09673 return cmd; 09674 }
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 9632 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09633 { 09634 int cmd; 09635 09636 if (vms->lastmsg > -1) { 09637 cmd = play_message(chan, vmu, vms); 09638 } else { 09639 cmd = ast_play_and_wait(chan, "vm-you"); 09640 if (!cmd) 09641 cmd = ast_play_and_wait(chan, "vm-haveno"); 09642 if (!cmd) 09643 cmd = ast_play_and_wait(chan, "vm-messages"); 09644 if (!cmd) { 09645 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09646 cmd = ast_play_and_wait(chan, vms->fn); 09647 } 09648 } 09649 return cmd; 09650 }
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 1487 of file app_voicemail_odbcstorage.c.
References ast_category_browse(), ast_category_get(), ast_config_load, ast_config_text_file_save(), ast_copy_string(), ast_debug, ast_free, ast_log(), AST_LOG_WARNING, ast_test_suite_event_notify, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), value, var, VM_SPOOL_DIR, VOICEMAIL_CONFIG, and write_password_to_file().
01488 { 01489 struct ast_config *cfg = NULL; 01490 struct ast_variable *var = NULL; 01491 struct ast_category *cat = NULL; 01492 char *category = NULL, *value = NULL, *new = NULL; 01493 const char *tmp = NULL; 01494 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01495 char secretfn[PATH_MAX] = ""; 01496 int found = 0; 01497 01498 if (!change_password_realtime(vmu, newpassword)) 01499 return; 01500 01501 /* check if we should store the secret in the spool directory next to the messages */ 01502 switch (vmu->passwordlocation) { 01503 case OPT_PWLOC_SPOOLDIR: 01504 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01505 if (write_password_to_file(secretfn, newpassword) == 0) { 01506 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01507 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01508 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01509 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01510 break; 01511 } else { 01512 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01513 } 01514 /* Fall-through */ 01515 case OPT_PWLOC_VOICEMAILCONF: 01516 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01517 while ((category = ast_category_browse(cfg, category))) { 01518 if (!strcasecmp(category, vmu->context)) { 01519 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01520 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01521 break; 01522 } 01523 value = strstr(tmp, ","); 01524 if (!value) { 01525 new = alloca(strlen(newpassword)+1); 01526 sprintf(new, "%s", newpassword); 01527 } else { 01528 new = alloca((strlen(value) + strlen(newpassword) + 1)); 01529 sprintf(new, "%s%s", newpassword, value); 01530 } 01531 if (!(cat = ast_category_get(cfg, category))) { 01532 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01533 break; 01534 } 01535 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01536 found = 1; 01537 } 01538 } 01539 /* save the results */ 01540 if (found) { 01541 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01542 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01543 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01544 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01545 break; 01546 } 01547 } 01548 /* Fall-through */ 01549 case OPT_PWLOC_USERSCONF: 01550 /* check users.conf and update the password stored for the mailbox */ 01551 /* if no vmsecret entry exists create one. */ 01552 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01553 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01554 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01555 ast_debug(4, "users.conf: %s\n", category); 01556 if (!strcasecmp(category, vmu->mailbox)) { 01557 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01558 ast_debug(3, "looks like we need to make vmsecret!\n"); 01559 var = ast_variable_new("vmsecret", newpassword, ""); 01560 } else { 01561 var = NULL; 01562 } 01563 new = alloca(strlen(newpassword) + 1); 01564 sprintf(new, "%s", newpassword); 01565 if (!(cat = ast_category_get(cfg, category))) { 01566 ast_debug(4, "failed to get category!\n"); 01567 ast_free(var); 01568 break; 01569 } 01570 if (!var) { 01571 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01572 } else { 01573 ast_variable_append(cat, var); 01574 } 01575 found = 1; 01576 break; 01577 } 01578 } 01579 /* save the results and clean things up */ 01580 if (found) { 01581 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01582 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01583 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01584 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01585 } 01586 } 01587 } 01588 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1590 of file app_voicemail_odbcstorage.c.
References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ext_pass_cmd, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
01591 { 01592 char buf[255]; 01593 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01594 ast_debug(1, "External password: %s\n",buf); 01595 if (!ast_safe_system(buf)) { 01596 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01597 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01598 /* Reset the password in memory, too */ 01599 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01600 } 01601 }
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.
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. |
Definition at line 4160 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04161 { 04162 char *txt; 04163 int txtsize = 0; 04164 04165 txtsize = (strlen(file) + 5)*sizeof(char); 04166 txt = alloca(txtsize); 04167 /* Sprintf here would safe because we alloca'd exactly the right length, 04168 * but trying to eliminate all sprintf's anyhow 04169 */ 04170 if (ast_check_realtime("voicemail_data")) { 04171 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04172 } 04173 snprintf(txt, txtsize, "%s.txt", file); 04174 unlink(txt); 04175 return ast_filedelete(file, NULL); 04176 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10600 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_play_and_wait(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, ast_flags::flags, 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 vm_app_options.
10601 { 10602 int res = 0; 10603 char *tmp; 10604 struct leave_vm_options leave_options; 10605 struct ast_flags flags = { 0 }; 10606 char *opts[OPT_ARG_ARRAY_SIZE]; 10607 AST_DECLARE_APP_ARGS(args, 10608 AST_APP_ARG(argv0); 10609 AST_APP_ARG(argv1); 10610 ); 10611 10612 memset(&leave_options, 0, sizeof(leave_options)); 10613 10614 if (chan->_state != AST_STATE_UP) 10615 ast_answer(chan); 10616 10617 if (!ast_strlen_zero(data)) { 10618 tmp = ast_strdupa(data); 10619 AST_STANDARD_APP_ARGS(args, tmp); 10620 if (args.argc == 2) { 10621 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10622 return -1; 10623 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10624 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10625 int gain; 10626 10627 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10628 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10629 return -1; 10630 } else { 10631 leave_options.record_gain = (signed char) gain; 10632 } 10633 } 10634 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10635 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10636 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10637 } 10638 } 10639 } else { 10640 char temp[256]; 10641 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10642 if (res < 0) 10643 return res; 10644 if (ast_strlen_zero(temp)) 10645 return 0; 10646 args.argv0 = ast_strdupa(temp); 10647 } 10648 10649 res = leave_voicemail(chan, args.argv0, &leave_options); 10650 if (res == 't') { 10651 ast_play_and_wait(chan, "vm-goodbye"); 10652 res = 0; 10653 } 10654 10655 if (res == OPERATOR_EXIT) { 10656 res = 0; 10657 } 10658 10659 if (res == ERROR_LOCK_PATH) { 10660 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10661 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10662 res = 0; 10663 } 10664 10665 return res; 10666 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9834 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_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_goto_if_exists(), ast_log(), AST_LOG_ERROR, 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, ast_channel::context, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free_user(), get_folder2(), get_folder_by_name(), globalflags, has_voicemail(), language, ast_vm_user::language, ast_vm_user::mailbox, make_file(), maxlogins, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, 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(), run_externnotify(), save_to_folder(), say_and_wait(), vm_app_options, 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 vmfmts.
09835 { 09836 /* XXX This is, admittedly, some pretty horrendous code. For some 09837 reason it just seemed a lot easier to do with GOTO's. I feel 09838 like I'm back in my GWBASIC days. XXX */ 09839 int res = -1; 09840 int cmd = 0; 09841 int valid = 0; 09842 char prefixstr[80] =""; 09843 char ext_context[256]=""; 09844 int box; 09845 int useadsi = 0; 09846 int skipuser = 0; 09847 struct vm_state vms; 09848 struct ast_vm_user *vmu = NULL, vmus; 09849 char *context = NULL; 09850 int silentexit = 0; 09851 struct ast_flags flags = { 0 }; 09852 signed char record_gain = 0; 09853 int play_auto = 0; 09854 int play_folder = 0; 09855 int in_urgent = 0; 09856 #ifdef IMAP_STORAGE 09857 int deleted = 0; 09858 #endif 09859 09860 /* Add the vm_state to the active list and keep it active */ 09861 memset(&vms, 0, sizeof(vms)); 09862 09863 vms.lastmsg = -1; 09864 09865 memset(&vmus, 0, sizeof(vmus)); 09866 09867 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09868 if (chan->_state != AST_STATE_UP) { 09869 ast_debug(1, "Before ast_answer\n"); 09870 ast_answer(chan); 09871 } 09872 09873 if (!ast_strlen_zero(data)) { 09874 char *opts[OPT_ARG_ARRAY_SIZE]; 09875 char *parse; 09876 AST_DECLARE_APP_ARGS(args, 09877 AST_APP_ARG(argv0); 09878 AST_APP_ARG(argv1); 09879 ); 09880 09881 parse = ast_strdupa(data); 09882 09883 AST_STANDARD_APP_ARGS(args, parse); 09884 09885 if (args.argc == 2) { 09886 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09887 return -1; 09888 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09889 int gain; 09890 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09891 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09892 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09893 return -1; 09894 } else { 09895 record_gain = (signed char) gain; 09896 } 09897 } else { 09898 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09899 } 09900 } 09901 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09902 play_auto = 1; 09903 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09904 /* See if it is a folder name first */ 09905 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09906 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09907 play_folder = -1; 09908 } 09909 } else { 09910 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09911 } 09912 } else { 09913 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09914 } 09915 if (play_folder > 9 || play_folder < 0) { 09916 ast_log(AST_LOG_WARNING, 09917 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09918 opts[OPT_ARG_PLAYFOLDER]); 09919 play_folder = 0; 09920 } 09921 } 09922 } else { 09923 /* old style options parsing */ 09924 while (*(args.argv0)) { 09925 if (*(args.argv0) == 's') 09926 ast_set_flag(&flags, OPT_SILENT); 09927 else if (*(args.argv0) == 'p') 09928 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09929 else 09930 break; 09931 (args.argv0)++; 09932 } 09933 09934 } 09935 09936 valid = ast_test_flag(&flags, OPT_SILENT); 09937 09938 if ((context = strchr(args.argv0, '@'))) 09939 *context++ = '\0'; 09940 09941 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09942 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09943 else 09944 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09945 09946 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09947 skipuser++; 09948 else 09949 valid = 0; 09950 } 09951 09952 if (!valid) 09953 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09954 09955 ast_debug(1, "After vm_authenticate\n"); 09956 09957 if (vms.username[0] == '*') { 09958 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09959 09960 /* user entered '*' */ 09961 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09962 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 09963 res = 0; /* prevent hangup */ 09964 goto out; 09965 } 09966 } 09967 09968 if (!res) { 09969 valid = 1; 09970 if (!skipuser) 09971 vmu = &vmus; 09972 } else { 09973 res = 0; 09974 } 09975 09976 /* If ADSI is supported, setup login screen */ 09977 adsi_begin(chan, &useadsi); 09978 09979 ast_test_suite_assert(valid); 09980 if (!valid) { 09981 goto out; 09982 } 09983 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 09984 09985 #ifdef IMAP_STORAGE 09986 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 09987 pthread_setspecific(ts_vmstate.key, &vms); 09988 09989 vms.interactive = 1; 09990 vms.updated = 1; 09991 if (vmu) 09992 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 09993 vmstate_insert(&vms); 09994 init_vm_state(&vms); 09995 #endif 09996 /* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */ 09997 if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09998 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 09999 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 10000 return -1; 10001 } 10002 if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 10003 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 10004 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 10005 return -1; 10006 } 10007 10008 /* Set language from config to override channel language */ 10009 if (!ast_strlen_zero(vmu->language)) 10010 ast_string_field_set(chan, language, vmu->language); 10011 10012 /* Retrieve urgent, old and new message counts */ 10013 ast_debug(1, "Before open_mailbox\n"); 10014 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10015 if (res < 0) 10016 goto out; 10017 vms.oldmessages = vms.lastmsg + 1; 10018 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10019 /* check INBOX */ 10020 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10021 if (res < 0) 10022 goto out; 10023 vms.newmessages = vms.lastmsg + 1; 10024 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10025 /* Start in Urgent */ 10026 in_urgent = 1; 10027 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10028 if (res < 0) 10029 goto out; 10030 vms.urgentmessages = vms.lastmsg + 1; 10031 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10032 10033 /* Select proper mailbox FIRST!! */ 10034 if (play_auto) { 10035 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10036 if (vms.urgentmessages) { 10037 in_urgent = 1; 10038 res = open_mailbox(&vms, vmu, 11); 10039 } else { 10040 in_urgent = 0; 10041 res = open_mailbox(&vms, vmu, play_folder); 10042 } 10043 if (res < 0) 10044 goto out; 10045 10046 /* If there are no new messages, inform the user and hangup */ 10047 if (vms.lastmsg == -1) { 10048 in_urgent = 0; 10049 cmd = vm_browse_messages(chan, &vms, vmu); 10050 res = 0; 10051 goto out; 10052 } 10053 } else { 10054 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10055 /* If we only have old messages start here */ 10056 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10057 in_urgent = 0; 10058 play_folder = 1; 10059 if (res < 0) 10060 goto out; 10061 } else if (!vms.urgentmessages && vms.newmessages) { 10062 /* If we have new messages but none are urgent */ 10063 in_urgent = 0; 10064 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10065 if (res < 0) 10066 goto out; 10067 } 10068 } 10069 10070 if (useadsi) 10071 adsi_status(chan, &vms); 10072 res = 0; 10073 10074 /* Check to see if this is a new user */ 10075 if (!strcasecmp(vmu->mailbox, vmu->password) && 10076 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10077 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10078 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10079 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10080 if ((cmd == 't') || (cmd == '#')) { 10081 /* Timeout */ 10082 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10083 res = 0; 10084 goto out; 10085 } else if (cmd < 0) { 10086 /* Hangup */ 10087 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10088 res = -1; 10089 goto out; 10090 } 10091 } 10092 #ifdef IMAP_STORAGE 10093 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10094 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10095 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10096 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10097 } 10098 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10099 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10100 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10101 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10102 } 10103 #endif 10104 10105 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10106 if (play_auto) { 10107 cmd = '1'; 10108 } else { 10109 cmd = vm_intro(chan, vmu, &vms); 10110 } 10111 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10112 10113 vms.repeats = 0; 10114 vms.starting = 1; 10115 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10116 /* Run main menu */ 10117 switch (cmd) { 10118 case '1': /* First message */ 10119 vms.curmsg = 0; 10120 /* Fall through */ 10121 case '5': /* Play current message */ 10122 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10123 cmd = vm_browse_messages(chan, &vms, vmu); 10124 break; 10125 case '2': /* Change folders */ 10126 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10127 if (useadsi) 10128 adsi_folders(chan, 0, "Change to folder..."); 10129 10130 cmd = get_folder2(chan, "vm-changeto", 0); 10131 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10132 if (cmd == '#') { 10133 cmd = 0; 10134 } else if (cmd > 0) { 10135 cmd = cmd - '0'; 10136 res = close_mailbox(&vms, vmu); 10137 if (res == ERROR_LOCK_PATH) 10138 goto out; 10139 /* If folder is not urgent, set in_urgent to zero! */ 10140 if (cmd != 11) in_urgent = 0; 10141 res = open_mailbox(&vms, vmu, cmd); 10142 if (res < 0) 10143 goto out; 10144 play_folder = cmd; 10145 cmd = 0; 10146 } 10147 if (useadsi) 10148 adsi_status2(chan, &vms); 10149 10150 if (!cmd) { 10151 cmd = vm_play_folder_name(chan, vms.vmbox); 10152 } 10153 10154 vms.starting = 1; 10155 break; 10156 case '3': /* Advanced options */ 10157 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10158 cmd = 0; 10159 vms.repeats = 0; 10160 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10161 switch (cmd) { 10162 case '1': /* Reply */ 10163 if (vms.lastmsg > -1 && !vms.starting) { 10164 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10165 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10166 res = cmd; 10167 goto out; 10168 } 10169 } else { 10170 cmd = ast_play_and_wait(chan, "vm-sorry"); 10171 } 10172 cmd = 't'; 10173 break; 10174 case '2': /* Callback */ 10175 if (!vms.starting) 10176 ast_verb(3, "Callback Requested\n"); 10177 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10178 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10179 if (cmd == 9) { 10180 silentexit = 1; 10181 goto out; 10182 } else if (cmd == ERROR_LOCK_PATH) { 10183 res = cmd; 10184 goto out; 10185 } 10186 } else { 10187 cmd = ast_play_and_wait(chan, "vm-sorry"); 10188 } 10189 cmd = 't'; 10190 break; 10191 case '3': /* Envelope */ 10192 if (vms.lastmsg > -1 && !vms.starting) { 10193 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10194 if (cmd == ERROR_LOCK_PATH) { 10195 res = cmd; 10196 goto out; 10197 } 10198 } else { 10199 cmd = ast_play_and_wait(chan, "vm-sorry"); 10200 } 10201 cmd = 't'; 10202 break; 10203 case '4': /* Dialout */ 10204 if (!ast_strlen_zero(vmu->dialout)) { 10205 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10206 if (cmd == 9) { 10207 silentexit = 1; 10208 goto out; 10209 } 10210 } else { 10211 cmd = ast_play_and_wait(chan, "vm-sorry"); 10212 } 10213 cmd = 't'; 10214 break; 10215 10216 case '5': /* Leave VoiceMail */ 10217 if (ast_test_flag(vmu, VM_SVMAIL)) { 10218 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10219 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10220 res = cmd; 10221 goto out; 10222 } 10223 } else { 10224 cmd = ast_play_and_wait(chan, "vm-sorry"); 10225 } 10226 cmd = 't'; 10227 break; 10228 10229 case '*': /* Return to main menu */ 10230 cmd = 't'; 10231 break; 10232 10233 default: 10234 cmd = 0; 10235 if (!vms.starting) { 10236 cmd = ast_play_and_wait(chan, "vm-toreply"); 10237 } 10238 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10239 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10240 } 10241 if (!cmd && !vms.starting) { 10242 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10243 } 10244 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10245 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10246 } 10247 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10248 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10249 } 10250 if (!cmd) { 10251 cmd = ast_play_and_wait(chan, "vm-starmain"); 10252 } 10253 if (!cmd) { 10254 cmd = ast_waitfordigit(chan, 6000); 10255 } 10256 if (!cmd) { 10257 vms.repeats++; 10258 } 10259 if (vms.repeats > 3) { 10260 cmd = 't'; 10261 } 10262 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10263 } 10264 } 10265 if (cmd == 't') { 10266 cmd = 0; 10267 vms.repeats = 0; 10268 } 10269 break; 10270 case '4': /* Go to the previous message */ 10271 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10272 if (vms.curmsg > 0) { 10273 vms.curmsg--; 10274 cmd = play_message(chan, vmu, &vms); 10275 } else { 10276 /* Check if we were listening to new 10277 messages. If so, go to Urgent messages 10278 instead of saying "no more messages" 10279 */ 10280 if (in_urgent == 0 && vms.urgentmessages > 0) { 10281 /* Check for Urgent messages */ 10282 in_urgent = 1; 10283 res = close_mailbox(&vms, vmu); 10284 if (res == ERROR_LOCK_PATH) 10285 goto out; 10286 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10287 if (res < 0) 10288 goto out; 10289 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10290 vms.curmsg = vms.lastmsg; 10291 if (vms.lastmsg < 0) { 10292 cmd = ast_play_and_wait(chan, "vm-nomore"); 10293 } 10294 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10295 vms.curmsg = vms.lastmsg; 10296 cmd = play_message(chan, vmu, &vms); 10297 } else { 10298 cmd = ast_play_and_wait(chan, "vm-nomore"); 10299 } 10300 } 10301 break; 10302 case '6': /* Go to the next message */ 10303 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10304 if (vms.curmsg < vms.lastmsg) { 10305 vms.curmsg++; 10306 cmd = play_message(chan, vmu, &vms); 10307 } else { 10308 if (in_urgent && vms.newmessages > 0) { 10309 /* Check if we were listening to urgent 10310 * messages. If so, go to regular new messages 10311 * instead of saying "no more messages" 10312 */ 10313 in_urgent = 0; 10314 res = close_mailbox(&vms, vmu); 10315 if (res == ERROR_LOCK_PATH) 10316 goto out; 10317 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10318 if (res < 0) 10319 goto out; 10320 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10321 vms.curmsg = -1; 10322 if (vms.lastmsg < 0) { 10323 cmd = ast_play_and_wait(chan, "vm-nomore"); 10324 } 10325 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10326 vms.curmsg = 0; 10327 cmd = play_message(chan, vmu, &vms); 10328 } else { 10329 cmd = ast_play_and_wait(chan, "vm-nomore"); 10330 } 10331 } 10332 break; 10333 case '7': /* Delete the current message */ 10334 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10335 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10336 if (useadsi) 10337 adsi_delete(chan, &vms); 10338 if (vms.deleted[vms.curmsg]) { 10339 if (play_folder == 0) { 10340 if (in_urgent) { 10341 vms.urgentmessages--; 10342 } else { 10343 vms.newmessages--; 10344 } 10345 } 10346 else if (play_folder == 1) 10347 vms.oldmessages--; 10348 cmd = ast_play_and_wait(chan, "vm-deleted"); 10349 } else { 10350 if (play_folder == 0) { 10351 if (in_urgent) { 10352 vms.urgentmessages++; 10353 } else { 10354 vms.newmessages++; 10355 } 10356 } 10357 else if (play_folder == 1) 10358 vms.oldmessages++; 10359 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10360 } 10361 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10362 if (vms.curmsg < vms.lastmsg) { 10363 vms.curmsg++; 10364 cmd = play_message(chan, vmu, &vms); 10365 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10366 vms.curmsg = 0; 10367 cmd = play_message(chan, vmu, &vms); 10368 } else { 10369 /* Check if we were listening to urgent 10370 messages. If so, go to regular new messages 10371 instead of saying "no more messages" 10372 */ 10373 if (in_urgent == 1) { 10374 /* Check for new messages */ 10375 in_urgent = 0; 10376 res = close_mailbox(&vms, vmu); 10377 if (res == ERROR_LOCK_PATH) 10378 goto out; 10379 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10380 if (res < 0) 10381 goto out; 10382 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10383 vms.curmsg = -1; 10384 if (vms.lastmsg < 0) { 10385 cmd = ast_play_and_wait(chan, "vm-nomore"); 10386 } 10387 } else { 10388 cmd = ast_play_and_wait(chan, "vm-nomore"); 10389 } 10390 } 10391 } 10392 } else /* Delete not valid if we haven't selected a message */ 10393 cmd = 0; 10394 #ifdef IMAP_STORAGE 10395 deleted = 1; 10396 #endif 10397 break; 10398 10399 case '8': /* Forward the current message */ 10400 if (vms.lastmsg > -1) { 10401 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10402 if (cmd == ERROR_LOCK_PATH) { 10403 res = cmd; 10404 goto out; 10405 } 10406 } else { 10407 /* Check if we were listening to urgent 10408 messages. If so, go to regular new messages 10409 instead of saying "no more messages" 10410 */ 10411 if (in_urgent == 1 && vms.newmessages > 0) { 10412 /* Check for new messages */ 10413 in_urgent = 0; 10414 res = close_mailbox(&vms, vmu); 10415 if (res == ERROR_LOCK_PATH) 10416 goto out; 10417 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10418 if (res < 0) 10419 goto out; 10420 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10421 vms.curmsg = -1; 10422 if (vms.lastmsg < 0) { 10423 cmd = ast_play_and_wait(chan, "vm-nomore"); 10424 } 10425 } else { 10426 cmd = ast_play_and_wait(chan, "vm-nomore"); 10427 } 10428 } 10429 break; 10430 case '9': /* Save message to folder */ 10431 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10432 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10433 /* No message selected */ 10434 cmd = 0; 10435 break; 10436 } 10437 if (useadsi) 10438 adsi_folders(chan, 1, "Save to folder..."); 10439 cmd = get_folder2(chan, "vm-savefolder", 1); 10440 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10441 box = 0; /* Shut up compiler */ 10442 if (cmd == '#') { 10443 cmd = 0; 10444 break; 10445 } else if (cmd > 0) { 10446 box = cmd = cmd - '0'; 10447 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10448 if (cmd == ERROR_LOCK_PATH) { 10449 res = cmd; 10450 goto out; 10451 #ifndef IMAP_STORAGE 10452 } else if (!cmd) { 10453 vms.deleted[vms.curmsg] = 1; 10454 #endif 10455 } else { 10456 vms.deleted[vms.curmsg] = 0; 10457 vms.heard[vms.curmsg] = 0; 10458 } 10459 } 10460 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10461 if (useadsi) 10462 adsi_message(chan, &vms); 10463 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10464 if (!cmd) { 10465 cmd = ast_play_and_wait(chan, "vm-message"); 10466 if (!cmd) 10467 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10468 if (!cmd) 10469 cmd = ast_play_and_wait(chan, "vm-savedto"); 10470 if (!cmd) 10471 cmd = vm_play_folder_name(chan, vms.fn); 10472 } else { 10473 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10474 } 10475 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10476 if (vms.curmsg < vms.lastmsg) { 10477 vms.curmsg++; 10478 cmd = play_message(chan, vmu, &vms); 10479 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10480 vms.curmsg = 0; 10481 cmd = play_message(chan, vmu, &vms); 10482 } else { 10483 /* Check if we were listening to urgent 10484 messages. If so, go to regular new messages 10485 instead of saying "no more messages" 10486 */ 10487 if (in_urgent == 1 && vms.newmessages > 0) { 10488 /* Check for new messages */ 10489 in_urgent = 0; 10490 res = close_mailbox(&vms, vmu); 10491 if (res == ERROR_LOCK_PATH) 10492 goto out; 10493 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10494 if (res < 0) 10495 goto out; 10496 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10497 vms.curmsg = -1; 10498 if (vms.lastmsg < 0) { 10499 cmd = ast_play_and_wait(chan, "vm-nomore"); 10500 } 10501 } else { 10502 cmd = ast_play_and_wait(chan, "vm-nomore"); 10503 } 10504 } 10505 } 10506 break; 10507 case '*': /* Help */ 10508 if (!vms.starting) { 10509 cmd = ast_play_and_wait(chan, "vm-onefor"); 10510 if (!strncasecmp(chan->language, "he", 2)) { 10511 cmd = ast_play_and_wait(chan, "vm-for"); 10512 } 10513 if (!cmd) 10514 cmd = vm_play_folder_name(chan, vms.vmbox); 10515 if (!cmd) 10516 cmd = ast_play_and_wait(chan, "vm-opts"); 10517 if (!cmd) 10518 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10519 } else 10520 cmd = 0; 10521 break; 10522 case '0': /* Mailbox options */ 10523 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10524 if (useadsi) 10525 adsi_status(chan, &vms); 10526 break; 10527 default: /* Nothing */ 10528 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10529 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10530 break; 10531 } 10532 } 10533 if ((cmd == 't') || (cmd == '#')) { 10534 /* Timeout */ 10535 res = 0; 10536 } else { 10537 /* Hangup */ 10538 res = -1; 10539 } 10540 10541 out: 10542 if (res > -1) { 10543 ast_stopstream(chan); 10544 adsi_goodbye(chan); 10545 if (valid && res != OPERATOR_EXIT) { 10546 if (silentexit) 10547 res = ast_play_and_wait(chan, "vm-dialout"); 10548 else 10549 res = ast_play_and_wait(chan, "vm-goodbye"); 10550 } 10551 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10552 res = 0; 10553 } 10554 if (useadsi) 10555 ast_adsi_unload_session(chan); 10556 } 10557 if (vmu) 10558 close_mailbox(&vms, vmu); 10559 if (valid) { 10560 int new = 0, old = 0, urgent = 0; 10561 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10562 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10563 /* Urgent flag not passwd to externnotify here */ 10564 run_externnotify(vmu->context, vmu->mailbox, NULL); 10565 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10566 queue_mwi_event(ext_context, urgent, new, old); 10567 } 10568 #ifdef IMAP_STORAGE 10569 /* expunge message - use UID Expunge if supported on IMAP server*/ 10570 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10571 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10572 ast_mutex_lock(&vms.lock); 10573 #ifdef HAVE_IMAP_TK2006 10574 if (LEVELUIDPLUS (vms.mailstream)) { 10575 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10576 } else 10577 #endif 10578 mail_expunge(vms.mailstream); 10579 ast_mutex_unlock(&vms.lock); 10580 } 10581 /* before we delete the state, we should copy pertinent info 10582 * back to the persistent model */ 10583 if (vmu) { 10584 vmstate_delete(&vms); 10585 } 10586 #endif 10587 if (vmu) 10588 free_user(vmu); 10589 if (vms.deleted) 10590 ast_free(vms.deleted); 10591 if (vms.heard) 10592 ast_free(vms.heard); 10593 10594 #ifdef IMAP_STORAGE 10595 pthread_setspecific(ts_vmstate.key, NULL); 10596 #endif 10597 return res; 10598 }
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 |
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6823 of file app_voicemail_odbcstorage.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, maxsilence, play_record_review(), silencethreshold, vm_pls_try_again, and vm_prepend_timeout.
06825 { 06826 int cmd = 0; 06827 int retries = 0, prepend_duration = 0, already_recorded = 0; 06828 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06829 char textfile[PATH_MAX]; 06830 struct ast_config *msg_cfg; 06831 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06832 #ifndef IMAP_STORAGE 06833 signed char zero_gain = 0; 06834 #endif 06835 const char *duration_str; 06836 06837 /* Must always populate duration correctly */ 06838 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06839 strcpy(textfile, msgfile); 06840 strcpy(backup, msgfile); 06841 strcpy(backup_textfile, msgfile); 06842 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06843 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06844 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06845 06846 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06847 *duration = atoi(duration_str); 06848 } else { 06849 *duration = 0; 06850 } 06851 06852 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06853 if (cmd) 06854 retries = 0; 06855 switch (cmd) { 06856 case '1': 06857 06858 #ifdef IMAP_STORAGE 06859 /* Record new intro file */ 06860 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06861 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06862 ast_play_and_wait(chan, INTRO); 06863 ast_play_and_wait(chan, "beep"); 06864 play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06865 cmd = 't'; 06866 #else 06867 06868 /* prepend a message to the current message, update the metadata and return */ 06869 06870 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06871 strcpy(textfile, msgfile); 06872 strncat(textfile, ".txt", sizeof(textfile) - 1); 06873 *duration = 0; 06874 06875 /* if we can't read the message metadata, stop now */ 06876 if (!msg_cfg) { 06877 cmd = 0; 06878 break; 06879 } 06880 06881 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06882 #ifndef IMAP_STORAGE 06883 if (already_recorded) { 06884 ast_filecopy(backup, msgfile, NULL); 06885 copy(backup_textfile, textfile); 06886 } 06887 else { 06888 ast_filecopy(msgfile, backup, NULL); 06889 copy(textfile, backup_textfile); 06890 } 06891 #endif 06892 already_recorded = 1; 06893 06894 if (record_gain) 06895 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06896 06897 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06898 06899 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06900 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06901 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06902 ast_filerename(backup, msgfile, NULL); 06903 } 06904 06905 if (record_gain) 06906 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06907 06908 06909 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06910 *duration = atoi(duration_str); 06911 06912 if (prepend_duration) { 06913 struct ast_category *msg_cat; 06914 /* need enough space for a maximum-length message duration */ 06915 char duration_buf[12]; 06916 06917 *duration += prepend_duration; 06918 msg_cat = ast_category_get(msg_cfg, "message"); 06919 snprintf(duration_buf, 11, "%ld", *duration); 06920 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06921 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06922 } 06923 } 06924 06925 #endif 06926 break; 06927 case '2': 06928 /* NULL out introfile so we know there is no intro! */ 06929 #ifdef IMAP_STORAGE 06930 *vms->introfn = '\0'; 06931 #endif 06932 cmd = 't'; 06933 break; 06934 case '*': 06935 cmd = '*'; 06936 break; 06937 default: 06938 /* If time_out and return to menu, reset already_recorded */ 06939 already_recorded = 0; 06940 06941 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06942 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06943 if (!cmd) { 06944 cmd = ast_play_and_wait(chan, "vm-starmain"); 06945 /* "press star to return to the main menu" */ 06946 } 06947 if (!cmd) { 06948 cmd = ast_waitfordigit(chan, 6000); 06949 } 06950 if (!cmd) { 06951 retries++; 06952 } 06953 if (retries > 3) { 06954 cmd = '*'; /* Let's cancel this beast */ 06955 } 06956 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 06957 } 06958 } 06959 06960 if (msg_cfg) 06961 ast_config_destroy(msg_cfg); 06962 if (prepend_duration) 06963 *duration = prepend_duration; 06964 06965 if (already_recorded && cmd == -1) { 06966 /* restore original message if prepention cancelled */ 06967 ast_filerename(backup, msgfile, NULL); 06968 rename(backup_textfile, textfile); 06969 } 06970 06971 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 06972 cmd = 0; 06973 return cmd; 06974 }
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 9152 of file app_voicemail_odbcstorage.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
09153 { 09154 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09155 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09156 } else { /* Default to ENGLISH */ 09157 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09158 } 09159 }
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 9051 of file app_voicemail_odbcstorage.c.
References 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.
09052 { 09053 int res = 0; 09054 /* Play instructions and wait for new command */ 09055 while (!res) { 09056 if (vms->starting) { 09057 if (vms->lastmsg > -1) { 09058 if (skipadvanced) 09059 res = ast_play_and_wait(chan, "vm-onefor-full"); 09060 else 09061 res = ast_play_and_wait(chan, "vm-onefor"); 09062 if (!res) 09063 res = vm_play_folder_name(chan, vms->vmbox); 09064 } 09065 if (!res) { 09066 if (skipadvanced) 09067 res = ast_play_and_wait(chan, "vm-opts-full"); 09068 else 09069 res = ast_play_and_wait(chan, "vm-opts"); 09070 } 09071 } else { 09072 /* Added for additional help */ 09073 if (skipadvanced) { 09074 res = ast_play_and_wait(chan, "vm-onefor-full"); 09075 if (!res) 09076 res = vm_play_folder_name(chan, vms->vmbox); 09077 res = ast_play_and_wait(chan, "vm-opts-full"); 09078 } 09079 /* Logic: 09080 * If the current message is not the first OR 09081 * if we're listening to the first new message and there are 09082 * also urgent messages, then prompt for navigation to the 09083 * previous message 09084 */ 09085 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09086 res = ast_play_and_wait(chan, "vm-prev"); 09087 } 09088 if (!res && !skipadvanced) 09089 res = ast_play_and_wait(chan, "vm-advopts"); 09090 if (!res) 09091 res = ast_play_and_wait(chan, "vm-repeat"); 09092 /* Logic: 09093 * If we're not listening to the last message OR 09094 * we're listening to the last urgent message and there are 09095 * also new non-urgent messages, then prompt for navigation 09096 * to the next message 09097 */ 09098 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09099 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09100 res = ast_play_and_wait(chan, "vm-next"); 09101 } 09102 if (!res) { 09103 if (!vms->deleted[vms->curmsg]) 09104 res = ast_play_and_wait(chan, "vm-delete"); 09105 else 09106 res = ast_play_and_wait(chan, "vm-undelete"); 09107 if (!res) 09108 res = ast_play_and_wait(chan, "vm-toforward"); 09109 if (!res) 09110 res = ast_play_and_wait(chan, "vm-savemessage"); 09111 } 09112 } 09113 if (!res) { 09114 res = ast_play_and_wait(chan, "vm-helpexit"); 09115 } 09116 if (!res) 09117 res = ast_waitfordigit(chan, 6000); 09118 if (!res) { 09119 vms->repeats++; 09120 if (vms->repeats > 2) { 09121 res = 't'; 09122 } 09123 } 09124 } 09125 return res; 09126 }
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 9128 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.
09129 { 09130 int res = 0; 09131 /* Play instructions and wait for new command */ 09132 while (!res) { 09133 if (vms->lastmsg > -1) { 09134 res = ast_play_and_wait(chan, "vm-listen"); 09135 if (!res) 09136 res = vm_play_folder_name(chan, vms->vmbox); 09137 if (!res) 09138 res = ast_play_and_wait(chan, "press"); 09139 if (!res) 09140 res = ast_play_and_wait(chan, "digits/1"); 09141 } 09142 if (!res) 09143 res = ast_play_and_wait(chan, "vm-opts"); 09144 if (!res) { 09145 vms->starting = 0; 09146 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09147 } 09148 } 09149 return res; 09150 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 8989 of file app_voicemail_odbcstorage.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, 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(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.
08990 { 08991 char prefile[256]; 08992 08993 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08994 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08995 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08996 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08997 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08998 ast_play_and_wait(chan, "vm-tempgreetactive"); 08999 } 09000 DISPOSE(prefile, -1); 09001 } 09002 09003 /* Play voicemail intro - syntax is different for different languages */ 09004 if (0) { 09005 return 0; 09006 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09007 return vm_intro_cs(chan, vms); 09008 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09009 static int deprecation_warning = 0; 09010 if (deprecation_warning++ % 10 == 0) { 09011 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09012 } 09013 return vm_intro_cs(chan, vms); 09014 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09015 return vm_intro_de(chan, vms); 09016 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09017 return vm_intro_es(chan, vms); 09018 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09019 return vm_intro_fr(chan, vms); 09020 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09021 return vm_intro_gr(chan, vms); 09022 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09023 return vm_intro_he(chan, vms); 09024 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09025 return vm_intro_it(chan, vms); 09026 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09027 return vm_intro_nl(chan, vms); 09028 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09029 return vm_intro_no(chan, vms); 09030 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09031 return vm_intro_pl(chan, vms); 09032 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09033 return vm_intro_pt_BR(chan, vms); 09034 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09035 return vm_intro_pt(chan, vms); 09036 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09037 return vm_intro_multilang(chan, vms, "n"); 09038 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09039 return vm_intro_se(chan, vms); 09040 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09041 return vm_intro_multilang(chan, vms, "n"); 09042 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09043 return vm_intro_vi(chan, vms); 09044 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09045 return vm_intro_zh(chan, vms); 09046 } else { /* Default to ENGLISH */ 09047 return vm_intro_en(chan, vms); 09048 } 09049 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8859 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08860 { 08861 int res; 08862 res = ast_play_and_wait(chan, "vm-youhave"); 08863 if (!res) { 08864 if (vms->newmessages) { 08865 if (vms->newmessages == 1) { 08866 res = ast_play_and_wait(chan, "digits/jednu"); 08867 } else { 08868 res = say_and_wait(chan, vms->newmessages, chan->language); 08869 } 08870 if (!res) { 08871 if ((vms->newmessages == 1)) 08872 res = ast_play_and_wait(chan, "vm-novou"); 08873 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08874 res = ast_play_and_wait(chan, "vm-nove"); 08875 if (vms->newmessages > 4) 08876 res = ast_play_and_wait(chan, "vm-novych"); 08877 } 08878 if (vms->oldmessages && !res) 08879 res = ast_play_and_wait(chan, "vm-and"); 08880 else if (!res) { 08881 if ((vms->newmessages == 1)) 08882 res = ast_play_and_wait(chan, "vm-zpravu"); 08883 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08884 res = ast_play_and_wait(chan, "vm-zpravy"); 08885 if (vms->newmessages > 4) 08886 res = ast_play_and_wait(chan, "vm-zprav"); 08887 } 08888 } 08889 if (!res && vms->oldmessages) { 08890 res = say_and_wait(chan, vms->oldmessages, chan->language); 08891 if (!res) { 08892 if ((vms->oldmessages == 1)) 08893 res = ast_play_and_wait(chan, "vm-starou"); 08894 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08895 res = ast_play_and_wait(chan, "vm-stare"); 08896 if (vms->oldmessages > 4) 08897 res = ast_play_and_wait(chan, "vm-starych"); 08898 } 08899 if (!res) { 08900 if ((vms->oldmessages == 1)) 08901 res = ast_play_and_wait(chan, "vm-zpravu"); 08902 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08903 res = ast_play_and_wait(chan, "vm-zpravy"); 08904 if (vms->oldmessages > 4) 08905 res = ast_play_and_wait(chan, "vm-zprav"); 08906 } 08907 } 08908 if (!res) { 08909 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08910 res = ast_play_and_wait(chan, "vm-no"); 08911 if (!res) 08912 res = ast_play_and_wait(chan, "vm-zpravy"); 08913 } 08914 } 08915 } 08916 return res; 08917 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8555 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08556 { 08557 /* Introduce messages they have */ 08558 int res; 08559 res = ast_play_and_wait(chan, "vm-youhave"); 08560 if (!res) { 08561 if (vms->newmessages) { 08562 if ((vms->newmessages == 1)) 08563 res = ast_play_and_wait(chan, "digits/1F"); 08564 else 08565 res = say_and_wait(chan, vms->newmessages, chan->language); 08566 if (!res) 08567 res = ast_play_and_wait(chan, "vm-INBOX"); 08568 if (vms->oldmessages && !res) 08569 res = ast_play_and_wait(chan, "vm-and"); 08570 else if (!res) { 08571 if ((vms->newmessages == 1)) 08572 res = ast_play_and_wait(chan, "vm-message"); 08573 else 08574 res = ast_play_and_wait(chan, "vm-messages"); 08575 } 08576 08577 } 08578 if (!res && vms->oldmessages) { 08579 if (vms->oldmessages == 1) 08580 res = ast_play_and_wait(chan, "digits/1F"); 08581 else 08582 res = say_and_wait(chan, vms->oldmessages, chan->language); 08583 if (!res) 08584 res = ast_play_and_wait(chan, "vm-Old"); 08585 if (!res) { 08586 if (vms->oldmessages == 1) 08587 res = ast_play_and_wait(chan, "vm-message"); 08588 else 08589 res = ast_play_and_wait(chan, "vm-messages"); 08590 } 08591 } 08592 if (!res) { 08593 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08594 res = ast_play_and_wait(chan, "vm-no"); 08595 if (!res) 08596 res = ast_play_and_wait(chan, "vm-messages"); 08597 } 08598 } 08599 } 08600 return res; 08601 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8304 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08305 { 08306 int res; 08307 08308 /* Introduce messages they have */ 08309 res = ast_play_and_wait(chan, "vm-youhave"); 08310 if (!res) { 08311 if (vms->urgentmessages) { 08312 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08313 if (!res) 08314 res = ast_play_and_wait(chan, "vm-Urgent"); 08315 if ((vms->oldmessages || vms->newmessages) && !res) { 08316 res = ast_play_and_wait(chan, "vm-and"); 08317 } else if (!res) { 08318 if ((vms->urgentmessages == 1)) 08319 res = ast_play_and_wait(chan, "vm-message"); 08320 else 08321 res = ast_play_and_wait(chan, "vm-messages"); 08322 } 08323 } 08324 if (vms->newmessages) { 08325 res = say_and_wait(chan, vms->newmessages, chan->language); 08326 if (!res) 08327 res = ast_play_and_wait(chan, "vm-INBOX"); 08328 if (vms->oldmessages && !res) 08329 res = ast_play_and_wait(chan, "vm-and"); 08330 else if (!res) { 08331 if ((vms->newmessages == 1)) 08332 res = ast_play_and_wait(chan, "vm-message"); 08333 else 08334 res = ast_play_and_wait(chan, "vm-messages"); 08335 } 08336 08337 } 08338 if (!res && vms->oldmessages) { 08339 res = say_and_wait(chan, vms->oldmessages, chan->language); 08340 if (!res) 08341 res = ast_play_and_wait(chan, "vm-Old"); 08342 if (!res) { 08343 if (vms->oldmessages == 1) 08344 res = ast_play_and_wait(chan, "vm-message"); 08345 else 08346 res = ast_play_and_wait(chan, "vm-messages"); 08347 } 08348 } 08349 if (!res) { 08350 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08351 res = ast_play_and_wait(chan, "vm-no"); 08352 if (!res) 08353 res = ast_play_and_wait(chan, "vm-messages"); 08354 } 08355 } 08356 } 08357 return res; 08358 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8604 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08605 { 08606 /* Introduce messages they have */ 08607 int res; 08608 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08609 res = ast_play_and_wait(chan, "vm-youhaveno"); 08610 if (!res) 08611 res = ast_play_and_wait(chan, "vm-messages"); 08612 } else { 08613 res = ast_play_and_wait(chan, "vm-youhave"); 08614 } 08615 if (!res) { 08616 if (vms->newmessages) { 08617 if (!res) { 08618 if ((vms->newmessages == 1)) { 08619 res = ast_play_and_wait(chan, "digits/1M"); 08620 if (!res) 08621 res = ast_play_and_wait(chan, "vm-message"); 08622 if (!res) 08623 res = ast_play_and_wait(chan, "vm-INBOXs"); 08624 } else { 08625 res = say_and_wait(chan, vms->newmessages, chan->language); 08626 if (!res) 08627 res = ast_play_and_wait(chan, "vm-messages"); 08628 if (!res) 08629 res = ast_play_and_wait(chan, "vm-INBOX"); 08630 } 08631 } 08632 if (vms->oldmessages && !res) 08633 res = ast_play_and_wait(chan, "vm-and"); 08634 } 08635 if (vms->oldmessages) { 08636 if (!res) { 08637 if (vms->oldmessages == 1) { 08638 res = ast_play_and_wait(chan, "digits/1M"); 08639 if (!res) 08640 res = ast_play_and_wait(chan, "vm-message"); 08641 if (!res) 08642 res = ast_play_and_wait(chan, "vm-Olds"); 08643 } else { 08644 res = say_and_wait(chan, vms->oldmessages, chan->language); 08645 if (!res) 08646 res = ast_play_and_wait(chan, "vm-messages"); 08647 if (!res) 08648 res = ast_play_and_wait(chan, "vm-Old"); 08649 } 08650 } 08651 } 08652 } 08653 return res; 08654 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8702 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08703 { 08704 /* Introduce messages they have */ 08705 int res; 08706 res = ast_play_and_wait(chan, "vm-youhave"); 08707 if (!res) { 08708 if (vms->newmessages) { 08709 res = say_and_wait(chan, vms->newmessages, chan->language); 08710 if (!res) 08711 res = ast_play_and_wait(chan, "vm-INBOX"); 08712 if (vms->oldmessages && !res) 08713 res = ast_play_and_wait(chan, "vm-and"); 08714 else if (!res) { 08715 if ((vms->newmessages == 1)) 08716 res = ast_play_and_wait(chan, "vm-message"); 08717 else 08718 res = ast_play_and_wait(chan, "vm-messages"); 08719 } 08720 08721 } 08722 if (!res && vms->oldmessages) { 08723 res = say_and_wait(chan, vms->oldmessages, chan->language); 08724 if (!res) 08725 res = ast_play_and_wait(chan, "vm-Old"); 08726 if (!res) { 08727 if (vms->oldmessages == 1) 08728 res = ast_play_and_wait(chan, "vm-message"); 08729 else 08730 res = ast_play_and_wait(chan, "vm-messages"); 08731 } 08732 } 08733 if (!res) { 08734 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08735 res = ast_play_and_wait(chan, "vm-no"); 08736 if (!res) 08737 res = ast_play_and_wait(chan, "vm-messages"); 08738 } 08739 } 08740 } 08741 return res; 08742 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8103 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
08104 { 08105 int res = 0; 08106 08107 if (vms->newmessages) { 08108 res = ast_play_and_wait(chan, "vm-youhave"); 08109 if (!res) 08110 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08111 if (!res) { 08112 if ((vms->newmessages == 1)) { 08113 res = ast_play_and_wait(chan, "vm-INBOX"); 08114 if (!res) 08115 res = ast_play_and_wait(chan, "vm-message"); 08116 } else { 08117 res = ast_play_and_wait(chan, "vm-INBOXs"); 08118 if (!res) 08119 res = ast_play_and_wait(chan, "vm-messages"); 08120 } 08121 } 08122 } else if (vms->oldmessages){ 08123 res = ast_play_and_wait(chan, "vm-youhave"); 08124 if (!res) 08125 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08126 if ((vms->oldmessages == 1)){ 08127 res = ast_play_and_wait(chan, "vm-Old"); 08128 if (!res) 08129 res = ast_play_and_wait(chan, "vm-message"); 08130 } else { 08131 res = ast_play_and_wait(chan, "vm-Olds"); 08132 if (!res) 08133 res = ast_play_and_wait(chan, "vm-messages"); 08134 } 08135 } else if (!vms->oldmessages && !vms->newmessages) 08136 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08137 return res; 08138 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8237 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
08238 { 08239 int res = 0; 08240 08241 /* Introduce messages they have */ 08242 if (!res) { 08243 if ((vms->newmessages) || (vms->oldmessages)) { 08244 res = ast_play_and_wait(chan, "vm-youhave"); 08245 } 08246 /* 08247 * The word "shtei" refers to the number 2 in hebrew when performing a count 08248 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08249 * an element, this is one of them. 08250 */ 08251 if (vms->newmessages) { 08252 if (!res) { 08253 if (vms->newmessages == 1) { 08254 res = ast_play_and_wait(chan, "vm-INBOX1"); 08255 } else { 08256 if (vms->newmessages == 2) { 08257 res = ast_play_and_wait(chan, "vm-shtei"); 08258 } else { 08259 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08260 } 08261 res = ast_play_and_wait(chan, "vm-INBOX"); 08262 } 08263 } 08264 if (vms->oldmessages && !res) { 08265 res = ast_play_and_wait(chan, "vm-and"); 08266 if (vms->oldmessages == 1) { 08267 res = ast_play_and_wait(chan, "vm-Old1"); 08268 } else { 08269 if (vms->oldmessages == 2) { 08270 res = ast_play_and_wait(chan, "vm-shtei"); 08271 } else { 08272 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08273 } 08274 res = ast_play_and_wait(chan, "vm-Old"); 08275 } 08276 } 08277 } 08278 if (!res && vms->oldmessages && !vms->newmessages) { 08279 if (!res) { 08280 if (vms->oldmessages == 1) { 08281 res = ast_play_and_wait(chan, "vm-Old1"); 08282 } else { 08283 if (vms->oldmessages == 2) { 08284 res = ast_play_and_wait(chan, "vm-shtei"); 08285 } else { 08286 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08287 } 08288 res = ast_play_and_wait(chan, "vm-Old"); 08289 } 08290 } 08291 } 08292 if (!res) { 08293 if (!vms->oldmessages && !vms->newmessages) { 08294 if (!res) { 08295 res = ast_play_and_wait(chan, "vm-nomessages"); 08296 } 08297 } 08298 } 08299 } 08300 return res; 08301 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8361 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08362 { 08363 /* Introduce messages they have */ 08364 int res; 08365 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08366 res = ast_play_and_wait(chan, "vm-no") || 08367 ast_play_and_wait(chan, "vm-message"); 08368 else 08369 res = ast_play_and_wait(chan, "vm-youhave"); 08370 if (!res && vms->newmessages) { 08371 res = (vms->newmessages == 1) ? 08372 ast_play_and_wait(chan, "digits/un") || 08373 ast_play_and_wait(chan, "vm-nuovo") || 08374 ast_play_and_wait(chan, "vm-message") : 08375 /* 2 or more new messages */ 08376 say_and_wait(chan, vms->newmessages, chan->language) || 08377 ast_play_and_wait(chan, "vm-nuovi") || 08378 ast_play_and_wait(chan, "vm-messages"); 08379 if (!res && vms->oldmessages) 08380 res = ast_play_and_wait(chan, "vm-and"); 08381 } 08382 if (!res && vms->oldmessages) { 08383 res = (vms->oldmessages == 1) ? 08384 ast_play_and_wait(chan, "digits/un") || 08385 ast_play_and_wait(chan, "vm-vecchio") || 08386 ast_play_and_wait(chan, "vm-message") : 08387 /* 2 or more old messages */ 08388 say_and_wait(chan, vms->oldmessages, chan->language) || 08389 ast_play_and_wait(chan, "vm-vecchi") || 08390 ast_play_and_wait(chan, "vm-messages"); 08391 } 08392 return res; 08393 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8197 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(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
08198 { 08199 int res; 08200 int lastnum = 0; 08201 08202 res = ast_play_and_wait(chan, "vm-youhave"); 08203 08204 if (!res && vms->newmessages) { 08205 lastnum = vms->newmessages; 08206 08207 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08208 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08209 } 08210 08211 if (!res && vms->oldmessages) { 08212 res = ast_play_and_wait(chan, "vm-and"); 08213 } 08214 } 08215 08216 if (!res && vms->oldmessages) { 08217 lastnum = vms->oldmessages; 08218 08219 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08220 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08221 } 08222 } 08223 08224 if (!res) { 08225 if (lastnum == 0) { 08226 res = ast_play_and_wait(chan, "vm-no"); 08227 } 08228 if (!res) { 08229 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08230 } 08231 } 08232 08233 return res; 08234 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8745 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08746 { 08747 /* Introduce messages they have */ 08748 int res; 08749 res = ast_play_and_wait(chan, "vm-youhave"); 08750 if (!res) { 08751 if (vms->newmessages) { 08752 res = say_and_wait(chan, vms->newmessages, chan->language); 08753 if (!res) { 08754 if (vms->newmessages == 1) 08755 res = ast_play_and_wait(chan, "vm-INBOXs"); 08756 else 08757 res = ast_play_and_wait(chan, "vm-INBOX"); 08758 } 08759 if (vms->oldmessages && !res) 08760 res = ast_play_and_wait(chan, "vm-and"); 08761 else if (!res) { 08762 if ((vms->newmessages == 1)) 08763 res = ast_play_and_wait(chan, "vm-message"); 08764 else 08765 res = ast_play_and_wait(chan, "vm-messages"); 08766 } 08767 08768 } 08769 if (!res && vms->oldmessages) { 08770 res = say_and_wait(chan, vms->oldmessages, chan->language); 08771 if (!res) { 08772 if (vms->oldmessages == 1) 08773 res = ast_play_and_wait(chan, "vm-Olds"); 08774 else 08775 res = ast_play_and_wait(chan, "vm-Old"); 08776 } 08777 if (!res) { 08778 if (vms->oldmessages == 1) 08779 res = ast_play_and_wait(chan, "vm-message"); 08780 else 08781 res = ast_play_and_wait(chan, "vm-messages"); 08782 } 08783 } 08784 if (!res) { 08785 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08786 res = ast_play_and_wait(chan, "vm-no"); 08787 if (!res) 08788 res = ast_play_and_wait(chan, "vm-messages"); 08789 } 08790 } 08791 } 08792 return res; 08793 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8511 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08512 { 08513 /* Introduce messages they have */ 08514 int res; 08515 08516 res = ast_play_and_wait(chan, "vm-youhave"); 08517 if (res) 08518 return res; 08519 08520 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08521 res = ast_play_and_wait(chan, "vm-no"); 08522 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08523 return res; 08524 } 08525 08526 if (vms->newmessages) { 08527 if ((vms->newmessages == 1)) { 08528 res = ast_play_and_wait(chan, "digits/1"); 08529 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08530 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08531 } else { 08532 res = say_and_wait(chan, vms->newmessages, chan->language); 08533 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08534 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08535 } 08536 if (!res && vms->oldmessages) 08537 res = ast_play_and_wait(chan, "vm-and"); 08538 } 08539 if (!res && vms->oldmessages) { 08540 if (vms->oldmessages == 1) { 08541 res = ast_play_and_wait(chan, "digits/1"); 08542 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08543 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08544 } else { 08545 res = say_and_wait(chan, vms->oldmessages, chan->language); 08546 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08547 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08548 } 08549 } 08550 08551 return res; 08552 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8396 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08397 { 08398 /* Introduce messages they have */ 08399 int res; 08400 div_t num; 08401 08402 if (!vms->oldmessages && !vms->newmessages) { 08403 res = ast_play_and_wait(chan, "vm-no"); 08404 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08405 return res; 08406 } else { 08407 res = ast_play_and_wait(chan, "vm-youhave"); 08408 } 08409 08410 if (vms->newmessages) { 08411 num = div(vms->newmessages, 10); 08412 if (vms->newmessages == 1) { 08413 res = ast_play_and_wait(chan, "digits/1-a"); 08414 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08415 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08416 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08417 if (num.rem == 2) { 08418 if (!num.quot) { 08419 res = ast_play_and_wait(chan, "digits/2-ie"); 08420 } else { 08421 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08422 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08423 } 08424 } else { 08425 res = say_and_wait(chan, vms->newmessages, chan->language); 08426 } 08427 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08428 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08429 } else { 08430 res = say_and_wait(chan, vms->newmessages, chan->language); 08431 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08432 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08433 } 08434 if (!res && vms->oldmessages) 08435 res = ast_play_and_wait(chan, "vm-and"); 08436 } 08437 if (!res && vms->oldmessages) { 08438 num = div(vms->oldmessages, 10); 08439 if (vms->oldmessages == 1) { 08440 res = ast_play_and_wait(chan, "digits/1-a"); 08441 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08442 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08443 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08444 if (num.rem == 2) { 08445 if (!num.quot) { 08446 res = ast_play_and_wait(chan, "digits/2-ie"); 08447 } else { 08448 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08449 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08450 } 08451 } else { 08452 res = say_and_wait(chan, vms->oldmessages, chan->language); 08453 } 08454 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08455 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08456 } else { 08457 res = say_and_wait(chan, vms->oldmessages, chan->language); 08458 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08459 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08460 } 08461 } 08462 08463 return res; 08464 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8796 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
08797 { 08798 /* Introduce messages they have */ 08799 int res; 08800 res = ast_play_and_wait(chan, "vm-youhave"); 08801 if (!res) { 08802 if (vms->newmessages) { 08803 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08804 if (!res) { 08805 if ((vms->newmessages == 1)) { 08806 res = ast_play_and_wait(chan, "vm-message"); 08807 if (!res) 08808 res = ast_play_and_wait(chan, "vm-INBOXs"); 08809 } else { 08810 res = ast_play_and_wait(chan, "vm-messages"); 08811 if (!res) 08812 res = ast_play_and_wait(chan, "vm-INBOX"); 08813 } 08814 } 08815 if (vms->oldmessages && !res) 08816 res = ast_play_and_wait(chan, "vm-and"); 08817 } 08818 if (!res && vms->oldmessages) { 08819 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08820 if (!res) { 08821 if (vms->oldmessages == 1) { 08822 res = ast_play_and_wait(chan, "vm-message"); 08823 if (!res) 08824 res = ast_play_and_wait(chan, "vm-Olds"); 08825 } else { 08826 res = ast_play_and_wait(chan, "vm-messages"); 08827 if (!res) 08828 res = ast_play_and_wait(chan, "vm-Old"); 08829 } 08830 } 08831 } 08832 if (!res) { 08833 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08834 res = ast_play_and_wait(chan, "vm-no"); 08835 if (!res) 08836 res = ast_play_and_wait(chan, "vm-messages"); 08837 } 08838 } 08839 } 08840 return res; 08841 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8657 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
08657 { 08658 /* Introduce messages they have */ 08659 int res; 08660 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08661 res = ast_play_and_wait(chan, "vm-nomessages"); 08662 return res; 08663 } else { 08664 res = ast_play_and_wait(chan, "vm-youhave"); 08665 } 08666 if (vms->newmessages) { 08667 if (!res) 08668 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08669 if ((vms->newmessages == 1)) { 08670 if (!res) 08671 res = ast_play_and_wait(chan, "vm-message"); 08672 if (!res) 08673 res = ast_play_and_wait(chan, "vm-INBOXs"); 08674 } else { 08675 if (!res) 08676 res = ast_play_and_wait(chan, "vm-messages"); 08677 if (!res) 08678 res = ast_play_and_wait(chan, "vm-INBOX"); 08679 } 08680 if (vms->oldmessages && !res) 08681 res = ast_play_and_wait(chan, "vm-and"); 08682 } 08683 if (vms->oldmessages) { 08684 if (!res) 08685 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08686 if (vms->oldmessages == 1) { 08687 if (!res) 08688 res = ast_play_and_wait(chan, "vm-message"); 08689 if (!res) 08690 res = ast_play_and_wait(chan, "vm-Olds"); 08691 } else { 08692 if (!res) 08693 res = ast_play_and_wait(chan, "vm-messages"); 08694 if (!res) 08695 res = ast_play_and_wait(chan, "vm-Old"); 08696 } 08697 } 08698 return res; 08699 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8467 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
08468 { 08469 /* Introduce messages they have */ 08470 int res; 08471 08472 res = ast_play_and_wait(chan, "vm-youhave"); 08473 if (res) 08474 return res; 08475 08476 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08477 res = ast_play_and_wait(chan, "vm-no"); 08478 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08479 return res; 08480 } 08481 08482 if (vms->newmessages) { 08483 if ((vms->newmessages == 1)) { 08484 res = ast_play_and_wait(chan, "digits/ett"); 08485 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08486 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08487 } else { 08488 res = say_and_wait(chan, vms->newmessages, chan->language); 08489 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08490 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08491 } 08492 if (!res && vms->oldmessages) 08493 res = ast_play_and_wait(chan, "vm-and"); 08494 } 08495 if (!res && vms->oldmessages) { 08496 if (vms->oldmessages == 1) { 08497 res = ast_play_and_wait(chan, "digits/ett"); 08498 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08499 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08500 } else { 08501 res = say_and_wait(chan, vms->oldmessages, chan->language); 08502 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08503 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08504 } 08505 } 08506 08507 return res; 08508 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8959 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08960 { 08961 int res; 08962 08963 /* Introduce messages they have */ 08964 res = ast_play_and_wait(chan, "vm-youhave"); 08965 if (!res) { 08966 if (vms->newmessages) { 08967 res = say_and_wait(chan, vms->newmessages, chan->language); 08968 if (!res) 08969 res = ast_play_and_wait(chan, "vm-INBOX"); 08970 if (vms->oldmessages && !res) 08971 res = ast_play_and_wait(chan, "vm-and"); 08972 } 08973 if (!res && vms->oldmessages) { 08974 res = say_and_wait(chan, vms->oldmessages, chan->language); 08975 if (!res) 08976 res = ast_play_and_wait(chan, "vm-Old"); 08977 } 08978 if (!res) { 08979 if (!vms->oldmessages && !vms->newmessages) { 08980 res = ast_play_and_wait(chan, "vm-no"); 08981 if (!res) 08982 res = ast_play_and_wait(chan, "vm-message"); 08983 } 08984 } 08985 } 08986 return res; 08987 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8920 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08921 { 08922 int res; 08923 /* Introduce messages they have */ 08924 res = ast_play_and_wait(chan, "vm-you"); 08925 08926 if (!res && vms->newmessages) { 08927 res = ast_play_and_wait(chan, "vm-have"); 08928 if (!res) 08929 res = say_and_wait(chan, vms->newmessages, chan->language); 08930 if (!res) 08931 res = ast_play_and_wait(chan, "vm-tong"); 08932 if (!res) 08933 res = ast_play_and_wait(chan, "vm-INBOX"); 08934 if (vms->oldmessages && !res) 08935 res = ast_play_and_wait(chan, "vm-and"); 08936 else if (!res) 08937 res = ast_play_and_wait(chan, "vm-messages"); 08938 } 08939 if (!res && vms->oldmessages) { 08940 res = ast_play_and_wait(chan, "vm-have"); 08941 if (!res) 08942 res = say_and_wait(chan, vms->oldmessages, chan->language); 08943 if (!res) 08944 res = ast_play_and_wait(chan, "vm-tong"); 08945 if (!res) 08946 res = ast_play_and_wait(chan, "vm-Old"); 08947 if (!res) 08948 res = ast_play_and_wait(chan, "vm-messages"); 08949 } 08950 if (!res && !vms->oldmessages && !vms->newmessages) { 08951 res = ast_play_and_wait(chan, "vm-haveno"); 08952 if (!res) 08953 res = ast_play_and_wait(chan, "vm-messages"); 08954 } 08955 return res; 08956 }
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 3237 of file app_voicemail_odbcstorage.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03238 { 03239 switch (ast_lock_path(path)) { 03240 case AST_LOCK_TIMEOUT: 03241 return -1; 03242 default: 03243 return 0; 03244 } 03245 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1639 of file app_voicemail_odbcstorage.c.
References my_umask, and VOICEMAIL_FILE_MODE.
01640 { 01641 FILE *p = NULL; 01642 int pfd = mkstemp(template); 01643 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01644 if (pfd > -1) { 01645 p = fdopen(pfd, "w+"); 01646 if (!p) { 01647 close(pfd); 01648 pfd = -1; 01649 } 01650 } 01651 return p; 01652 }
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 9162 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, ext_pass_cmd, maxgreet, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, and VM_SPOOL_DIR.
09163 { 09164 int cmd = 0; 09165 int duration = 0; 09166 int tries = 0; 09167 char newpassword[80] = ""; 09168 char newpassword2[80] = ""; 09169 char prefile[PATH_MAX] = ""; 09170 unsigned char buf[256]; 09171 int bytes = 0; 09172 09173 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09174 if (ast_adsi_available(chan)) { 09175 bytes += adsi_logo(buf + bytes); 09176 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09177 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09178 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09179 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09180 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09181 } 09182 09183 /* If forcename is set, have the user record their name */ 09184 if (ast_test_flag(vmu, VM_FORCENAME)) { 09185 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09186 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09187 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09188 if (cmd < 0 || cmd == 't' || cmd == '#') 09189 return cmd; 09190 } 09191 } 09192 09193 /* If forcegreetings is set, have the user record their greetings */ 09194 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09195 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09196 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09197 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09198 if (cmd < 0 || cmd == 't' || cmd == '#') 09199 return cmd; 09200 } 09201 09202 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09203 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09204 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09205 if (cmd < 0 || cmd == 't' || cmd == '#') 09206 return cmd; 09207 } 09208 } 09209 09210 /* 09211 * Change the password last since new users will be able to skip over any steps this one comes before 09212 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09213 */ 09214 for (;;) { 09215 newpassword[1] = '\0'; 09216 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09217 if (cmd == '#') 09218 newpassword[0] = '\0'; 09219 if (cmd < 0 || cmd == 't' || cmd == '#') 09220 return cmd; 09221 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09222 if (cmd < 0 || cmd == 't' || cmd == '#') 09223 return cmd; 09224 cmd = check_password(vmu, newpassword); /* perform password validation */ 09225 if (cmd != 0) { 09226 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09227 cmd = ast_play_and_wait(chan, vm_invalid_password); 09228 } else { 09229 newpassword2[1] = '\0'; 09230 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09231 if (cmd == '#') 09232 newpassword2[0] = '\0'; 09233 if (cmd < 0 || cmd == 't' || cmd == '#') 09234 return cmd; 09235 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09236 if (cmd < 0 || cmd == 't' || cmd == '#') 09237 return cmd; 09238 if (!strcmp(newpassword, newpassword2)) 09239 break; 09240 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09241 cmd = ast_play_and_wait(chan, vm_mismatch); 09242 } 09243 if (++tries == 3) 09244 return -1; 09245 if (cmd != 0) { 09246 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09247 } 09248 } 09249 if (pwdchange & PWDCHANGE_INTERNAL) 09250 vm_change_password(vmu, newpassword); 09251 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09252 vm_change_password_shell(vmu, newpassword); 09253 09254 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09255 cmd = ast_play_and_wait(chan, vm_passchanged); 09256 09257 return cmd; 09258 }
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 9260 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, ext_pass_cmd, ast_vm_user::mailbox, maxgreet, ast_vm_user::password, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, VM_SPOOL_DIR, and vm_tempgreeting().
09261 { 09262 int cmd = 0; 09263 int retries = 0; 09264 int duration = 0; 09265 char newpassword[80] = ""; 09266 char newpassword2[80] = ""; 09267 char prefile[PATH_MAX] = ""; 09268 unsigned char buf[256]; 09269 int bytes = 0; 09270 09271 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09272 if (ast_adsi_available(chan)) { 09273 bytes += adsi_logo(buf + bytes); 09274 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09275 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09276 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09277 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09278 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09279 } 09280 while ((cmd >= 0) && (cmd != 't')) { 09281 if (cmd) 09282 retries = 0; 09283 switch (cmd) { 09284 case '1': /* Record your unavailable message */ 09285 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09286 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09287 break; 09288 case '2': /* Record your busy message */ 09289 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09290 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09291 break; 09292 case '3': /* Record greeting */ 09293 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09294 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09295 break; 09296 case '4': /* manage the temporary greeting */ 09297 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09298 break; 09299 case '5': /* change password */ 09300 if (vmu->password[0] == '-') { 09301 cmd = ast_play_and_wait(chan, "vm-no"); 09302 break; 09303 } 09304 newpassword[1] = '\0'; 09305 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09306 if (cmd == '#') 09307 newpassword[0] = '\0'; 09308 else { 09309 if (cmd < 0) 09310 break; 09311 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09312 break; 09313 } 09314 } 09315 cmd = check_password(vmu, newpassword); /* perform password validation */ 09316 if (cmd != 0) { 09317 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09318 cmd = ast_play_and_wait(chan, vm_invalid_password); 09319 if (!cmd) { 09320 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09321 } 09322 break; 09323 } 09324 newpassword2[1] = '\0'; 09325 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09326 if (cmd == '#') 09327 newpassword2[0] = '\0'; 09328 else { 09329 if (cmd < 0) 09330 break; 09331 09332 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09333 break; 09334 } 09335 } 09336 if (strcmp(newpassword, newpassword2)) { 09337 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09338 cmd = ast_play_and_wait(chan, vm_mismatch); 09339 if (!cmd) { 09340 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09341 } 09342 break; 09343 } 09344 09345 if (pwdchange & PWDCHANGE_INTERNAL) { 09346 vm_change_password(vmu, newpassword); 09347 } 09348 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09349 vm_change_password_shell(vmu, newpassword); 09350 } 09351 09352 ast_debug(1, "User %s set password to %s of length %d\n", 09353 vms->username, newpassword, (int) strlen(newpassword)); 09354 cmd = ast_play_and_wait(chan, vm_passchanged); 09355 break; 09356 case '*': 09357 cmd = 't'; 09358 break; 09359 default: 09360 cmd = 0; 09361 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09362 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09363 if (ast_fileexists(prefile, NULL, NULL)) { 09364 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09365 } 09366 DISPOSE(prefile, -1); 09367 if (!cmd) { 09368 cmd = ast_play_and_wait(chan, "vm-options"); 09369 } 09370 if (!cmd) { 09371 cmd = ast_waitfordigit(chan, 6000); 09372 } 09373 if (!cmd) { 09374 retries++; 09375 } 09376 if (retries > 3) { 09377 cmd = 't'; 09378 } 09379 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09380 } 09381 } 09382 if (cmd == 't') 09383 cmd = 0; 09384 return cmd; 09385 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8066 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().
08067 { 08068 int cmd; 08069 08070 if ( !strncasecmp(chan->language, "it", 2) || 08071 !strncasecmp(chan->language, "es", 2) || 08072 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08073 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08074 return cmd ? cmd : ast_play_and_wait(chan, box); 08075 } else if (!strncasecmp(chan->language, "gr", 2)) { 08076 return vm_play_folder_name_gr(chan, box); 08077 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08078 return ast_play_and_wait(chan, box); 08079 } else if (!strncasecmp(chan->language, "pl", 2)) { 08080 return vm_play_folder_name_pl(chan, box); 08081 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08082 return vm_play_folder_name_ua(chan, box); 08083 } else if (!strncasecmp(chan->language, "vi", 2)) { 08084 return ast_play_and_wait(chan, box); 08085 } else { /* Default English */ 08086 cmd = ast_play_and_wait(chan, box); 08087 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08088 } 08089 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8019 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
08020 { 08021 int cmd; 08022 char *buf; 08023 08024 buf = alloca(strlen(box) + 2); 08025 strcpy(buf, box); 08026 strcat(buf, "s"); 08027 08028 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08029 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08030 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08031 } else { 08032 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08033 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08034 } 08035 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8037 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
08038 { 08039 int cmd; 08040 08041 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08042 if (!strcasecmp(box, "vm-INBOX")) 08043 cmd = ast_play_and_wait(chan, "vm-new-e"); 08044 else 08045 cmd = ast_play_and_wait(chan, "vm-old-e"); 08046 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08047 } else { 08048 cmd = ast_play_and_wait(chan, "vm-messages"); 08049 return cmd ? cmd : ast_play_and_wait(chan, box); 08050 } 08051 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8053 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
08054 { 08055 int cmd; 08056 08057 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08058 cmd = ast_play_and_wait(chan, "vm-messages"); 08059 return cmd ? cmd : ast_play_and_wait(chan, box); 08060 } else { 08061 cmd = ast_play_and_wait(chan, box); 08062 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08063 } 08064 }
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 9403 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, maxgreet, play_record_review(), RETRIEVE, vm_state::username, and VM_SPOOL_DIR.
09404 { 09405 int cmd = 0; 09406 int retries = 0; 09407 int duration = 0; 09408 char prefile[PATH_MAX] = ""; 09409 unsigned char buf[256]; 09410 int bytes = 0; 09411 09412 if (ast_adsi_available(chan)) { 09413 bytes += adsi_logo(buf + bytes); 09414 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09415 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09416 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09417 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09418 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09419 } 09420 09421 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09422 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09423 while ((cmd >= 0) && (cmd != 't')) { 09424 if (cmd) 09425 retries = 0; 09426 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09427 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09428 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09429 cmd = 't'; 09430 } else { 09431 switch (cmd) { 09432 case '1': 09433 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09434 break; 09435 case '2': 09436 DELETE(prefile, -1, prefile, vmu); 09437 ast_play_and_wait(chan, "vm-tempremoved"); 09438 cmd = 't'; 09439 break; 09440 case '*': 09441 cmd = 't'; 09442 break; 09443 default: 09444 cmd = ast_play_and_wait(chan, 09445 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09446 "vm-tempgreeting2" : "vm-tempgreeting"); 09447 if (!cmd) { 09448 cmd = ast_waitfordigit(chan, 6000); 09449 } 09450 if (!cmd) { 09451 retries++; 09452 } 09453 if (retries > 3) { 09454 cmd = 't'; 09455 } 09456 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09457 } 09458 } 09459 DISPOSE(prefile, -1); 09460 } 09461 if (cmd == 't') 09462 cmd = 0; 09463 return cmd; 09464 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11366 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::list, user, and vm_users_data_provider_get_helper().
11368 { 11369 struct ast_vm_user *user; 11370 11371 AST_LIST_LOCK(&users); 11372 AST_LIST_TRAVERSE(&users, user, list) { 11373 vm_users_data_provider_get_helper(search, data_root, user); 11374 } 11375 AST_LIST_UNLOCK(&users); 11376 11377 return 0; 11378 }
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 11319 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, inboxcount2(), vm_zone::list, vm_zone::name, and user.
11321 { 11322 struct ast_data *data_user, *data_zone; 11323 struct ast_data *data_state; 11324 struct vm_zone *zone = NULL; 11325 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11326 char ext_context[256] = ""; 11327 11328 data_user = ast_data_add_node(data_root, "user"); 11329 if (!data_user) { 11330 return -1; 11331 } 11332 11333 ast_data_add_structure(ast_vm_user, data_user, user); 11334 11335 AST_LIST_LOCK(&zones); 11336 AST_LIST_TRAVERSE(&zones, zone, list) { 11337 if (!strcmp(zone->name, user->zonetag)) { 11338 break; 11339 } 11340 } 11341 AST_LIST_UNLOCK(&zones); 11342 11343 /* state */ 11344 data_state = ast_data_add_node(data_user, "state"); 11345 if (!data_state) { 11346 return -1; 11347 } 11348 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11349 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11350 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11351 ast_data_add_int(data_state, "newmsg", newmsg); 11352 ast_data_add_int(data_state, "oldmsg", oldmsg); 11353 11354 if (zone) { 11355 data_zone = ast_data_add_node(data_user, "zone"); 11356 ast_data_add_structure(vm_zone, data_zone, zone); 11357 } 11358 11359 if (!ast_data_search_match(search, data_user)) { 11360 ast_data_remove_node(data_root, data_user); 11361 } 11362 11363 return 0; 11364 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11005 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(), strsep(), and vm_authenticate().
11006 { 11007 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11008 struct ast_vm_user vmus; 11009 char *options = NULL; 11010 int silent = 0, skipuser = 0; 11011 int res = -1; 11012 11013 if (data) { 11014 s = ast_strdupa(data); 11015 user = strsep(&s, ","); 11016 options = strsep(&s, ","); 11017 if (user) { 11018 s = user; 11019 user = strsep(&s, "@"); 11020 context = strsep(&s, ""); 11021 if (!ast_strlen_zero(user)) 11022 skipuser++; 11023 ast_copy_string(mailbox, user, sizeof(mailbox)); 11024 } 11025 } 11026 11027 if (options) { 11028 silent = (strchr(options, 's')) != NULL; 11029 } 11030 11031 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11032 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11033 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11034 ast_play_and_wait(chan, "auth-thankyou"); 11035 res = 0; 11036 } else if (mailbox[0] == '*') { 11037 /* user entered '*' */ 11038 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11039 res = 0; /* prevent hangup */ 11040 } 11041 } 11042 11043 return res; 11044 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12523 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(), ast_channel::language, LOG_WARNING, and sayname().
12524 { 12525 char *context; 12526 char *args_copy; 12527 int res; 12528 12529 if (ast_strlen_zero(data)) { 12530 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12531 return -1; 12532 } 12533 12534 args_copy = ast_strdupa(data); 12535 if ((context = strchr(args_copy, '@'))) { 12536 *context++ = '\0'; 12537 } else { 12538 context = "default"; 12539 } 12540 12541 if ((res = sayname(chan, args_copy, context) < 0)) { 12542 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12543 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12544 if (!res) { 12545 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12546 } 12547 } 12548 12549 return res; 12550 }
static struct ast_tm* vmu_tm | ( | const struct ast_vm_user * | vmu, | |
struct ast_tm * | tm | |||
) | [static] |
fill in *tm for current time according to the proper timezone, if any.
Definition at line 4392 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_tvnow(), vm_zone::name, vm_zone::timezone, and ast_vm_user::zonetag.
04393 { 04394 const struct vm_zone *z = NULL; 04395 struct timeval t = ast_tvnow(); 04396 04397 /* Does this user have a timezone specified? */ 04398 if (!ast_strlen_zero(vmu->zonetag)) { 04399 /* Find the zone in the list */ 04400 AST_LIST_LOCK(&zones); 04401 AST_LIST_TRAVERSE(&zones, z, list) { 04402 if (!strcmp(z->name, vmu->zonetag)) 04403 break; 04404 } 04405 AST_LIST_UNLOCK(&zones); 04406 } 04407 ast_localtime(&t, tm, z ? z->timezone : NULL); 04408 return tm; 04409 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7427 of file app_voicemail_odbcstorage.c.
References ast_control_streamfile(), ast_test_suite_event_notify, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, and skipms.
07428 { 07429 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07430 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); 07431 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7419 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_log(), and ast_stream_and_wait().
07420 { 07421 int res; 07422 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07423 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07424 return res; 07425 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12497 of file app_voicemail_odbcstorage.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
12497 { 12498 struct ast_config *conf; 12499 struct ast_category *cat; 12500 struct ast_variable *var; 12501 12502 if (!(conf=ast_config_new())) { 12503 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12504 return -1; 12505 } 12506 if (!(cat=ast_category_new("general","",1))) { 12507 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12508 return -1; 12509 } 12510 if (!(var=ast_variable_new("password",password,""))) { 12511 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12512 return -1; 12513 } 12514 ast_category_append(conf,cat); 12515 ast_variable_append(cat,var); 12516 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12517 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12518 return -1; 12519 } 12520 return 0; 12521 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13602 of file app_voicemail_odbcstorage.c.
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.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13602 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] |
Initial value:
{ { .handler = handle_voicemail_show_users , .summary = "List defined voicemail boxes" ,__VA_ARGS__ }, { .handler = handle_voicemail_show_zones , .summary = "List zone message formats" ,__VA_ARGS__ }, { .handler = handle_voicemail_reload , .summary = "Reload voicemail configuration" ,__VA_ARGS__ }, }
Definition at line 11242 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] |
Initial value:
{ .name = "MAILBOX_EXISTS", .read = acf_mailbox_exists, }
Definition at line 11000 of file app_voicemail_odbcstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1675 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.
ast_mutex_t poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 794 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_app_option vm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} [static] |
Definition at line 513 of file app_voicemail_odbcstorage.c.
struct ast_data_entry vm_data_providers[] [static] |
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] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11380 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.