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