#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 | 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, 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 | 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } |
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_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 404 of file app_voicemail_odbcstorage.c.
#define BASELINELEN 72 |
Definition at line 427 of file app_voicemail_odbcstorage.c.
#define BASEMAXINLINE 256 |
Definition at line 428 of file app_voicemail_odbcstorage.c.
#define CHUNKSIZE 65536 |
Definition at line 401 of file app_voicemail_odbcstorage.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 397 of file app_voicemail_odbcstorage.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
Definition at line 711 of file app_voicemail_odbcstorage.c.
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 10997 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 11025 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 409 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 411 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 412 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 410 of file app_voicemail_odbcstorage.c.
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 413 of file app_voicemail_odbcstorage.c.
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 781 of file app_voicemail_odbcstorage.c.
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 712 of file app_voicemail_odbcstorage.c.
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 707 of file app_voicemail_odbcstorage.c.
#define ENDL "\n" |
Definition at line 432 of file app_voicemail_odbcstorage.c.
#define ERROR_LOCK_PATH -100 |
Definition at line 457 of file app_voicemail_odbcstorage.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 709 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 420 of file app_voicemail_odbcstorage.c.
#define MAX_DATETIME_FORMAT 512 |
Definition at line 435 of file app_voicemail_odbcstorage.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 436 of file app_voicemail_odbcstorage.c.
#define MAXMSG 100 |
Definition at line 422 of file app_voicemail_odbcstorage.c.
#define MAXMSGLIMIT 9999 |
Definition at line 423 of file app_voicemail_odbcstorage.c.
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 425 of file app_voicemail_odbcstorage.c.
#define OPERATOR_EXIT 300 |
Definition at line 458 of file app_voicemail_odbcstorage.c.
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 724 of file app_voicemail_odbcstorage.c.
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 723 of file app_voicemail_odbcstorage.c.
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 710 of file app_voicemail_odbcstorage.c.
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 706 of file app_voicemail_odbcstorage.c.
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 418 of file app_voicemail_odbcstorage.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 395 of file app_voicemail_odbcstorage.c.
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 708 of file app_voicemail_odbcstorage.c.
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 733 of file app_voicemail_odbcstorage.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 414 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 451 of file app_voicemail_odbcstorage.c.
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 449 of file app_voicemail_odbcstorage.c.
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 450 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 448 of file app_voicemail_odbcstorage.c.
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 442 of file app_voicemail_odbcstorage.c.
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 446 of file app_voicemail_odbcstorage.c.
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 445 of file app_voicemail_odbcstorage.c.
#define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 456 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 455 of file app_voicemail_odbcstorage.c.
#define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 454 of file app_voicemail_odbcstorage.c.
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 439 of file app_voicemail_odbcstorage.c.
#define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 447 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 438 of file app_voicemail_odbcstorage.c.
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 440 of file app_voicemail_odbcstorage.c.
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 443 of file app_voicemail_odbcstorage.c.
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 452 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 444 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 441 of file app_voicemail_odbcstorage.c.
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 453 of file app_voicemail_odbcstorage.c.
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 648 of file app_voicemail_odbcstorage.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 403 of file app_voicemail_odbcstorage.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 399 of file app_voicemail_odbcstorage.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 400 of file app_voicemail_odbcstorage.c.
enum vm_box |
Definition at line 461 of file app_voicemail_odbcstorage.c.
00461 { 00462 NEW_FOLDER, 00463 OLD_FOLDER, 00464 WORK_FOLDER, 00465 FAMILY_FOLDER, 00466 FRIENDS_FOLDER, 00467 GREETINGS_FOLDER 00468 };
enum vm_option_args |
Definition at line 482 of file app_voicemail_odbcstorage.c.
00482 { 00483 OPT_ARG_RECORDGAIN = 0, 00484 OPT_ARG_PLAYFOLDER = 1, 00485 OPT_ARG_DTMFEXIT = 2, 00486 /* This *must* be the last value in this enum! */ 00487 OPT_ARG_ARRAY_SIZE = 3, 00488 };
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 470 of file app_voicemail_odbcstorage.c.
00470 { 00471 OPT_SILENT = (1 << 0), 00472 OPT_BUSY_GREETING = (1 << 1), 00473 OPT_UNAVAIL_GREETING = (1 << 2), 00474 OPT_RECORDGAIN = (1 << 3), 00475 OPT_PREPEND_MAILBOX = (1 << 4), 00476 OPT_AUTOPLAY = (1 << 6), 00477 OPT_DTMFEXIT = (1 << 7), 00478 OPT_MESSAGE_Urgent = (1 << 8), 00479 OPT_MESSAGE_PRIORITY = (1 << 9) 00480 };
enum vm_passwordlocation |
Definition at line 490 of file app_voicemail_odbcstorage.c.
00490 { 00491 OPT_PWLOC_VOICEMAILCONF = 0, 00492 OPT_PWLOC_SPOOLDIR = 1, 00493 OPT_PWLOC_USERSCONF = 2, 00494 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5237 of file app_voicemail_odbcstorage.c.
References ast_strlen_zero().
05238 { 05239 DIR *dir; 05240 struct dirent *de; 05241 char fn[256]; 05242 int ret = 0; 05243 05244 /* If no mailbox, return immediately */ 05245 if (ast_strlen_zero(mailbox)) 05246 return 0; 05247 05248 if (ast_strlen_zero(folder)) 05249 folder = "INBOX"; 05250 if (ast_strlen_zero(context)) 05251 context = "default"; 05252 05253 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05254 05255 if (!(dir = opendir(fn))) 05256 return 0; 05257 05258 while ((de = readdir(dir))) { 05259 if (!strncasecmp(de->d_name, "msg", 3)) { 05260 if (shortcircuit) { 05261 ret = 1; 05262 break; 05263 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05264 ret++; 05265 } 05266 } 05267 } 05268 05269 closedir(dir); 05270 05271 return ret; 05272 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13197 of file app_voicemail_odbcstorage.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13197 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 10701 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().
10702 { 10703 struct ast_vm_user svm; 10704 AST_DECLARE_APP_ARGS(arg, 10705 AST_APP_ARG(mbox); 10706 AST_APP_ARG(context); 10707 ); 10708 10709 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 10710 10711 if (ast_strlen_zero(arg.mbox)) { 10712 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 10713 return -1; 10714 } 10715 10716 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 10717 return 0; 10718 }
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 4655 of file app_voicemail_odbcstorage.c.
References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
04656 { 04657 char tmpdir[256], newtmp[256]; 04658 char fname[256]; 04659 char tmpcmd[256]; 04660 int tmpfd = -1; 04661 04662 /* Eww. We want formats to tell us their own MIME type */ 04663 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04664 04665 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04666 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04667 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04668 tmpfd = mkstemp(newtmp); 04669 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04670 ast_debug(3, "newtmp: %s\n", newtmp); 04671 if (tmpfd > -1) { 04672 int soxstatus; 04673 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04674 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04675 attach = newtmp; 04676 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04677 } else { 04678 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04679 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04680 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04681 } 04682 } 04683 } 04684 fprintf(p, "--%s" ENDL, bound); 04685 if (msgnum > -1) 04686 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04687 else 04688 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04689 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04690 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04691 if (msgnum > -1) 04692 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04693 else 04694 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04695 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04696 base_encode(fname, p); 04697 if (last) 04698 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04699 if (tmpfd > -1) { 04700 unlink(fname); 04701 close(tmpfd); 04702 unlink(newtmp); 04703 } 04704 return 0; 04705 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6223 of file app_voicemail_odbcstorage.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), and ast_log().
06224 { 06225 int x; 06226 if (!ast_adsi_available(chan)) 06227 return; 06228 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06229 if (x < 0) 06230 return; 06231 if (!x) { 06232 if (adsi_load_vmail(chan, useadsi)) { 06233 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06234 return; 06235 } 06236 } else 06237 *useadsi = 1; 06238 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6412 of file app_voicemail_odbcstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
06413 { 06414 int bytes = 0; 06415 unsigned char buf[256]; 06416 unsigned char keys[8]; 06417 06418 int x; 06419 06420 if (!ast_adsi_available(chan)) 06421 return; 06422 06423 /* New meaning for keys */ 06424 for (x = 0; x < 5; x++) 06425 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06426 06427 keys[6] = 0x0; 06428 keys[7] = 0x0; 06429 06430 if (!vms->curmsg) { 06431 /* No prev key, provide "Folder" instead */ 06432 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06433 } 06434 if (vms->curmsg >= vms->lastmsg) { 06435 /* If last message ... */ 06436 if (vms->curmsg) { 06437 /* but not only message, provide "Folder" instead */ 06438 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06439 } else { 06440 /* Otherwise if only message, leave blank */ 06441 keys[3] = 1; 06442 } 06443 } 06444 06445 /* If deleted, show "undeleted" */ 06446 if (vms->deleted[vms->curmsg]) 06447 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06448 06449 /* Except "Exit" */ 06450 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06451 bytes += ast_adsi_set_keys(buf + bytes, keys); 06452 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06453 06454 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06455 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6288 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().
06289 { 06290 unsigned char buf[256]; 06291 int bytes = 0; 06292 unsigned char keys[8]; 06293 int x, y; 06294 06295 if (!ast_adsi_available(chan)) 06296 return; 06297 06298 for (x = 0; x < 5; x++) { 06299 y = ADSI_KEY_APPS + 12 + start + x; 06300 if (y > ADSI_KEY_APPS + 12 + 4) 06301 y = 0; 06302 keys[x] = ADSI_KEY_SKT | y; 06303 } 06304 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06305 keys[6] = 0; 06306 keys[7] = 0; 06307 06308 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06309 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06310 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06311 bytes += ast_adsi_set_keys(buf + bytes, keys); 06312 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06313 06314 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06315 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6560 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().
06561 { 06562 unsigned char buf[256]; 06563 int bytes = 0; 06564 06565 if (!ast_adsi_available(chan)) 06566 return; 06567 bytes += adsi_logo(buf + bytes); 06568 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06569 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06570 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06571 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06572 06573 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06574 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6094 of file app_voicemail_odbcstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, 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().
06095 { 06096 unsigned char buf[256]; 06097 int bytes = 0; 06098 int x; 06099 char num[5]; 06100 06101 *useadsi = 0; 06102 bytes += ast_adsi_data_mode(buf + bytes); 06103 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06104 06105 bytes = 0; 06106 bytes += adsi_logo(buf); 06107 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06108 #ifdef DISPLAY 06109 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06110 #endif 06111 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06112 bytes += ast_adsi_data_mode(buf + bytes); 06113 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06114 06115 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06116 bytes = 0; 06117 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06118 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06119 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06120 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06121 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06122 return 0; 06123 } 06124 06125 #ifdef DISPLAY 06126 /* Add a dot */ 06127 bytes = 0; 06128 bytes += ast_adsi_logo(buf); 06129 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06130 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06131 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06132 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06133 #endif 06134 bytes = 0; 06135 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06136 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06137 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06138 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06139 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06140 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06141 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06142 06143 #ifdef DISPLAY 06144 /* Add another dot */ 06145 bytes = 0; 06146 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06147 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06148 06149 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06150 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06151 #endif 06152 06153 bytes = 0; 06154 /* These buttons we load but don't use yet */ 06155 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06156 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06157 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06158 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06159 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06160 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06161 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06162 06163 #ifdef DISPLAY 06164 /* Add another dot */ 06165 bytes = 0; 06166 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06167 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06168 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06169 #endif 06170 06171 bytes = 0; 06172 for (x = 0; x < 5; x++) { 06173 snprintf(num, sizeof(num), "%d", x); 06174 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06175 } 06176 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06177 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06178 06179 #ifdef DISPLAY 06180 /* Add another dot */ 06181 bytes = 0; 06182 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06183 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06184 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06185 #endif 06186 06187 if (ast_adsi_end_download(chan)) { 06188 bytes = 0; 06189 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06190 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06191 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06192 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06193 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06194 return 0; 06195 } 06196 bytes = 0; 06197 bytes += ast_adsi_download_disconnect(buf + bytes); 06198 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06199 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06200 06201 ast_debug(1, "Done downloading scripts...\n"); 06202 06203 #ifdef DISPLAY 06204 /* Add last dot */ 06205 bytes = 0; 06206 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06207 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06208 #endif 06209 ast_debug(1, "Restarting session...\n"); 06210 06211 bytes = 0; 06212 /* Load the session now */ 06213 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06214 *useadsi = 1; 06215 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06216 } else 06217 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06218 06219 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06220 return 0; 06221 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6240 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().
06241 { 06242 unsigned char buf[256]; 06243 int bytes = 0; 06244 unsigned char keys[8]; 06245 int x; 06246 if (!ast_adsi_available(chan)) 06247 return; 06248 06249 for (x = 0; x < 8; x++) 06250 keys[x] = 0; 06251 /* Set one key for next */ 06252 keys[3] = ADSI_KEY_APPS + 3; 06253 06254 bytes += adsi_logo(buf + bytes); 06255 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06256 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06257 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06258 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06259 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06260 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06261 bytes += ast_adsi_set_keys(buf + bytes, keys); 06262 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06263 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06264 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6086 of file app_voicemail_odbcstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().
06087 { 06088 int bytes = 0; 06089 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06090 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06091 return bytes; 06092 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6317 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, and strsep().
06318 { 06319 int bytes = 0; 06320 unsigned char buf[256]; 06321 char buf1[256], buf2[256]; 06322 char fn2[PATH_MAX]; 06323 06324 char cid[256] = ""; 06325 char *val; 06326 char *name, *num; 06327 char datetime[21] = ""; 06328 FILE *f; 06329 06330 unsigned char keys[8]; 06331 06332 int x; 06333 06334 if (!ast_adsi_available(chan)) 06335 return; 06336 06337 /* Retrieve important info */ 06338 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06339 f = fopen(fn2, "r"); 06340 if (f) { 06341 while (!feof(f)) { 06342 if (!fgets((char *) buf, sizeof(buf), f)) { 06343 continue; 06344 } 06345 if (!feof(f)) { 06346 char *stringp = NULL; 06347 stringp = (char *) buf; 06348 strsep(&stringp, "="); 06349 val = strsep(&stringp, "="); 06350 if (!ast_strlen_zero(val)) { 06351 if (!strcmp((char *) buf, "callerid")) 06352 ast_copy_string(cid, val, sizeof(cid)); 06353 if (!strcmp((char *) buf, "origdate")) 06354 ast_copy_string(datetime, val, sizeof(datetime)); 06355 } 06356 } 06357 } 06358 fclose(f); 06359 } 06360 /* New meaning for keys */ 06361 for (x = 0; x < 5; x++) 06362 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06363 keys[6] = 0x0; 06364 keys[7] = 0x0; 06365 06366 if (!vms->curmsg) { 06367 /* No prev key, provide "Folder" instead */ 06368 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06369 } 06370 if (vms->curmsg >= vms->lastmsg) { 06371 /* If last message ... */ 06372 if (vms->curmsg) { 06373 /* but not only message, provide "Folder" instead */ 06374 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06375 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06376 06377 } else { 06378 /* Otherwise if only message, leave blank */ 06379 keys[3] = 1; 06380 } 06381 } 06382 06383 if (!ast_strlen_zero(cid)) { 06384 ast_callerid_parse(cid, &name, &num); 06385 if (!name) 06386 name = num; 06387 } else 06388 name = "Unknown Caller"; 06389 06390 /* If deleted, show "undeleted" */ 06391 06392 if (vms->deleted[vms->curmsg]) 06393 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06394 06395 /* Except "Exit" */ 06396 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06397 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06398 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06399 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06400 06401 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06402 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06403 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06404 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06405 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06406 bytes += ast_adsi_set_keys(buf + bytes, keys); 06407 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06408 06409 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06410 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6266 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().
06267 { 06268 unsigned char buf[256]; 06269 int bytes = 0; 06270 unsigned char keys[8]; 06271 int x; 06272 if (!ast_adsi_available(chan)) 06273 return; 06274 06275 for (x = 0; x < 8; x++) 06276 keys[x] = 0; 06277 /* Set one key for next */ 06278 keys[3] = ADSI_KEY_APPS + 3; 06279 06280 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06281 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06282 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06283 bytes += ast_adsi_set_keys(buf + bytes, keys); 06284 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06285 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06286 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6457 of file app_voicemail_odbcstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
06458 { 06459 unsigned char buf[256] = ""; 06460 char buf1[256] = "", buf2[256] = ""; 06461 int bytes = 0; 06462 unsigned char keys[8]; 06463 int x; 06464 06465 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06466 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06467 if (!ast_adsi_available(chan)) 06468 return; 06469 if (vms->newmessages) { 06470 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06471 if (vms->oldmessages) { 06472 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06473 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06474 } else { 06475 snprintf(buf2, sizeof(buf2), "%s.", newm); 06476 } 06477 } else if (vms->oldmessages) { 06478 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06479 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06480 } else { 06481 strcpy(buf1, "You have no messages."); 06482 buf2[0] = ' '; 06483 buf2[1] = '\0'; 06484 } 06485 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06486 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06487 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06488 06489 for (x = 0; x < 6; x++) 06490 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06491 keys[6] = 0; 06492 keys[7] = 0; 06493 06494 /* Don't let them listen if there are none */ 06495 if (vms->lastmsg < 0) 06496 keys[0] = 1; 06497 bytes += ast_adsi_set_keys(buf + bytes, keys); 06498 06499 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06500 06501 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06502 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6504 of file app_voicemail_odbcstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curbox, and vm_state::lastmsg.
06505 { 06506 unsigned char buf[256] = ""; 06507 char buf1[256] = "", buf2[256] = ""; 06508 int bytes = 0; 06509 unsigned char keys[8]; 06510 int x; 06511 06512 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06513 06514 if (!ast_adsi_available(chan)) 06515 return; 06516 06517 /* Original command keys */ 06518 for (x = 0; x < 6; x++) 06519 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06520 06521 keys[6] = 0; 06522 keys[7] = 0; 06523 06524 if ((vms->lastmsg + 1) < 1) 06525 keys[0] = 0; 06526 06527 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06528 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06529 06530 if (vms->lastmsg + 1) 06531 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06532 else 06533 strcpy(buf2, "no messages."); 06534 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06535 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06536 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06537 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06538 bytes += ast_adsi_set_keys(buf + bytes, keys); 06539 06540 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06541 06542 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06543 06544 }
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 12763 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_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, and wait_file().
12764 { 12765 int res = 0; 12766 char filename[PATH_MAX]; 12767 struct ast_config *msg_cfg = NULL; 12768 const char *origtime, *context; 12769 char *name, *num; 12770 int retries = 0; 12771 char *cid; 12772 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 12773 12774 vms->starting = 0; 12775 12776 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 12777 12778 /* Retrieve info from VM attribute file */ 12779 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 12780 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 12781 msg_cfg = ast_config_load(filename, config_flags); 12782 DISPOSE(vms->curdir, vms->curmsg); 12783 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 12784 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 12785 return 0; 12786 } 12787 12788 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 12789 ast_config_destroy(msg_cfg); 12790 return 0; 12791 } 12792 12793 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 12794 12795 context = ast_variable_retrieve(msg_cfg, "message", "context"); 12796 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 12797 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 12798 switch (option) { 12799 case 3: /* Play message envelope */ 12800 if (!res) 12801 res = play_message_datetime(chan, vmu, origtime, filename); 12802 if (!res) 12803 res = play_message_callerid(chan, vms, cid, context, 0); 12804 12805 res = 't'; 12806 break; 12807 12808 case 2: /* Call back */ 12809 12810 if (ast_strlen_zero(cid)) 12811 break; 12812 12813 ast_callerid_parse(cid, &name, &num); 12814 while ((res > -1) && (res != 't')) { 12815 switch (res) { 12816 case '1': 12817 if (num) { 12818 /* Dial the CID number */ 12819 res = dialout(chan, vmu, num, vmu->callback); 12820 if (res) { 12821 ast_config_destroy(msg_cfg); 12822 return 9; 12823 } 12824 } else { 12825 res = '2'; 12826 } 12827 break; 12828 12829 case '2': 12830 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 12831 if (!ast_strlen_zero(vmu->dialout)) { 12832 res = dialout(chan, vmu, NULL, vmu->dialout); 12833 if (res) { 12834 ast_config_destroy(msg_cfg); 12835 return 9; 12836 } 12837 } else { 12838 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 12839 res = ast_play_and_wait(chan, "vm-sorry"); 12840 } 12841 ast_config_destroy(msg_cfg); 12842 return res; 12843 case '*': 12844 res = 't'; 12845 break; 12846 case '3': 12847 case '4': 12848 case '5': 12849 case '6': 12850 case '7': 12851 case '8': 12852 case '9': 12853 case '0': 12854 12855 res = ast_play_and_wait(chan, "vm-sorry"); 12856 retries++; 12857 break; 12858 default: 12859 if (num) { 12860 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 12861 res = ast_play_and_wait(chan, "vm-num-i-have"); 12862 if (!res) 12863 res = play_message_callerid(chan, vms, num, vmu->context, 1); 12864 if (!res) 12865 res = ast_play_and_wait(chan, "vm-tocallnum"); 12866 /* Only prompt for a caller-specified number if there is a dialout context specified */ 12867 if (!ast_strlen_zero(vmu->dialout)) { 12868 if (!res) 12869 res = ast_play_and_wait(chan, "vm-calldiffnum"); 12870 } 12871 } else { 12872 res = ast_play_and_wait(chan, "vm-nonumber"); 12873 if (!ast_strlen_zero(vmu->dialout)) { 12874 if (!res) 12875 res = ast_play_and_wait(chan, "vm-toenternumber"); 12876 } 12877 } 12878 if (!res) 12879 res = ast_play_and_wait(chan, "vm-star-cancel"); 12880 if (!res) 12881 res = ast_waitfordigit(chan, 6000); 12882 if (!res) { 12883 retries++; 12884 if (retries > 3) 12885 res = 't'; 12886 } 12887 break; 12888 12889 } 12890 if (res == 't') 12891 res = 0; 12892 else if (res == '*') 12893 res = -1; 12894 } 12895 break; 12896 12897 case 1: /* Reply */ 12898 /* Send reply directly to sender */ 12899 if (ast_strlen_zero(cid)) 12900 break; 12901 12902 ast_callerid_parse(cid, &name, &num); 12903 if (!num) { 12904 ast_verb(3, "No CID number available, no reply sent\n"); 12905 if (!res) 12906 res = ast_play_and_wait(chan, "vm-nonumber"); 12907 ast_config_destroy(msg_cfg); 12908 return res; 12909 } else { 12910 struct ast_vm_user vmu2; 12911 if (find_user(&vmu2, vmu->context, num)) { 12912 struct leave_vm_options leave_options; 12913 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 12914 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 12915 12916 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 12917 12918 memset(&leave_options, 0, sizeof(leave_options)); 12919 leave_options.record_gain = record_gain; 12920 res = leave_voicemail(chan, mailbox, &leave_options); 12921 if (!res) 12922 res = 't'; 12923 ast_config_destroy(msg_cfg); 12924 return res; 12925 } else { 12926 /* Sender has no mailbox, can't reply */ 12927 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 12928 ast_play_and_wait(chan, "vm-nobox"); 12929 res = 't'; 12930 ast_config_destroy(msg_cfg); 12931 return res; 12932 } 12933 } 12934 res = 0; 12935 12936 break; 12937 } 12938 12939 #ifndef IMAP_STORAGE 12940 ast_config_destroy(msg_cfg); 12941 12942 if (!res) { 12943 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 12944 vms->heard[msg] = 1; 12945 res = wait_file(chan, vms, vms->fn); 12946 } 12947 #endif 12948 return res; 12949 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10444 of file app_voicemail_odbcstorage.c.
References apply_options(), ast_copy_string(), ast_strdupa, ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), 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(), and strsep().
10445 { 10446 /* Assumes lock is already held */ 10447 char *tmp; 10448 char *stringp; 10449 char *s; 10450 struct ast_vm_user *vmu; 10451 char *mailbox_full; 10452 int new = 0, old = 0, urgent = 0; 10453 char secretfn[PATH_MAX] = ""; 10454 10455 tmp = ast_strdupa(data); 10456 10457 if (!(vmu = find_or_create(context, box))) 10458 return -1; 10459 10460 populate_defaults(vmu); 10461 10462 stringp = tmp; 10463 if ((s = strsep(&stringp, ","))) { 10464 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10465 } 10466 if (stringp && (s = strsep(&stringp, ","))) { 10467 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10468 } 10469 if (stringp && (s = strsep(&stringp, ","))) { 10470 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10471 } 10472 if (stringp && (s = strsep(&stringp, ","))) { 10473 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10474 } 10475 if (stringp && (s = strsep(&stringp, ","))) { 10476 apply_options(vmu, s); 10477 } 10478 10479 switch (vmu->passwordlocation) { 10480 case OPT_PWLOC_SPOOLDIR: 10481 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10482 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10483 } 10484 10485 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10486 strcpy(mailbox_full, box); 10487 strcat(mailbox_full, "@"); 10488 strcat(mailbox_full, context); 10489 10490 inboxcount2(mailbox_full, &urgent, &new, &old); 10491 queue_mwi_event(mailbox_full, urgent, new, old); 10492 10493 return 0; 10494 }
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 1009 of file app_voicemail_odbcstorage.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, 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, 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.
01010 { 01011 int x; 01012 if (!strcasecmp(var, "attach")) { 01013 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01014 } else if (!strcasecmp(var, "attachfmt")) { 01015 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01016 } else if (!strcasecmp(var, "serveremail")) { 01017 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01018 } else if (!strcasecmp(var, "language")) { 01019 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01020 } else if (!strcasecmp(var, "tz")) { 01021 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01022 } else if (!strcasecmp(var, "locale")) { 01023 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01024 #ifdef IMAP_STORAGE 01025 } else if (!strcasecmp(var, "imapuser")) { 01026 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01027 vmu->imapversion = imapversion; 01028 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01029 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01030 vmu->imapversion = imapversion; 01031 } else if (!strcasecmp(var, "imapfolder")) { 01032 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01033 } else if (!strcasecmp(var, "imapvmshareid")) { 01034 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01035 vmu->imapversion = imapversion; 01036 #endif 01037 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01038 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01039 } else if (!strcasecmp(var, "saycid")){ 01040 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01041 } else if (!strcasecmp(var, "sendvoicemail")){ 01042 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01043 } else if (!strcasecmp(var, "review")){ 01044 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01045 } else if (!strcasecmp(var, "tempgreetwarn")){ 01046 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01047 } else if (!strcasecmp(var, "messagewrap")){ 01048 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01049 } else if (!strcasecmp(var, "operator")) { 01050 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01051 } else if (!strcasecmp(var, "envelope")){ 01052 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01053 } else if (!strcasecmp(var, "moveheard")){ 01054 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01055 } else if (!strcasecmp(var, "sayduration")){ 01056 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01057 } else if (!strcasecmp(var, "saydurationm")){ 01058 if (sscanf(value, "%30d", &x) == 1) { 01059 vmu->saydurationm = x; 01060 } else { 01061 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01062 } 01063 } else if (!strcasecmp(var, "forcename")){ 01064 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01065 } else if (!strcasecmp(var, "forcegreetings")){ 01066 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01067 } else if (!strcasecmp(var, "callback")) { 01068 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01069 } else if (!strcasecmp(var, "dialout")) { 01070 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01071 } else if (!strcasecmp(var, "exitcontext")) { 01072 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01073 } else if (!strcasecmp(var, "minsecs")) { 01074 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01075 vmu->minsecs = x; 01076 } else { 01077 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01078 vmu->minsecs = vmminsecs; 01079 } 01080 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01081 vmu->maxsecs = atoi(value); 01082 if (vmu->maxsecs <= 0) { 01083 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01084 vmu->maxsecs = vmmaxsecs; 01085 } else { 01086 vmu->maxsecs = atoi(value); 01087 } 01088 if (!strcasecmp(var, "maxmessage")) 01089 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01090 } else if (!strcasecmp(var, "maxmsg")) { 01091 vmu->maxmsg = atoi(value); 01092 /* Accept maxmsg=0 (Greetings only voicemail) */ 01093 if (vmu->maxmsg < 0) { 01094 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01095 vmu->maxmsg = MAXMSG; 01096 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01097 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01098 vmu->maxmsg = MAXMSGLIMIT; 01099 } 01100 } else if (!strcasecmp(var, "nextaftercmd")) { 01101 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01102 } else if (!strcasecmp(var, "backupdeleted")) { 01103 if (sscanf(value, "%30d", &x) == 1) 01104 vmu->maxdeletedmsg = x; 01105 else if (ast_true(value)) 01106 vmu->maxdeletedmsg = MAXMSG; 01107 else 01108 vmu->maxdeletedmsg = 0; 01109 01110 if (vmu->maxdeletedmsg < 0) { 01111 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01112 vmu->maxdeletedmsg = MAXMSG; 01113 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01114 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01115 vmu->maxdeletedmsg = MAXMSGLIMIT; 01116 } 01117 } else if (!strcasecmp(var, "volgain")) { 01118 sscanf(value, "%30lf", &vmu->volgain); 01119 } else if (!strcasecmp(var, "passwordlocation")) { 01120 if (!strcasecmp(value, "spooldir")) { 01121 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01122 } else { 01123 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01124 } 01125 } else if (!strcasecmp(var, "options")) { 01126 apply_options(vmu, value); 01127 } 01128 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1242 of file app_voicemail_odbcstorage.c.
References apply_option(), ast_strdupa, strsep(), value, and var.
01243 { 01244 char *stringp; 01245 char *s; 01246 char *var, *value; 01247 stringp = ast_strdupa(options); 01248 while ((s = strsep(&stringp, "|"))) { 01249 value = s; 01250 if ((var = strsep(&value, "=")) && value) { 01251 apply_option(vmu, var, value); 01252 } 01253 } 01254 }
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 1261 of file app_voicemail_odbcstorage.c.
References ast_copy_string(), ast_strlen_zero(), ast_vm_user::password, and var.
01262 { 01263 for (; var; var = var->next) { 01264 if (!strcasecmp(var->name, "vmsecret")) { 01265 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01266 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01267 if (ast_strlen_zero(retval->password)) 01268 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01269 } else if (!strcasecmp(var->name, "uniqueid")) { 01270 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01271 } else if (!strcasecmp(var->name, "pager")) { 01272 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01273 } else if (!strcasecmp(var->name, "email")) { 01274 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01275 } else if (!strcasecmp(var->name, "fullname")) { 01276 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01277 } else if (!strcasecmp(var->name, "context")) { 01278 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01279 } else if (!strcasecmp(var->name, "emailsubject")) { 01280 retval->emailsubject = ast_strdup(var->value); 01281 } else if (!strcasecmp(var->name, "emailbody")) { 01282 retval->emailbody = ast_strdup(var->value); 01283 #ifdef IMAP_STORAGE 01284 } else if (!strcasecmp(var->name, "imapuser")) { 01285 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01286 retval->imapversion = imapversion; 01287 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01288 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01289 retval->imapversion = imapversion; 01290 } else if (!strcasecmp(var->name, "imapfolder")) { 01291 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01292 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01293 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01294 retval->imapversion = imapversion; 01295 #endif 01296 } else 01297 apply_option(retval, var->name, var->value); 01298 } 01299 }
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 4330 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.
04331 { 04332 struct ast_str *tmp = ast_str_alloca(80); 04333 int first_section = 1; 04334 04335 ast_str_reset(*end); 04336 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04337 for (; *start; start++) { 04338 int need_encoding = 0; 04339 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04340 need_encoding = 1; 04341 } 04342 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04343 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04344 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04345 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04346 /* Start new line */ 04347 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04348 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04349 first_section = 0; 04350 } 04351 if (need_encoding && *start == ' ') { 04352 ast_str_append(&tmp, -1, "_"); 04353 } else if (need_encoding) { 04354 ast_str_append(&tmp, -1, "=%hhX", *start); 04355 } else { 04356 ast_str_append(&tmp, -1, "%c", *start); 04357 } 04358 } 04359 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04360 return ast_str_buffer(*end); 04361 }
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 4258 of file app_voicemail_odbcstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04259 { 04260 const char *ptr; 04261 04262 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04263 ast_str_set(buf, maxlen, "\""); 04264 for (ptr = from; *ptr; ptr++) { 04265 if (*ptr == '"' || *ptr == '\\') { 04266 ast_str_append(buf, maxlen, "\\%c", *ptr); 04267 } else { 04268 ast_str_append(buf, maxlen, "%c", *ptr); 04269 } 04270 } 04271 ast_str_append(buf, maxlen, "\""); 04272 04273 return ast_str_buffer(*buf); 04274 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10496 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, 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.
10497 { 10498 int res = 0; 10499 struct ast_vm_user *vmu; 10500 /* language parameter seems to only be used for display in manager action */ 10501 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10502 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10503 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10504 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10505 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10506 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10507 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir"; 10508 #ifdef IMAP_STORAGE 10509 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10510 "imapfolder=INBOX|imapvmshareid=6000"; 10511 #endif 10512 10513 switch (cmd) { 10514 case TEST_INIT: 10515 info->name = "vmuser"; 10516 info->category = "/apps/app_voicemail/"; 10517 info->summary = "Vmuser unit test"; 10518 info->description = 10519 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10520 return AST_TEST_NOT_RUN; 10521 case TEST_EXECUTE: 10522 break; 10523 } 10524 10525 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10526 return AST_TEST_NOT_RUN; 10527 } 10528 ast_set_flag(vmu, VM_ALLOCED); 10529 10530 apply_options(vmu, options_string); 10531 10532 if (!ast_test_flag(vmu, VM_ATTACH)) { 10533 ast_test_status_update(test, "Parse failure for attach option\n"); 10534 res = 1; 10535 } 10536 if (strcasecmp(vmu->attachfmt, "wav49")) { 10537 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10538 res = 1; 10539 } 10540 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10541 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10542 res = 1; 10543 } 10544 if (strcasecmp(vmu->zonetag, "central")) { 10545 ast_test_status_update(test, "Parse failure for tz option\n"); 10546 res = 1; 10547 } 10548 if (!ast_test_flag(vmu, VM_DELETE)) { 10549 ast_test_status_update(test, "Parse failure for delete option\n"); 10550 res = 1; 10551 } 10552 if (!ast_test_flag(vmu, VM_SAYCID)) { 10553 ast_test_status_update(test, "Parse failure for saycid option\n"); 10554 res = 1; 10555 } 10556 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10557 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10558 res = 1; 10559 } 10560 if (!ast_test_flag(vmu, VM_REVIEW)) { 10561 ast_test_status_update(test, "Parse failure for review option\n"); 10562 res = 1; 10563 } 10564 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10565 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10566 res = 1; 10567 } 10568 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10569 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10570 res = 1; 10571 } 10572 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10573 ast_test_status_update(test, "Parse failure for operator option\n"); 10574 res = 1; 10575 } 10576 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10577 ast_test_status_update(test, "Parse failure for envelope option\n"); 10578 res = 1; 10579 } 10580 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10581 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10582 res = 1; 10583 } 10584 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10585 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10586 res = 1; 10587 } 10588 if (vmu->saydurationm != 5) { 10589 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10590 res = 1; 10591 } 10592 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10593 ast_test_status_update(test, "Parse failure for forcename option\n"); 10594 res = 1; 10595 } 10596 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10597 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10598 res = 1; 10599 } 10600 if (strcasecmp(vmu->callback, "somecontext")) { 10601 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10602 res = 1; 10603 } 10604 if (strcasecmp(vmu->dialout, "somecontext2")) { 10605 ast_test_status_update(test, "Parse failure for dialout option\n"); 10606 res = 1; 10607 } 10608 if (strcasecmp(vmu->exit, "somecontext3")) { 10609 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10610 res = 1; 10611 } 10612 if (vmu->minsecs != 10) { 10613 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10614 res = 1; 10615 } 10616 if (vmu->maxsecs != 100) { 10617 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10618 res = 1; 10619 } 10620 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10621 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10622 res = 1; 10623 } 10624 if (vmu->maxdeletedmsg != 50) { 10625 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10626 res = 1; 10627 } 10628 if (vmu->volgain != 1.3) { 10629 ast_test_status_update(test, "Parse failure for volgain option\n"); 10630 res = 1; 10631 } 10632 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10633 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10634 res = 1; 10635 } 10636 #ifdef IMAP_STORAGE 10637 apply_options(vmu, option_string2); 10638 10639 if (strcasecmp(vmu->imapuser, "imapuser")) { 10640 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10641 res = 1; 10642 } 10643 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10644 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10645 res = 1; 10646 } 10647 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10648 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10649 res = 1; 10650 } 10651 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10652 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10653 res = 1; 10654 } 10655 #endif 10656 10657 free_user(vmu); 10658 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10659 }
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 4134 of file app_voicemail_odbcstorage.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04135 { 04136 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04137 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04138 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04139 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04140 int i, hiteof = 0; 04141 FILE *fi; 04142 struct baseio bio; 04143 04144 memset(&bio, 0, sizeof(bio)); 04145 bio.iocp = BASEMAXINLINE; 04146 04147 if (!(fi = fopen(filename, "rb"))) { 04148 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04149 return -1; 04150 } 04151 04152 while (!hiteof){ 04153 unsigned char igroup[3], ogroup[4]; 04154 int c, n; 04155 04156 memset(igroup, 0, sizeof(igroup)); 04157 04158 for (n = 0; n < 3; n++) { 04159 if ((c = inchar(&bio, fi)) == EOF) { 04160 hiteof = 1; 04161 break; 04162 } 04163 04164 igroup[n] = (unsigned char) c; 04165 } 04166 04167 if (n > 0) { 04168 ogroup[0]= dtable[igroup[0] >> 2]; 04169 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04170 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04171 ogroup[3]= dtable[igroup[2] & 0x3F]; 04172 04173 if (n < 3) { 04174 ogroup[3] = '='; 04175 04176 if (n < 2) 04177 ogroup[2] = '='; 04178 } 04179 04180 for (i = 0; i < 4; i++) 04181 ochar(&bio, ogroup[i], so); 04182 } 04183 } 04184 04185 fclose(fi); 04186 04187 if (fputs(ENDL, so) == EOF) { 04188 return 0; 04189 } 04190 04191 return 1; 04192 }
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 1221 of file app_voicemail_odbcstorage.c.
References ast_copy_string(), ast_realtime_require_field(), ast_update2_realtime(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, RQ_CHAR, and SENTINEL.
01222 { 01223 int res = -1; 01224 if (!strcmp(vmu->password, password)) { 01225 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01226 return 0; 01227 } 01228 01229 if (strlen(password) > 10) { 01230 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01231 } 01232 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01233 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01234 res = 0; 01235 } 01236 return res; 01237 }
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 4303 of file app_voicemail_odbcstorage.c.
04304 { 04305 for (; *str; str++) { 04306 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04307 return 1; 04308 } 04309 } 04310 return 0; 04311 }
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 1183 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().
01184 { 01185 /* check minimum length */ 01186 if (strlen(password) < minpassword) 01187 return 1; 01188 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01189 char cmd[255], buf[255]; 01190 01191 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01192 01193 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01194 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01195 ast_debug(5, "Result: %s\n", buf); 01196 if (!strncasecmp(buf, "VALID", 5)) { 01197 ast_debug(3, "Passed password check: '%s'\n", buf); 01198 return 0; 01199 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01200 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01201 return 0; 01202 } else { 01203 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01204 return 1; 01205 } 01206 } 01207 } 01208 return 0; 01209 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7722 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_log(), 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, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
07723 { 07724 int x = 0; 07725 #ifndef IMAP_STORAGE 07726 int res = 0, nummsg; 07727 char fn2[PATH_MAX]; 07728 #endif 07729 07730 if (vms->lastmsg <= -1) { 07731 goto done; 07732 } 07733 07734 vms->curmsg = -1; 07735 #ifndef IMAP_STORAGE 07736 /* Get the deleted messages fixed */ 07737 if (vm_lock_path(vms->curdir)) { 07738 return ERROR_LOCK_PATH; 07739 } 07740 07741 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07742 for (x = 0; x < vms->lastmsg + 1; x++) { 07743 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07744 /* Save this message. It's not in INBOX or hasn't been heard */ 07745 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07746 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07747 break; 07748 } 07749 vms->curmsg++; 07750 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07751 if (strcmp(vms->fn, fn2)) { 07752 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07753 } 07754 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07755 /* Move to old folder before deleting */ 07756 res = save_to_folder(vmu, vms, x, 1); 07757 if (res == ERROR_LOCK_PATH) { 07758 /* If save failed do not delete the message */ 07759 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07760 vms->deleted[x] = 0; 07761 vms->heard[x] = 0; 07762 --x; 07763 } 07764 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07765 /* Move to deleted folder */ 07766 res = save_to_folder(vmu, vms, x, 10); 07767 if (res == ERROR_LOCK_PATH) { 07768 /* If save failed do not delete the message */ 07769 vms->deleted[x] = 0; 07770 vms->heard[x] = 0; 07771 --x; 07772 } 07773 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07774 /* If realtime storage enabled - we should explicitly delete this message, 07775 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07776 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07777 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07778 DELETE(vms->curdir, x, vms->fn, vmu); 07779 } 07780 } 07781 } 07782 07783 /* Delete ALL remaining messages */ 07784 nummsg = x - 1; 07785 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07786 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07787 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07788 DELETE(vms->curdir, x, vms->fn, vmu); 07789 } 07790 } 07791 ast_unlock_path(vms->curdir); 07792 #else /* defined(IMAP_STORAGE) */ 07793 if (vms->deleted) { 07794 /* Since we now expunge after each delete, deleting in reverse order 07795 * ensures that no reordering occurs between each step. */ 07796 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 07797 if (vms->deleted[x]) { 07798 ast_debug(3, "IMAP delete of %d\n", x); 07799 DELETE(vms->curdir, x, vms->fn, vmu); 07800 } 07801 } 07802 } 07803 #endif 07804 07805 done: 07806 if (vms->deleted && vmu->maxmsg) { 07807 memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 07808 } 07809 if (vms->heard && vmu->maxmsg) { 07810 memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 07811 } 07812 07813 return 0; 07814 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10805 of file app_voicemail_odbcstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.
10806 { 10807 int which = 0; 10808 int wordlen; 10809 struct ast_vm_user *vmu; 10810 const char *context = ""; 10811 10812 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 10813 if (pos > 4) 10814 return NULL; 10815 if (pos == 3) 10816 return (state == 0) ? ast_strdup("for") : NULL; 10817 wordlen = strlen(word); 10818 AST_LIST_TRAVERSE(&users, vmu, list) { 10819 if (!strncasecmp(word, vmu->context, wordlen)) { 10820 if (context && strcmp(context, vmu->context) && ++which > state) 10821 return ast_strdup(vmu->context); 10822 /* ignore repeated contexts ? */ 10823 context = vmu->context; 10824 } 10825 } 10826 return NULL; 10827 }
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 3938 of file app_voicemail_odbcstorage.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
03939 { 03940 int ifd; 03941 int ofd; 03942 int res; 03943 int len; 03944 char buf[4096]; 03945 03946 #ifdef HARDLINK_WHEN_POSSIBLE 03947 /* Hard link if possible; saves disk space & is faster */ 03948 if (link(infile, outfile)) { 03949 #endif 03950 if ((ifd = open(infile, O_RDONLY)) < 0) { 03951 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03952 return -1; 03953 } 03954 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03955 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03956 close(ifd); 03957 return -1; 03958 } 03959 do { 03960 len = read(ifd, buf, sizeof(buf)); 03961 if (len < 0) { 03962 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03963 close(ifd); 03964 close(ofd); 03965 unlink(outfile); 03966 } 03967 if (len) { 03968 res = write(ofd, buf, len); 03969 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03970 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03971 close(ifd); 03972 close(ofd); 03973 unlink(outfile); 03974 } 03975 } 03976 } while (len); 03977 close(ifd); 03978 close(ofd); 03979 return 0; 03980 #ifdef HARDLINK_WHEN_POSSIBLE 03981 } else { 03982 /* Hard link succeeded */ 03983 return 0; 03984 } 03985 #endif 03986 }
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 5174 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(), 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().
05175 { 05176 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05177 const char *frombox = mbox(vmu, imbox); 05178 int recipmsgnum; 05179 int res = 0; 05180 05181 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05182 05183 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05184 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 05185 } else { 05186 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 05187 } 05188 05189 if (!dir) 05190 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05191 else 05192 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05193 05194 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05195 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 05196 05197 if (vm_lock_path(todir)) 05198 return ERROR_LOCK_PATH; 05199 05200 recipmsgnum = last_message_index(recip, todir) + 1; 05201 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05202 make_file(topath, sizeof(topath), todir, recipmsgnum); 05203 #ifndef ODBC_STORAGE 05204 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05205 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05206 } else { 05207 #endif 05208 /* If we are prepending a message for ODBC, then the message already 05209 * exists in the database, but we want to force copying from the 05210 * filesystem (since only the FS contains the prepend). */ 05211 copy_plain_file(frompath, topath); 05212 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05213 vm_delete(topath); 05214 #ifndef ODBC_STORAGE 05215 } 05216 #endif 05217 } else { 05218 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05219 res = -1; 05220 } 05221 ast_unlock_path(todir); 05222 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05223 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05224 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05225 flag); 05226 05227 return res; 05228 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 3997 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.
03998 { 03999 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04000 struct ast_variable *tmp,*var = NULL; 04001 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04002 ast_filecopy(frompath, topath, NULL); 04003 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04004 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04005 if (ast_check_realtime("voicemail_data")) { 04006 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04007 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04008 for (tmp = var; tmp; tmp = tmp->next) { 04009 if (!strcasecmp(tmp->name, "origmailbox")) { 04010 origmailbox = tmp->value; 04011 } else if (!strcasecmp(tmp->name, "context")) { 04012 context = tmp->value; 04013 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04014 macrocontext = tmp->value; 04015 } else if (!strcasecmp(tmp->name, "exten")) { 04016 exten = tmp->value; 04017 } else if (!strcasecmp(tmp->name, "priority")) { 04018 priority = tmp->value; 04019 } else if (!strcasecmp(tmp->name, "callerchan")) { 04020 callerchan = tmp->value; 04021 } else if (!strcasecmp(tmp->name, "callerid")) { 04022 callerid = tmp->value; 04023 } else if (!strcasecmp(tmp->name, "origdate")) { 04024 origdate = tmp->value; 04025 } else if (!strcasecmp(tmp->name, "origtime")) { 04026 origtime = tmp->value; 04027 } else if (!strcasecmp(tmp->name, "category")) { 04028 category = tmp->value; 04029 } else if (!strcasecmp(tmp->name, "duration")) { 04030 duration = tmp->value; 04031 } 04032 } 04033 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); 04034 } 04035 copy(frompath2, topath2); 04036 ast_variables_destroy(var); 04037 }
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 3841 of file app_voicemail_odbcstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
03842 { 03843 03844 int vmcount = 0; 03845 DIR *vmdir = NULL; 03846 struct dirent *vment = NULL; 03847 03848 if (vm_lock_path(dir)) 03849 return ERROR_LOCK_PATH; 03850 03851 if ((vmdir = opendir(dir))) { 03852 while ((vment = readdir(vmdir))) { 03853 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03854 vmcount++; 03855 } 03856 } 03857 closedir(vmdir); 03858 } 03859 ast_unlock_path(dir); 03860 03861 return vmcount; 03862 }
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 1609 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01610 { 01611 mode_t mode = VOICEMAIL_DIR_MODE; 01612 int res; 01613 01614 make_dir(dest, len, context, ext, folder); 01615 if ((res = ast_mkdir(dest, mode))) { 01616 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01617 return -1; 01618 } 01619 return 0; 01620 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 12691 of file app_voicemail_odbcstorage.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verb, ast_verbose, ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.
12692 { 12693 int cmd = 0; 12694 char destination[80] = ""; 12695 int retries = 0; 12696 12697 if (!num) { 12698 ast_verb(3, "Destination number will be entered manually\n"); 12699 while (retries < 3 && cmd != 't') { 12700 destination[1] = '\0'; 12701 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 12702 if (!cmd) 12703 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 12704 if (!cmd) 12705 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 12706 if (!cmd) { 12707 cmd = ast_waitfordigit(chan, 6000); 12708 if (cmd) 12709 destination[0] = cmd; 12710 } 12711 if (!cmd) { 12712 retries++; 12713 } else { 12714 12715 if (cmd < 0) 12716 return 0; 12717 if (cmd == '*') { 12718 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 12719 return 0; 12720 } 12721 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 12722 retries++; 12723 else 12724 cmd = 't'; 12725 } 12726 } 12727 if (retries >= 3) { 12728 return 0; 12729 } 12730 12731 } else { 12732 if (option_verbose > 2) 12733 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 12734 ast_copy_string(destination, num, sizeof(destination)); 12735 } 12736 12737 if (!ast_strlen_zero(destination)) { 12738 if (destination[strlen(destination) -1 ] == '*') 12739 return 0; 12740 if (option_verbose > 2) 12741 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 12742 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 12743 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 12744 chan->priority = 0; 12745 return 9; 12746 } 12747 return 0; 12748 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10412 of file app_voicemail_odbcstorage.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::list, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
10413 { 10414 struct ast_vm_user *vmu; 10415 10416 AST_LIST_TRAVERSE(&users, vmu, list) { 10417 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10418 if (strcasecmp(vmu->context, context)) { 10419 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10420 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10421 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10422 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10423 } 10424 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10425 return NULL; 10426 } 10427 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10428 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10429 return NULL; 10430 } 10431 } 10432 10433 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10434 return NULL; 10435 10436 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10437 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10438 10439 AST_LIST_INSERT_TAIL(&users, vmu, list); 10440 10441 return vmu; 10442 }
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 1370 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_test_flag, find_user_realtime(), globalflags, ast_vm_user::list, VM_ALLOCED, and VM_SEARCH.
01371 { 01372 /* This function could be made to generate one from a database, too */ 01373 struct ast_vm_user *vmu = NULL, *cur; 01374 AST_LIST_LOCK(&users); 01375 01376 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01377 context = "default"; 01378 01379 AST_LIST_TRAVERSE(&users, cur, list) { 01380 #ifdef IMAP_STORAGE 01381 if (cur->imapversion != imapversion) { 01382 continue; 01383 } 01384 #endif 01385 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01386 break; 01387 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01388 break; 01389 } 01390 if (cur) { 01391 /* Make a copy, so that on a reload, we have no race */ 01392 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01393 memcpy(vmu, cur, sizeof(*vmu)); 01394 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01395 AST_LIST_NEXT(vmu, list) = NULL; 01396 } 01397 } else 01398 vmu = find_user_realtime(ivm, context, mailbox); 01399 AST_LIST_UNLOCK(&users); 01400 return vmu; 01401 }
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 1333 of file app_voicemail_odbcstorage.c.
References apply_options_full(), ast_calloc, ast_copy_string(), ast_free, ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), globalflags, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
01334 { 01335 struct ast_variable *var; 01336 struct ast_vm_user *retval; 01337 01338 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01339 if (!ivm) 01340 ast_set_flag(retval, VM_ALLOCED); 01341 else 01342 memset(retval, 0, sizeof(*retval)); 01343 if (mailbox) 01344 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01345 populate_defaults(retval); 01346 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01347 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01348 else 01349 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01350 if (var) { 01351 apply_options_full(retval, var); 01352 ast_variables_destroy(var); 01353 } else { 01354 if (!ivm) 01355 ast_free(retval); 01356 retval = NULL; 01357 } 01358 } 01359 return retval; 01360 }
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 6939 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_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(), 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(), and VM_FWDURGAUTO.
06940 { 06941 #ifdef IMAP_STORAGE 06942 int todircount = 0; 06943 struct vm_state *dstvms; 06944 #endif 06945 char username[70]=""; 06946 char fn[PATH_MAX]; /* for playback of name greeting */ 06947 char ecodes[16] = "#"; 06948 int res = 0, cmd = 0; 06949 struct ast_vm_user *receiver = NULL, *vmtmp; 06950 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 06951 char *stringp; 06952 const char *s; 06953 int saved_messages = 0; 06954 int valid_extensions = 0; 06955 char *dir; 06956 int curmsg; 06957 char urgent_str[7] = ""; 06958 char tmptxtfile[PATH_MAX]; 06959 int prompt_played = 0; 06960 #ifndef IMAP_STORAGE 06961 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06962 #endif 06963 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 06964 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 06965 } 06966 06967 if (vms == NULL) return -1; 06968 dir = vms->curdir; 06969 curmsg = vms->curmsg; 06970 06971 tmptxtfile[0] = '\0'; 06972 while (!res && !valid_extensions) { 06973 int use_directory = 0; 06974 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 06975 int done = 0; 06976 int retries = 0; 06977 cmd = 0; 06978 while ((cmd >= 0) && !done ){ 06979 if (cmd) 06980 retries = 0; 06981 switch (cmd) { 06982 case '1': 06983 use_directory = 0; 06984 done = 1; 06985 break; 06986 case '2': 06987 use_directory = 1; 06988 done = 1; 06989 break; 06990 case '*': 06991 cmd = 't'; 06992 done = 1; 06993 break; 06994 default: 06995 /* Press 1 to enter an extension press 2 to use the directory */ 06996 cmd = ast_play_and_wait(chan, "vm-forward"); 06997 if (!cmd) 06998 cmd = ast_waitfordigit(chan, 3000); 06999 if (!cmd) 07000 retries++; 07001 if (retries > 3) { 07002 cmd = 't'; 07003 done = 1; 07004 } 07005 07006 } 07007 } 07008 if (cmd < 0 || cmd == 't') 07009 break; 07010 } 07011 07012 if (use_directory) { 07013 /* use app_directory */ 07014 07015 char old_context[sizeof(chan->context)]; 07016 char old_exten[sizeof(chan->exten)]; 07017 int old_priority; 07018 struct ast_app* directory_app; 07019 07020 directory_app = pbx_findapp("Directory"); 07021 if (directory_app) { 07022 char vmcontext[256]; 07023 /* make backup copies */ 07024 memcpy(old_context, chan->context, sizeof(chan->context)); 07025 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07026 old_priority = chan->priority; 07027 07028 /* call the the Directory, changes the channel */ 07029 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07030 res = pbx_exec(chan, directory_app, vmcontext); 07031 07032 ast_copy_string(username, chan->exten, sizeof(username)); 07033 07034 /* restore the old context, exten, and priority */ 07035 memcpy(chan->context, old_context, sizeof(chan->context)); 07036 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07037 chan->priority = old_priority; 07038 } else { 07039 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07040 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07041 } 07042 } else { 07043 /* Ask for an extension */ 07044 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07045 prompt_played++; 07046 if (res || prompt_played > 4) 07047 break; 07048 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07049 break; 07050 } 07051 07052 /* start all over if no username */ 07053 if (ast_strlen_zero(username)) 07054 continue; 07055 stringp = username; 07056 s = strsep(&stringp, "*"); 07057 /* start optimistic */ 07058 valid_extensions = 1; 07059 while (s) { 07060 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07061 int oldmsgs; 07062 int newmsgs; 07063 int capacity; 07064 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07065 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07066 /* Shouldn't happen, but allow trying another extension if it does */ 07067 res = ast_play_and_wait(chan, "pbx-invalid"); 07068 valid_extensions = 0; 07069 break; 07070 } 07071 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07072 if ((newmsgs + oldmsgs) >= capacity) { 07073 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07074 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07075 valid_extensions = 0; 07076 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07077 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07078 free_user(vmtmp); 07079 } 07080 inprocess_count(receiver->mailbox, receiver->context, -1); 07081 break; 07082 } 07083 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07084 } else { 07085 /* XXX Optimization for the future. When we encounter a single bad extension, 07086 * bailing out on all of the extensions may not be the way to go. We should 07087 * probably just bail on that single extension, then allow the user to enter 07088 * several more. XXX 07089 */ 07090 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07091 free_user(receiver); 07092 } 07093 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07094 /* "I am sorry, that's not a valid extension. Please try again." */ 07095 res = ast_play_and_wait(chan, "pbx-invalid"); 07096 valid_extensions = 0; 07097 break; 07098 } 07099 07100 /* play name if available, else play extension number */ 07101 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07102 RETRIEVE(fn, -1, s, receiver->context); 07103 if (ast_fileexists(fn, NULL, NULL) > 0) { 07104 res = ast_stream_and_wait(chan, fn, ecodes); 07105 if (res) { 07106 DISPOSE(fn, -1); 07107 return res; 07108 } 07109 } else { 07110 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07111 } 07112 DISPOSE(fn, -1); 07113 07114 s = strsep(&stringp, "*"); 07115 } 07116 /* break from the loop of reading the extensions */ 07117 if (valid_extensions) 07118 break; 07119 } 07120 /* check if we're clear to proceed */ 07121 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07122 return res; 07123 if (is_new_message == 1) { 07124 struct leave_vm_options leave_options; 07125 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07126 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07127 07128 /* Send VoiceMail */ 07129 memset(&leave_options, 0, sizeof(leave_options)); 07130 leave_options.record_gain = record_gain; 07131 cmd = leave_voicemail(chan, mailbox, &leave_options); 07132 } else { 07133 /* Forward VoiceMail */ 07134 long duration = 0; 07135 struct vm_state vmstmp; 07136 int copy_msg_result = 0; 07137 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07138 07139 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07140 07141 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07142 if (!cmd) { 07143 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07144 #ifdef IMAP_STORAGE 07145 int attach_user_voicemail; 07146 char *myserveremail = serveremail; 07147 07148 /* get destination mailbox */ 07149 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07150 if (!dstvms) { 07151 dstvms = create_vm_state_from_user(vmtmp); 07152 } 07153 if (dstvms) { 07154 init_mailstream(dstvms, 0); 07155 if (!dstvms->mailstream) { 07156 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07157 } else { 07158 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07159 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07160 } 07161 } else { 07162 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07163 } 07164 if (!ast_strlen_zero(vmtmp->serveremail)) 07165 myserveremail = vmtmp->serveremail; 07166 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07167 /* NULL category for IMAP storage */ 07168 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07169 dstvms->curbox, 07170 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07171 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07172 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07173 NULL, urgent_str); 07174 #else 07175 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07176 #endif 07177 saved_messages++; 07178 AST_LIST_REMOVE_CURRENT(list); 07179 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07180 free_user(vmtmp); 07181 if (res) 07182 break; 07183 } 07184 AST_LIST_TRAVERSE_SAFE_END; 07185 if (saved_messages > 0 && !copy_msg_result) { 07186 /* give confirmation that the message was saved */ 07187 /* commented out since we can't forward batches yet 07188 if (saved_messages == 1) 07189 res = ast_play_and_wait(chan, "vm-message"); 07190 else 07191 res = ast_play_and_wait(chan, "vm-messages"); 07192 if (!res) 07193 res = ast_play_and_wait(chan, "vm-saved"); */ 07194 #ifdef IMAP_STORAGE 07195 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07196 if (ast_strlen_zero(vmstmp.introfn)) 07197 #endif 07198 res = ast_play_and_wait(chan, "vm-msgsaved"); 07199 } 07200 #ifndef IMAP_STORAGE 07201 else { 07202 /* with IMAP, mailbox full warning played by imap_check_limits */ 07203 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07204 } 07205 /* Restore original message without prepended message if backup exists */ 07206 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07207 strcpy(textfile, msgfile); 07208 strcpy(backup, msgfile); 07209 strcpy(backup_textfile, msgfile); 07210 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07211 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07212 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07213 if (ast_fileexists(backup, NULL, NULL) > 0) { 07214 ast_filerename(backup, msgfile, NULL); 07215 rename(backup_textfile, textfile); 07216 } 07217 #endif 07218 } 07219 DISPOSE(dir, curmsg); 07220 #ifndef IMAP_STORAGE 07221 if (cmd) { /* assuming hangup, cleanup backup file */ 07222 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07223 strcpy(textfile, msgfile); 07224 strcpy(backup_textfile, msgfile); 07225 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07226 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07227 rename(backup_textfile, textfile); 07228 } 07229 #endif 07230 } 07231 07232 /* If anything failed above, we still have this list to free */ 07233 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07234 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07235 free_user(vmtmp); 07236 } 07237 return res ? res : cmd; 07238 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1664 of file app_voicemail_odbcstorage.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01665 { 01666 if (ast_test_flag(vmu, VM_ALLOCED)) { 01667 if (vmu->emailbody != NULL) { 01668 ast_free(vmu->emailbody); 01669 vmu->emailbody = NULL; 01670 } 01671 if (vmu->emailsubject != NULL) { 01672 ast_free(vmu->emailsubject); 01673 vmu->emailsubject = NULL; 01674 } 01675 ast_free(vmu); 01676 } 01677 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11404 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.
11405 { 11406 struct ast_vm_user *current; 11407 AST_LIST_LOCK(&users); 11408 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11409 ast_set_flag(current, VM_ALLOCED); 11410 free_user(current); 11411 } 11412 AST_LIST_UNLOCK(&users); 11413 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11416 of file app_voicemail_odbcstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and vm_zone::list.
11417 { 11418 struct vm_zone *zcur; 11419 AST_LIST_LOCK(&zones); 11420 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11421 free_zone(zcur); 11422 AST_LIST_UNLOCK(&zones); 11423 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4941 of file app_voicemail_odbcstorage.c.
References ast_free.
04942 { 04943 ast_free(z); 04944 }
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 4897 of file app_voicemail_odbcstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
04898 { 04899 struct ast_tm tm; 04900 struct timeval t = ast_tvnow(); 04901 04902 ast_localtime(&t, &tm, "UTC"); 04903 04904 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04905 }
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 6580 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().
06581 { 06582 int x; 06583 int d; 06584 char fn[PATH_MAX]; 06585 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06586 if (d) 06587 return d; 06588 for (x = start; x < 5; x++) { /* For all folders */ 06589 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06590 return d; 06591 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06592 if (d) 06593 return d; 06594 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06595 d = vm_play_folder_name(chan, fn); 06596 if (d) 06597 return d; 06598 d = ast_waitfordigit(chan, 500); 06599 if (d) 06600 return d; 06601 } 06602 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06603 if (d) 06604 return d; 06605 d = ast_waitfordigit(chan, 4000); 06606 return d; 06607 }
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 6621 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), and get_folder().
06622 { 06623 int res = 0; 06624 int loops = 0; 06625 res = ast_play_and_wait(chan, fn); /* Folder name */ 06626 while (((res < '0') || (res > '9')) && 06627 (res != '#') && (res >= 0) && 06628 loops < 4) { 06629 res = get_folder(chan, 0); 06630 loops++; 06631 } 06632 if (loops == 4) { /* give up */ 06633 return '#'; 06634 } 06635 return res; 06636 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1651 of file app_voicemail_odbcstorage.c.
References ARRAY_LEN.
01652 { 01653 size_t i; 01654 01655 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01656 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01657 return i; 01658 } 01659 } 01660 01661 return -1; 01662 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11187 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.
11188 { 11189 unsigned int len; 11190 struct mwi_sub *mwi_sub; 11191 struct mwi_sub_task *p = datap; 11192 11193 len = sizeof(*mwi_sub); 11194 if (!ast_strlen_zero(p->mailbox)) 11195 len += strlen(p->mailbox); 11196 11197 if (!ast_strlen_zero(p->context)) 11198 len += strlen(p->context) + 1; /* Allow for seperator */ 11199 11200 if (!(mwi_sub = ast_calloc(1, len))) 11201 return -1; 11202 11203 mwi_sub->uniqueid = p->uniqueid; 11204 if (!ast_strlen_zero(p->mailbox)) 11205 strcpy(mwi_sub->mailbox, p->mailbox); 11206 11207 if (!ast_strlen_zero(p->context)) { 11208 strcat(mwi_sub->mailbox, "@"); 11209 strcat(mwi_sub->mailbox, p->context); 11210 } 11211 11212 AST_RWLIST_WRLOCK(&mwi_subs); 11213 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11214 AST_RWLIST_UNLOCK(&mwi_subs); 11215 ast_free((void *) p->mailbox); 11216 ast_free((void *) p->context); 11217 ast_free(p); 11218 poll_subscribed_mailbox(mwi_sub); 11219 return 0; 11220 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11165 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.
11166 { 11167 struct mwi_sub *mwi_sub; 11168 uint32_t *uniqueid = datap; 11169 11170 AST_RWLIST_WRLOCK(&mwi_subs); 11171 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11172 if (mwi_sub->uniqueid == *uniqueid) { 11173 AST_LIST_REMOVE_CURRENT(entry); 11174 break; 11175 } 11176 } 11177 AST_RWLIST_TRAVERSE_SAFE_END 11178 AST_RWLIST_UNLOCK(&mwi_subs); 11179 11180 if (mwi_sub) 11181 mwi_sub_destroy(mwi_sub); 11182 11183 ast_free(uniqueid); 11184 return 0; 11185 }
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 10940 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.
10941 { 10942 switch (cmd) { 10943 case CLI_INIT: 10944 e->command = "voicemail reload"; 10945 e->usage = 10946 "Usage: voicemail reload\n" 10947 " Reload voicemail configuration\n"; 10948 return NULL; 10949 case CLI_GENERATE: 10950 return NULL; 10951 } 10952 10953 if (a->argc != 2) 10954 return CLI_SHOWUSAGE; 10955 10956 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 10957 load_config(1); 10958 10959 return CLI_SUCCESS; 10960 }
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 10830 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.
10831 { 10832 struct ast_vm_user *vmu; 10833 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 10834 const char *context = NULL; 10835 int users_counter = 0; 10836 10837 switch (cmd) { 10838 case CLI_INIT: 10839 e->command = "voicemail show users"; 10840 e->usage = 10841 "Usage: voicemail show users [for <context>]\n" 10842 " Lists all mailboxes currently set up\n"; 10843 return NULL; 10844 case CLI_GENERATE: 10845 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 10846 } 10847 10848 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 10849 return CLI_SHOWUSAGE; 10850 if (a->argc == 5) { 10851 if (strcmp(a->argv[3],"for")) 10852 return CLI_SHOWUSAGE; 10853 context = a->argv[4]; 10854 } 10855 10856 if (ast_check_realtime("voicemail")) { 10857 if (!context) { 10858 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 10859 return CLI_SHOWUSAGE; 10860 } 10861 return show_users_realtime(a->fd, context); 10862 } 10863 10864 AST_LIST_LOCK(&users); 10865 if (AST_LIST_EMPTY(&users)) { 10866 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 10867 AST_LIST_UNLOCK(&users); 10868 return CLI_FAILURE; 10869 } 10870 if (a->argc == 3) 10871 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10872 else { 10873 int count = 0; 10874 AST_LIST_TRAVERSE(&users, vmu, list) { 10875 if (!strcmp(context, vmu->context)) 10876 count++; 10877 } 10878 if (count) { 10879 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10880 } else { 10881 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 10882 AST_LIST_UNLOCK(&users); 10883 return CLI_FAILURE; 10884 } 10885 } 10886 AST_LIST_TRAVERSE(&users, vmu, list) { 10887 int newmsgs = 0, oldmsgs = 0; 10888 char count[12], tmp[256] = ""; 10889 10890 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 10891 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 10892 inboxcount(tmp, &newmsgs, &oldmsgs); 10893 snprintf(count, sizeof(count), "%d", newmsgs); 10894 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 10895 users_counter++; 10896 } 10897 } 10898 AST_LIST_UNLOCK(&users); 10899 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 10900 return CLI_SUCCESS; 10901 }
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 10904 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.
10905 { 10906 struct vm_zone *zone; 10907 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 10908 char *res = CLI_SUCCESS; 10909 10910 switch (cmd) { 10911 case CLI_INIT: 10912 e->command = "voicemail show zones"; 10913 e->usage = 10914 "Usage: voicemail show zones\n" 10915 " Lists zone message formats\n"; 10916 return NULL; 10917 case CLI_GENERATE: 10918 return NULL; 10919 } 10920 10921 if (a->argc != 3) 10922 return CLI_SHOWUSAGE; 10923 10924 AST_LIST_LOCK(&zones); 10925 if (!AST_LIST_EMPTY(&zones)) { 10926 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 10927 AST_LIST_TRAVERSE(&zones, zone, list) { 10928 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 10929 } 10930 } else { 10931 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 10932 res = CLI_FAILURE; 10933 } 10934 AST_LIST_UNLOCK(&zones); 10935 10936 return res; 10937 }
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 5283 of file app_voicemail_odbcstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
05284 { 05285 char tmp[256], *tmp2 = tmp, *box, *context; 05286 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05287 if (ast_strlen_zero(folder)) { 05288 folder = "INBOX"; 05289 } 05290 while ((box = strsep(&tmp2, ",&"))) { 05291 if ((context = strchr(box, '@'))) 05292 *context++ = '\0'; 05293 else 05294 context = "default"; 05295 if (__has_voicemail(context, box, folder, 1)) 05296 return 1; 05297 /* If we are checking INBOX, we should check Urgent as well */ 05298 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05299 return 1; 05300 } 05301 } 05302 return 0; 05303 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5365 of file app_voicemail_odbcstorage.c.
References inboxcount2().
05366 { 05367 int urgentmsgs = 0; 05368 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05369 if (newmsgs) { 05370 *newmsgs += urgentmsgs; 05371 } 05372 return res; 05373 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5306 of file app_voicemail_odbcstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), inboxcount2(), and strsep().
05307 { 05308 char tmp[256]; 05309 char *context; 05310 05311 /* If no mailbox, return immediately */ 05312 if (ast_strlen_zero(mailbox)) 05313 return 0; 05314 05315 if (newmsgs) 05316 *newmsgs = 0; 05317 if (oldmsgs) 05318 *oldmsgs = 0; 05319 if (urgentmsgs) 05320 *urgentmsgs = 0; 05321 05322 if (strchr(mailbox, ',')) { 05323 int tmpnew, tmpold, tmpurgent; 05324 char *mb, *cur; 05325 05326 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05327 mb = tmp; 05328 while ((cur = strsep(&mb, ", "))) { 05329 if (!ast_strlen_zero(cur)) { 05330 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05331 return -1; 05332 else { 05333 if (newmsgs) 05334 *newmsgs += tmpnew; 05335 if (oldmsgs) 05336 *oldmsgs += tmpold; 05337 if (urgentmsgs) 05338 *urgentmsgs += tmpurgent; 05339 } 05340 } 05341 } 05342 return 0; 05343 } 05344 05345 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05346 05347 if ((context = strchr(tmp, '@'))) 05348 *context++ = '\0'; 05349 else 05350 context = "default"; 05351 05352 if (newmsgs) 05353 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05354 if (oldmsgs) 05355 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05356 if (urgentmsgs) 05357 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05358 05359 return 0; 05360 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4069 of file app_voicemail_odbcstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
04070 { 04071 int l; 04072 04073 if (bio->ateof) 04074 return 0; 04075 04076 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04077 if (ferror(fi)) 04078 return -1; 04079 04080 bio->ateof = 1; 04081 return 0; 04082 } 04083 04084 bio->iolen = l; 04085 bio->iocp = 0; 04086 04087 return 1; 04088 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4093 of file app_voicemail_odbcstorage.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
04094 { 04095 if (bio->iocp>=bio->iolen) { 04096 if (!inbuf(bio, fi)) 04097 return EOF; 04098 } 04099 04100 return bio->iobuf[bio->iocp++]; 04101 }
static int inprocess_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 891 of file app_voicemail_odbcstorage.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
00892 { 00893 struct inprocess *i = obj, *j = arg; 00894 if (strcmp(i->mailbox, j->mailbox)) { 00895 return 0; 00896 } 00897 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 00898 }
static int inprocess_count | ( | const char * | context, | |
const char * | mailbox, | |||
int | delta | |||
) | [static] |
Definition at line 900 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.
00901 { 00902 struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00903 arg->context = arg->mailbox + strlen(mailbox) + 1; 00904 strcpy(arg->mailbox, mailbox); /* SAFE */ 00905 strcpy(arg->context, context); /* SAFE */ 00906 ao2_lock(inprocess_container); 00907 if ((i = ao2_find(inprocess_container, arg, 0))) { 00908 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00909 ao2_unlock(inprocess_container); 00910 ao2_ref(i, -1); 00911 return ret; 00912 } 00913 if (delta < 0) { 00914 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00915 } 00916 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00917 ao2_unlock(inprocess_container); 00918 return 0; 00919 } 00920 i->context = i->mailbox + strlen(mailbox) + 1; 00921 strcpy(i->mailbox, mailbox); /* SAFE */ 00922 strcpy(i->context, context); /* SAFE */ 00923 i->count = delta; 00924 ao2_link(inprocess_container, i); 00925 ao2_unlock(inprocess_container); 00926 ao2_ref(i, -1); 00927 return 0; 00928 }
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 4907 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, and RETRIEVE.
04908 { 04909 int res; 04910 char fn[PATH_MAX]; 04911 char dest[PATH_MAX]; 04912 04913 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04914 04915 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04916 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04917 return -1; 04918 } 04919 04920 RETRIEVE(fn, -1, ext, context); 04921 if (ast_fileexists(fn, NULL, NULL) > 0) { 04922 res = ast_stream_and_wait(chan, fn, ecodes); 04923 if (res) { 04924 DISPOSE(fn, -1); 04925 return res; 04926 } 04927 } else { 04928 /* Dispose just in case */ 04929 DISPOSE(fn, -1); 04930 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04931 if (res) 04932 return res; 04933 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04934 if (res) 04935 return res; 04936 } 04937 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04938 return res; 04939 }
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 1308 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
01309 { 01310 int i; 01311 char *local_key = ast_strdupa(key); 01312 01313 for (i = 0; i < strlen(key); ++i) { 01314 if (!strchr(VALID_DTMF, *local_key)) { 01315 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01316 return 0; 01317 } 01318 local_key++; 01319 } 01320 return 1; 01321 }
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 3895 of file app_voicemail_odbcstorage.c.
References map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
03896 { 03897 int x; 03898 unsigned char map[MAXMSGLIMIT] = ""; 03899 DIR *msgdir; 03900 struct dirent *msgdirent; 03901 int msgdirint; 03902 03903 /* Reading the entire directory into a file map scales better than 03904 * doing a stat repeatedly on a predicted sequence. I suspect this 03905 * is partially due to stat(2) internally doing a readdir(2) itself to 03906 * find each file. */ 03907 if (!(msgdir = opendir(dir))) { 03908 return -1; 03909 } 03910 03911 while ((msgdirent = readdir(msgdir))) { 03912 if (sscanf(msgdirent->d_name, "msg%30d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) 03913 map[msgdirint] = 1; 03914 } 03915 closedir(msgdir); 03916 03917 for (x = 0; x < vmu->maxmsg; x++) { 03918 if (map[x] == 0) 03919 break; 03920 } 03921 03922 return x - 1; 03923 }
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 5438 of file app_voicemail_odbcstorage.c.
References ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_exists_extension(), ast_fileexists(), ast_free, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::caller, ast_channel::context, ast_vm_user::context, create_dirpath(), DISPOSE, errno, ast_vm_user::exit, find_user(), ast_party_caller::id, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, ast_party_id::number, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), RETRIEVE, S_COR, ast_party_number::str, ast_party_number::valid, VM_OPERATOR, and VOICEMAIL_DIR_MODE.
05439 { 05440 #ifdef IMAP_STORAGE 05441 int newmsgs, oldmsgs; 05442 #else 05443 char urgdir[PATH_MAX]; 05444 #endif 05445 char txtfile[PATH_MAX]; 05446 char tmptxtfile[PATH_MAX]; 05447 struct vm_state *vms = NULL; 05448 char callerid[256]; 05449 FILE *txt; 05450 char date[256]; 05451 int txtdes; 05452 int res = 0; 05453 int msgnum; 05454 int duration = 0; 05455 int ausemacro = 0; 05456 int ousemacro = 0; 05457 int ouseexten = 0; 05458 char tmpdur[16]; 05459 char priority[16]; 05460 char origtime[16]; 05461 char dir[PATH_MAX]; 05462 char tmpdir[PATH_MAX]; 05463 char fn[PATH_MAX]; 05464 char prefile[PATH_MAX] = ""; 05465 char tempfile[PATH_MAX] = ""; 05466 char ext_context[256] = ""; 05467 char fmt[80]; 05468 char *context; 05469 char ecodes[17] = "#"; 05470 struct ast_str *tmp = ast_str_create(16); 05471 char *tmpptr; 05472 struct ast_vm_user *vmu; 05473 struct ast_vm_user svm; 05474 const char *category = NULL; 05475 const char *code; 05476 const char *alldtmf = "0123456789ABCD*#"; 05477 char flag[80]; 05478 05479 if (!tmp) { 05480 return -1; 05481 } 05482 05483 ast_str_set(&tmp, 0, "%s", ext); 05484 ext = ast_str_buffer(tmp); 05485 if ((context = strchr(ext, '@'))) { 05486 *context++ = '\0'; 05487 tmpptr = strchr(context, '&'); 05488 } else { 05489 tmpptr = strchr(ext, '&'); 05490 } 05491 05492 if (tmpptr) 05493 *tmpptr++ = '\0'; 05494 05495 ast_channel_lock(chan); 05496 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05497 category = ast_strdupa(category); 05498 } 05499 ast_channel_unlock(chan); 05500 05501 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05502 ast_copy_string(flag, "Urgent", sizeof(flag)); 05503 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05504 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05505 } else { 05506 flag[0] = '\0'; 05507 } 05508 05509 ast_debug(3, "Before find_user\n"); 05510 if (!(vmu = find_user(&svm, context, ext))) { 05511 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05512 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05513 ast_free(tmp); 05514 return res; 05515 } 05516 /* Setup pre-file if appropriate */ 05517 if (strcmp(vmu->context, "default")) 05518 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05519 else 05520 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05521 05522 /* Set the path to the prefile. Will be one of 05523 VM_SPOOL_DIRcontext/ext/busy 05524 VM_SPOOL_DIRcontext/ext/unavail 05525 Depending on the flag set in options. 05526 */ 05527 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05528 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05529 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05530 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05531 } 05532 /* Set the path to the tmpfile as 05533 VM_SPOOL_DIR/context/ext/temp 05534 and attempt to create the folder structure. 05535 */ 05536 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05537 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05538 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05539 ast_free(tmp); 05540 return -1; 05541 } 05542 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05543 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05544 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05545 05546 DISPOSE(tempfile, -1); 05547 /* It's easier just to try to make it than to check for its existence */ 05548 #ifndef IMAP_STORAGE 05549 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05550 #else 05551 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05552 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05553 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05554 } 05555 #endif 05556 05557 /* Check current or macro-calling context for special extensions */ 05558 if (ast_test_flag(vmu, VM_OPERATOR)) { 05559 if (!ast_strlen_zero(vmu->exit)) { 05560 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05561 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05562 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05563 ouseexten = 1; 05564 } 05565 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05566 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05567 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05568 ouseexten = 1; 05569 } else if (!ast_strlen_zero(chan->macrocontext) 05570 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05571 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05572 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05573 ousemacro = 1; 05574 } 05575 } 05576 05577 if (!ast_strlen_zero(vmu->exit)) { 05578 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05579 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05580 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05581 } 05582 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05583 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05584 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05585 } else if (!ast_strlen_zero(chan->macrocontext) 05586 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05587 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05588 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05589 ausemacro = 1; 05590 } 05591 05592 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05593 for (code = alldtmf; *code; code++) { 05594 char e[2] = ""; 05595 e[0] = *code; 05596 if (strchr(ecodes, e[0]) == NULL 05597 && ast_canmatch_extension(chan, chan->context, e, 1, 05598 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05599 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05600 } 05601 } 05602 } 05603 05604 /* Play the beginning intro if desired */ 05605 if (!ast_strlen_zero(prefile)) { 05606 #ifdef ODBC_STORAGE 05607 int success = 05608 #endif 05609 RETRIEVE(prefile, -1, ext, context); 05610 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05611 if (ast_streamfile(chan, prefile, chan->language) > -1) 05612 res = ast_waitstream(chan, ecodes); 05613 #ifdef ODBC_STORAGE 05614 if (success == -1) { 05615 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05616 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05617 store_file(prefile, vmu->mailbox, vmu->context, -1); 05618 } 05619 #endif 05620 } else { 05621 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05622 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05623 } 05624 DISPOSE(prefile, -1); 05625 if (res < 0) { 05626 ast_debug(1, "Hang up during prefile playback\n"); 05627 free_user(vmu); 05628 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05629 ast_free(tmp); 05630 return -1; 05631 } 05632 } 05633 if (res == '#') { 05634 /* On a '#' we skip the instructions */ 05635 ast_set_flag(options, OPT_SILENT); 05636 res = 0; 05637 } 05638 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05639 if (vmu->maxmsg == 0) { 05640 if (option_debug > 2) 05641 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05642 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05643 goto leave_vm_out; 05644 } 05645 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05646 res = ast_stream_and_wait(chan, INTRO, ecodes); 05647 if (res == '#') { 05648 ast_set_flag(options, OPT_SILENT); 05649 res = 0; 05650 } 05651 } 05652 if (res > 0) 05653 ast_stopstream(chan); 05654 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05655 other than the operator -- an automated attendant or mailbox login for example */ 05656 if (res == '*') { 05657 chan->exten[0] = 'a'; 05658 chan->exten[1] = '\0'; 05659 if (!ast_strlen_zero(vmu->exit)) { 05660 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05661 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05662 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05663 } 05664 chan->priority = 0; 05665 free_user(vmu); 05666 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05667 ast_free(tmp); 05668 return 0; 05669 } 05670 05671 /* Check for a '0' here */ 05672 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05673 transfer: 05674 if (ouseexten || ousemacro) { 05675 chan->exten[0] = 'o'; 05676 chan->exten[1] = '\0'; 05677 if (!ast_strlen_zero(vmu->exit)) { 05678 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05679 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05680 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05681 } 05682 ast_play_and_wait(chan, "transfer"); 05683 chan->priority = 0; 05684 free_user(vmu); 05685 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05686 } 05687 ast_free(tmp); 05688 return OPERATOR_EXIT; 05689 } 05690 05691 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05692 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05693 if (!ast_strlen_zero(options->exitcontext)) 05694 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05695 free_user(vmu); 05696 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05697 ast_free(tmp); 05698 return res; 05699 } 05700 05701 if (res < 0) { 05702 free_user(vmu); 05703 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05704 ast_free(tmp); 05705 return -1; 05706 } 05707 /* The meat of recording the message... All the announcements and beeps have been played*/ 05708 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05709 if (!ast_strlen_zero(fmt)) { 05710 msgnum = 0; 05711 05712 #ifdef IMAP_STORAGE 05713 /* Is ext a mailbox? */ 05714 /* must open stream for this user to get info! */ 05715 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05716 if (res < 0) { 05717 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05718 ast_free(tmp); 05719 return -1; 05720 } 05721 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05722 /* It is possible under certain circumstances that inboxcount did not 05723 * create a vm_state when it was needed. This is a catchall which will 05724 * rarely be used. 05725 */ 05726 if (!(vms = create_vm_state_from_user(vmu))) { 05727 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05728 ast_free(tmp); 05729 return -1; 05730 } 05731 } 05732 vms->newmessages++; 05733 05734 /* here is a big difference! We add one to it later */ 05735 msgnum = newmsgs + oldmsgs; 05736 ast_debug(3, "Messagecount set to %d\n", msgnum); 05737 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05738 /* set variable for compatibility */ 05739 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05740 05741 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05742 goto leave_vm_out; 05743 } 05744 #else 05745 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05746 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05747 if (!res) 05748 res = ast_waitstream(chan, ""); 05749 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05750 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05751 inprocess_count(vmu->mailbox, vmu->context, -1); 05752 goto leave_vm_out; 05753 } 05754 05755 #endif 05756 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05757 txtdes = mkstemp(tmptxtfile); 05758 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05759 if (txtdes < 0) { 05760 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05761 if (!res) 05762 res = ast_waitstream(chan, ""); 05763 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05764 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05765 inprocess_count(vmu->mailbox, vmu->context, -1); 05766 goto leave_vm_out; 05767 } 05768 05769 /* Now play the beep once we have the message number for our next message. */ 05770 if (res >= 0) { 05771 /* Unless we're *really* silent, try to send the beep */ 05772 res = ast_stream_and_wait(chan, "beep", ""); 05773 } 05774 05775 /* Store information in real-time storage */ 05776 if (ast_check_realtime("voicemail_data")) { 05777 snprintf(priority, sizeof(priority), "%d", chan->priority); 05778 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05779 get_date(date, sizeof(date)); 05780 ast_callerid_merge(callerid, sizeof(callerid), 05781 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05782 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05783 "Unknown"); 05784 ast_store_realtime("voicemail_data", 05785 "origmailbox", ext, 05786 "context", chan->context, 05787 "macrocontext", chan->macrocontext, 05788 "exten", chan->exten, 05789 "priority", priority, 05790 "callerchan", chan->name, 05791 "callerid", callerid, 05792 "origdate", date, 05793 "origtime", origtime, 05794 "category", S_OR(category, ""), 05795 "filename", tmptxtfile, 05796 SENTINEL); 05797 } 05798 05799 /* Store information */ 05800 txt = fdopen(txtdes, "w+"); 05801 if (txt) { 05802 get_date(date, sizeof(date)); 05803 ast_callerid_merge(callerid, sizeof(callerid), 05804 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05805 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05806 "Unknown"); 05807 fprintf(txt, 05808 ";\n" 05809 "; Message Information file\n" 05810 ";\n" 05811 "[message]\n" 05812 "origmailbox=%s\n" 05813 "context=%s\n" 05814 "macrocontext=%s\n" 05815 "exten=%s\n" 05816 "rdnis=%s\n" 05817 "priority=%d\n" 05818 "callerchan=%s\n" 05819 "callerid=%s\n" 05820 "origdate=%s\n" 05821 "origtime=%ld\n" 05822 "category=%s\n", 05823 ext, 05824 chan->context, 05825 chan->macrocontext, 05826 chan->exten, 05827 S_COR(chan->redirecting.from.number.valid, 05828 chan->redirecting.from.number.str, "unknown"), 05829 chan->priority, 05830 chan->name, 05831 callerid, 05832 date, (long) time(NULL), 05833 category ? category : ""); 05834 } else { 05835 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05836 inprocess_count(vmu->mailbox, vmu->context, -1); 05837 if (ast_check_realtime("voicemail_data")) { 05838 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05839 } 05840 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05841 goto leave_vm_out; 05842 } 05843 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05844 05845 if (txt) { 05846 fprintf(txt, "flag=%s\n", flag); 05847 if (duration < vmu->minsecs) { 05848 fclose(txt); 05849 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmu->minsecs); 05850 ast_filedelete(tmptxtfile, NULL); 05851 unlink(tmptxtfile); 05852 if (ast_check_realtime("voicemail_data")) { 05853 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05854 } 05855 inprocess_count(vmu->mailbox, vmu->context, -1); 05856 } else { 05857 fprintf(txt, "duration=%d\n", duration); 05858 fclose(txt); 05859 if (vm_lock_path(dir)) { 05860 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05861 /* Delete files */ 05862 ast_filedelete(tmptxtfile, NULL); 05863 unlink(tmptxtfile); 05864 inprocess_count(vmu->mailbox, vmu->context, -1); 05865 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05866 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05867 unlink(tmptxtfile); 05868 ast_unlock_path(dir); 05869 inprocess_count(vmu->mailbox, vmu->context, -1); 05870 if (ast_check_realtime("voicemail_data")) { 05871 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05872 } 05873 } else { 05874 #ifndef IMAP_STORAGE 05875 msgnum = last_message_index(vmu, dir) + 1; 05876 #endif 05877 make_file(fn, sizeof(fn), dir, msgnum); 05878 05879 /* assign a variable with the name of the voicemail file */ 05880 #ifndef IMAP_STORAGE 05881 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05882 #else 05883 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05884 #endif 05885 05886 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05887 ast_filerename(tmptxtfile, fn, NULL); 05888 rename(tmptxtfile, txtfile); 05889 inprocess_count(vmu->mailbox, vmu->context, -1); 05890 05891 /* Properly set permissions on voicemail text descriptor file. 05892 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05893 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05894 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05895 05896 ast_unlock_path(dir); 05897 if (ast_check_realtime("voicemail_data")) { 05898 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05899 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 05900 } 05901 /* We must store the file first, before copying the message, because 05902 * ODBC storage does the entire copy with SQL. 05903 */ 05904 if (ast_fileexists(fn, NULL, NULL) > 0) { 05905 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05906 } 05907 05908 /* Are there to be more recipients of this message? */ 05909 while (tmpptr) { 05910 struct ast_vm_user recipu, *recip; 05911 char *exten, *cntx; 05912 05913 exten = strsep(&tmpptr, "&"); 05914 cntx = strchr(exten, '@'); 05915 if (cntx) { 05916 *cntx = '\0'; 05917 cntx++; 05918 } 05919 if ((recip = find_user(&recipu, cntx, exten))) { 05920 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05921 free_user(recip); 05922 } 05923 } 05924 #ifndef IMAP_STORAGE 05925 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05926 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05927 char sfn[PATH_MAX]; 05928 char dfn[PATH_MAX]; 05929 int x; 05930 /* It's easier just to try to make it than to check for its existence */ 05931 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05932 x = last_message_index(vmu, urgdir) + 1; 05933 make_file(sfn, sizeof(sfn), dir, msgnum); 05934 make_file(dfn, sizeof(dfn), urgdir, x); 05935 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 05936 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05937 /* Notification must happen for this new message in Urgent folder, not INBOX */ 05938 ast_copy_string(fn, dfn, sizeof(fn)); 05939 msgnum = x; 05940 } 05941 #endif 05942 /* Notification needs to happen after the copy, though. */ 05943 if (ast_fileexists(fn, NULL, NULL)) { 05944 #ifdef IMAP_STORAGE 05945 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 05946 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05947 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05948 flag); 05949 #else 05950 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 05951 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05952 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05953 flag); 05954 #endif 05955 } 05956 05957 /* Disposal needs to happen after the optional move and copy */ 05958 if (ast_fileexists(fn, NULL, NULL)) { 05959 DISPOSE(dir, msgnum); 05960 } 05961 } 05962 } 05963 } else { 05964 inprocess_count(vmu->mailbox, vmu->context, -1); 05965 } 05966 if (res == '0') { 05967 goto transfer; 05968 } else if (res > 0 && res != 't') 05969 res = 0; 05970 05971 if (duration < vmu->minsecs) 05972 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05973 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05974 else 05975 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05976 } else 05977 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 05978 leave_vm_out: 05979 free_user(vmu); 05980 05981 #ifdef IMAP_STORAGE 05982 /* expunge message - use UID Expunge if supported on IMAP server*/ 05983 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 05984 if (expungeonhangup == 1) { 05985 ast_mutex_lock(&vms->lock); 05986 #ifdef HAVE_IMAP_TK2006 05987 if (LEVELUIDPLUS (vms->mailstream)) { 05988 mail_expunge_full(vms->mailstream, NIL, EX_UID); 05989 } else 05990 #endif 05991 mail_expunge(vms->mailstream); 05992 ast_mutex_unlock(&vms->lock); 05993 } 05994 #endif 05995 05996 ast_free(tmp); 05997 return res; 05998 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11469 of file app_voicemail_odbcstorage.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, 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_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, 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, 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, LOG_ERROR, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, smdi_iface, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, 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_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.
11470 { 11471 struct ast_vm_user *current; 11472 struct ast_config *cfg, *ucfg; 11473 char *cat; 11474 struct ast_variable *var; 11475 const char *val; 11476 char *q, *stringp, *tmp; 11477 int x; 11478 int tmpadsi[4]; 11479 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11480 char secretfn[PATH_MAX] = ""; 11481 11482 ast_unload_realtime("voicemail"); 11483 ast_unload_realtime("voicemail_data"); 11484 11485 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11486 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11487 return 0; 11488 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11489 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11490 ucfg = NULL; 11491 } 11492 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11493 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11494 ast_config_destroy(ucfg); 11495 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11496 return 0; 11497 } 11498 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11499 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11500 return 0; 11501 } else { 11502 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11503 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11504 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11505 ucfg = NULL; 11506 } 11507 } 11508 #ifdef IMAP_STORAGE 11509 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11510 #endif 11511 /* set audio control prompts */ 11512 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11513 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11514 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11515 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11516 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11517 11518 /* Free all the users structure */ 11519 free_vm_users(); 11520 11521 /* Free all the zones structure */ 11522 free_vm_zones(); 11523 11524 AST_LIST_LOCK(&users); 11525 11526 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11527 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11528 11529 if (cfg) { 11530 /* General settings */ 11531 11532 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11533 val = "default"; 11534 ast_copy_string(userscontext, val, sizeof(userscontext)); 11535 /* Attach voice message to mail message ? */ 11536 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11537 val = "yes"; 11538 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11539 11540 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11541 val = "no"; 11542 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11543 11544 volgain = 0.0; 11545 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11546 sscanf(val, "%30lf", &volgain); 11547 11548 #ifdef ODBC_STORAGE 11549 strcpy(odbc_database, "asterisk"); 11550 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11551 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11552 } 11553 strcpy(odbc_table, "voicemessages"); 11554 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11555 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11556 } 11557 #endif 11558 /* Mail command */ 11559 strcpy(mailcmd, SENDMAIL); 11560 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11561 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11562 11563 maxsilence = 0; 11564 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11565 maxsilence = atoi(val); 11566 if (maxsilence > 0) 11567 maxsilence *= 1000; 11568 } 11569 11570 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11571 maxmsg = MAXMSG; 11572 } else { 11573 maxmsg = atoi(val); 11574 if (maxmsg < 0) { 11575 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11576 maxmsg = MAXMSG; 11577 } else if (maxmsg > MAXMSGLIMIT) { 11578 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11579 maxmsg = MAXMSGLIMIT; 11580 } 11581 } 11582 11583 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11584 maxdeletedmsg = 0; 11585 } else { 11586 if (sscanf(val, "%30d", &x) == 1) 11587 maxdeletedmsg = x; 11588 else if (ast_true(val)) 11589 maxdeletedmsg = MAXMSG; 11590 else 11591 maxdeletedmsg = 0; 11592 11593 if (maxdeletedmsg < 0) { 11594 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11595 maxdeletedmsg = MAXMSG; 11596 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11597 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11598 maxdeletedmsg = MAXMSGLIMIT; 11599 } 11600 } 11601 11602 /* Load date format config for voicemail mail */ 11603 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11604 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11605 } 11606 11607 /* Load date format config for voicemail pager mail */ 11608 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11609 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11610 } 11611 11612 /* External password changing command */ 11613 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11614 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11615 pwdchange = PWDCHANGE_EXTERNAL; 11616 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11617 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11618 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11619 } 11620 11621 /* External password validation command */ 11622 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11623 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11624 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11625 } 11626 11627 #ifdef IMAP_STORAGE 11628 /* IMAP server address */ 11629 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11630 ast_copy_string(imapserver, val, sizeof(imapserver)); 11631 } else { 11632 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11633 } 11634 /* IMAP server port */ 11635 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11636 ast_copy_string(imapport, val, sizeof(imapport)); 11637 } else { 11638 ast_copy_string(imapport, "143", sizeof(imapport)); 11639 } 11640 /* IMAP server flags */ 11641 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11642 ast_copy_string(imapflags, val, sizeof(imapflags)); 11643 } 11644 /* IMAP server master username */ 11645 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11646 ast_copy_string(authuser, val, sizeof(authuser)); 11647 } 11648 /* IMAP server master password */ 11649 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11650 ast_copy_string(authpassword, val, sizeof(authpassword)); 11651 } 11652 /* Expunge on exit */ 11653 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11654 if (ast_false(val)) 11655 expungeonhangup = 0; 11656 else 11657 expungeonhangup = 1; 11658 } else { 11659 expungeonhangup = 1; 11660 } 11661 /* IMAP voicemail folder */ 11662 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11663 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 11664 } else { 11665 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 11666 } 11667 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 11668 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 11669 } 11670 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 11671 imapgreetings = ast_true(val); 11672 } else { 11673 imapgreetings = 0; 11674 } 11675 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 11676 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11677 } else { 11678 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 11679 } 11680 11681 /* There is some very unorthodox casting done here. This is due 11682 * to the way c-client handles the argument passed in. It expects a 11683 * void pointer and casts the pointer directly to a long without 11684 * first dereferencing it. */ 11685 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 11686 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 11687 } else { 11688 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 11689 } 11690 11691 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 11692 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 11693 } else { 11694 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 11695 } 11696 11697 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 11698 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 11699 } else { 11700 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 11701 } 11702 11703 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 11704 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 11705 } else { 11706 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 11707 } 11708 11709 /* Increment configuration version */ 11710 imapversion++; 11711 #endif 11712 /* External voicemail notify application */ 11713 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 11714 ast_copy_string(externnotify, val, sizeof(externnotify)); 11715 ast_debug(1, "found externnotify: %s\n", externnotify); 11716 } else { 11717 externnotify[0] = '\0'; 11718 } 11719 11720 /* SMDI voicemail notification */ 11721 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 11722 ast_debug(1, "Enabled SMDI voicemail notification\n"); 11723 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 11724 smdi_iface = ast_smdi_interface_find(val); 11725 } else { 11726 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 11727 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 11728 } 11729 if (!smdi_iface) { 11730 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 11731 } 11732 } 11733 11734 /* Silence treshold */ 11735 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 11736 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 11737 silencethreshold = atoi(val); 11738 11739 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 11740 val = ASTERISK_USERNAME; 11741 ast_copy_string(serveremail, val, sizeof(serveremail)); 11742 11743 vmmaxsecs = 0; 11744 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 11745 if (sscanf(val, "%30d", &x) == 1) { 11746 vmmaxsecs = x; 11747 } else { 11748 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 11749 } 11750 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 11751 static int maxmessage_deprecate = 0; 11752 if (maxmessage_deprecate == 0) { 11753 maxmessage_deprecate = 1; 11754 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 11755 } 11756 if (sscanf(val, "%30d", &x) == 1) { 11757 vmmaxsecs = x; 11758 } else { 11759 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 11760 } 11761 } 11762 11763 vmminsecs = 0; 11764 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 11765 if (sscanf(val, "%30d", &x) == 1) { 11766 vmminsecs = x; 11767 if (maxsilence / 1000 >= vmminsecs) { 11768 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 11769 } 11770 } else { 11771 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 11772 } 11773 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 11774 static int maxmessage_deprecate = 0; 11775 if (maxmessage_deprecate == 0) { 11776 maxmessage_deprecate = 1; 11777 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 11778 } 11779 if (sscanf(val, "%30d", &x) == 1) { 11780 vmminsecs = x; 11781 if (maxsilence / 1000 >= vmminsecs) { 11782 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 11783 } 11784 } else { 11785 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 11786 } 11787 } 11788 11789 val = ast_variable_retrieve(cfg, "general", "format"); 11790 if (!val) { 11791 val = "wav"; 11792 } else { 11793 tmp = ast_strdupa(val); 11794 val = ast_format_str_reduce(tmp); 11795 if (!val) { 11796 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 11797 val = "wav"; 11798 } 11799 } 11800 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 11801 11802 skipms = 3000; 11803 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 11804 if (sscanf(val, "%30d", &x) == 1) { 11805 maxgreet = x; 11806 } else { 11807 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 11808 } 11809 } 11810 11811 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 11812 if (sscanf(val, "%30d", &x) == 1) { 11813 skipms = x; 11814 } else { 11815 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 11816 } 11817 } 11818 11819 maxlogins = 3; 11820 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 11821 if (sscanf(val, "%30d", &x) == 1) { 11822 maxlogins = x; 11823 } else { 11824 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 11825 } 11826 } 11827 11828 minpassword = MINPASSWORD; 11829 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 11830 if (sscanf(val, "%30d", &x) == 1) { 11831 minpassword = x; 11832 } else { 11833 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 11834 } 11835 } 11836 11837 /* Force new user to record name ? */ 11838 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 11839 val = "no"; 11840 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 11841 11842 /* Force new user to record greetings ? */ 11843 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 11844 val = "no"; 11845 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 11846 11847 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 11848 ast_debug(1, "VM_CID Internal context string: %s\n", val); 11849 stringp = ast_strdupa(val); 11850 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 11851 if (!ast_strlen_zero(stringp)) { 11852 q = strsep(&stringp, ","); 11853 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 11854 q++; 11855 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 11856 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 11857 } else { 11858 cidinternalcontexts[x][0] = '\0'; 11859 } 11860 } 11861 } 11862 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 11863 ast_debug(1, "VM Review Option disabled globally\n"); 11864 val = "no"; 11865 } 11866 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 11867 11868 /* Temporary greeting reminder */ 11869 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 11870 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 11871 val = "no"; 11872 } else { 11873 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 11874 } 11875 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 11876 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 11877 ast_debug(1, "VM next message wrap disabled globally\n"); 11878 val = "no"; 11879 } 11880 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 11881 11882 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 11883 ast_debug(1, "VM Operator break disabled globally\n"); 11884 val = "no"; 11885 } 11886 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 11887 11888 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 11889 ast_debug(1, "VM CID Info before msg disabled globally\n"); 11890 val = "no"; 11891 } 11892 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 11893 11894 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 11895 ast_debug(1, "Send Voicemail msg disabled globally\n"); 11896 val = "no"; 11897 } 11898 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 11899 11900 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 11901 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 11902 val = "yes"; 11903 } 11904 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 11905 11906 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 11907 ast_debug(1, "Move Heard enabled globally\n"); 11908 val = "yes"; 11909 } 11910 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 11911 11912 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 11913 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 11914 val = "no"; 11915 } 11916 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 11917 11918 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 11919 ast_debug(1, "Duration info before msg enabled globally\n"); 11920 val = "yes"; 11921 } 11922 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 11923 11924 saydurationminfo = 2; 11925 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 11926 if (sscanf(val, "%30d", &x) == 1) { 11927 saydurationminfo = x; 11928 } else { 11929 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 11930 } 11931 } 11932 11933 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 11934 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 11935 val = "no"; 11936 } 11937 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 11938 11939 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 11940 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 11941 ast_debug(1, "found dialout context: %s\n", dialcontext); 11942 } else { 11943 dialcontext[0] = '\0'; 11944 } 11945 11946 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 11947 ast_copy_string(callcontext, val, sizeof(callcontext)); 11948 ast_debug(1, "found callback context: %s\n", callcontext); 11949 } else { 11950 callcontext[0] = '\0'; 11951 } 11952 11953 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 11954 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 11955 ast_debug(1, "found operator context: %s\n", exitcontext); 11956 } else { 11957 exitcontext[0] = '\0'; 11958 } 11959 11960 /* load password sounds configuration */ 11961 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 11962 ast_copy_string(vm_password, val, sizeof(vm_password)); 11963 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 11964 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 11965 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 11966 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 11967 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 11968 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 11969 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 11970 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 11971 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 11972 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 11973 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 11974 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 11975 } 11976 /* load configurable audio prompts */ 11977 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 11978 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 11979 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 11980 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 11981 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 11982 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 11983 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 11984 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 11985 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 11986 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 11987 11988 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 11989 val = "no"; 11990 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 11991 11992 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 11993 val = "voicemail.conf"; 11994 } 11995 if (!(strcmp(val, "spooldir"))) { 11996 passwordlocation = OPT_PWLOC_SPOOLDIR; 11997 } else { 11998 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 11999 } 12000 12001 poll_freq = DEFAULT_POLL_FREQ; 12002 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12003 if (sscanf(val, "%30u", &poll_freq) != 1) { 12004 poll_freq = DEFAULT_POLL_FREQ; 12005 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12006 } 12007 } 12008 12009 poll_mailboxes = 0; 12010 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12011 poll_mailboxes = ast_true(val); 12012 12013 if (ucfg) { 12014 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12015 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12016 continue; 12017 if ((current = find_or_create(userscontext, cat))) { 12018 populate_defaults(current); 12019 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12020 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12021 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12022 current->passwordlocation = OPT_PWLOC_USERSCONF; 12023 } 12024 12025 switch (current->passwordlocation) { 12026 case OPT_PWLOC_SPOOLDIR: 12027 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12028 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12029 } 12030 } 12031 } 12032 ast_config_destroy(ucfg); 12033 } 12034 cat = ast_category_browse(cfg, NULL); 12035 while (cat) { 12036 if (strcasecmp(cat, "general")) { 12037 var = ast_variable_browse(cfg, cat); 12038 if (strcasecmp(cat, "zonemessages")) { 12039 /* Process mailboxes in this context */ 12040 while (var) { 12041 append_mailbox(cat, var->name, var->value); 12042 var = var->next; 12043 } 12044 } else { 12045 /* Timezones in this context */ 12046 while (var) { 12047 struct vm_zone *z; 12048 if ((z = ast_malloc(sizeof(*z)))) { 12049 char *msg_format, *tzone; 12050 msg_format = ast_strdupa(var->value); 12051 tzone = strsep(&msg_format, "|,"); 12052 if (msg_format) { 12053 ast_copy_string(z->name, var->name, sizeof(z->name)); 12054 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12055 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12056 AST_LIST_LOCK(&zones); 12057 AST_LIST_INSERT_HEAD(&zones, z, list); 12058 AST_LIST_UNLOCK(&zones); 12059 } else { 12060 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12061 ast_free(z); 12062 } 12063 } else { 12064 AST_LIST_UNLOCK(&users); 12065 ast_config_destroy(cfg); 12066 return -1; 12067 } 12068 var = var->next; 12069 } 12070 } 12071 } 12072 cat = ast_category_browse(cfg, cat); 12073 } 12074 memset(fromstring, 0, sizeof(fromstring)); 12075 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12076 strcpy(charset, "ISO-8859-1"); 12077 if (emailbody) { 12078 ast_free(emailbody); 12079 emailbody = NULL; 12080 } 12081 if (emailsubject) { 12082 ast_free(emailsubject); 12083 emailsubject = NULL; 12084 } 12085 if (pagerbody) { 12086 ast_free(pagerbody); 12087 pagerbody = NULL; 12088 } 12089 if (pagersubject) { 12090 ast_free(pagersubject); 12091 pagersubject = NULL; 12092 } 12093 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12094 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12095 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12096 ast_copy_string(fromstring, val, sizeof(fromstring)); 12097 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12098 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12099 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12100 ast_copy_string(charset, val, sizeof(charset)); 12101 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12102 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12103 for (x = 0; x < 4; x++) { 12104 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12105 } 12106 } 12107 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12108 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12109 for (x = 0; x < 4; x++) { 12110 memcpy(&adsisec[x], &tmpadsi[x], 1); 12111 } 12112 } 12113 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12114 if (atoi(val)) { 12115 adsiver = atoi(val); 12116 } 12117 } 12118 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12119 ast_copy_string(zonetag, val, sizeof(zonetag)); 12120 } 12121 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12122 ast_copy_string(locale, val, sizeof(locale)); 12123 } 12124 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12125 emailsubject = ast_strdup(val); 12126 } 12127 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12128 emailbody = ast_strdup(substitute_escapes(val)); 12129 } 12130 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12131 pagersubject = ast_strdup(val); 12132 } 12133 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12134 pagerbody = ast_strdup(substitute_escapes(val)); 12135 } 12136 AST_LIST_UNLOCK(&users); 12137 ast_config_destroy(cfg); 12138 12139 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12140 start_poll_thread(); 12141 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12142 stop_poll_thread();; 12143 12144 return 0; 12145 } else { 12146 AST_LIST_UNLOCK(&users); 12147 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12148 if (ucfg) 12149 ast_config_destroy(ucfg); 12150 return 0; 12151 } 12152 }
static int load_module | ( | void | ) | [static] |
Definition at line 12644 of file app_voicemail_odbcstorage.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), ast_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, RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), vmauthenticate(), and vmsayname_exec().
12645 { 12646 int res; 12647 my_umask = umask(0); 12648 umask(my_umask); 12649 12650 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 12651 return AST_MODULE_LOAD_DECLINE; 12652 } 12653 12654 /* compute the location of the voicemail spool directory */ 12655 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 12656 12657 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 12658 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 12659 } 12660 12661 if ((res = load_config(0))) 12662 return res; 12663 12664 res = ast_register_application_xml(app, vm_exec); 12665 res |= ast_register_application_xml(app2, vm_execmain); 12666 res |= ast_register_application_xml(app3, vm_box_exists); 12667 res |= ast_register_application_xml(app4, vmauthenticate); 12668 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 12669 res |= ast_custom_function_register(&mailbox_exists_acf); 12670 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 12671 #ifdef TEST_FRAMEWORK 12672 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 12673 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 12674 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 12675 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 12676 #endif 12677 12678 if (res) 12679 return res; 12680 12681 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 12682 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 12683 12684 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 12685 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 12686 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 12687 12688 return res; 12689 }
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 1563 of file app_voicemail_odbcstorage.c.
01564 { 01565 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01566 }
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 4386 of file app_voicemail_odbcstorage.c.
References add_email_attachment(), ast_channel_release(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_localtime(), ast_log(), ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
04387 { 04388 char date[256]; 04389 char host[MAXHOSTNAMELEN] = ""; 04390 char who[256]; 04391 char bound[256]; 04392 char dur[256]; 04393 struct ast_tm tm; 04394 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04395 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04396 char *greeting_attachment; 04397 char filename[256]; 04398 04399 if (!str1 || !str2) { 04400 ast_free(str1); 04401 ast_free(str2); 04402 return; 04403 } 04404 04405 if (cidnum) { 04406 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04407 } 04408 if (cidname) { 04409 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04410 } 04411 gethostname(host, sizeof(host) - 1); 04412 04413 if (strchr(srcemail, '@')) { 04414 ast_copy_string(who, srcemail, sizeof(who)); 04415 } else { 04416 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04417 } 04418 04419 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04420 if (greeting_attachment) { 04421 *greeting_attachment++ = '\0'; 04422 } 04423 04424 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04425 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04426 fprintf(p, "Date: %s" ENDL, date); 04427 04428 /* Set date format for voicemail mail */ 04429 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04430 04431 if (!ast_strlen_zero(fromstring)) { 04432 struct ast_channel *ast; 04433 if ((ast = ast_dummy_channel_alloc())) { 04434 char *ptr; 04435 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04436 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04437 04438 if (check_mime(ast_str_buffer(str1))) { 04439 int first_line = 1; 04440 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04441 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04442 *ptr = '\0'; 04443 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04444 first_line = 0; 04445 /* Substring is smaller, so this will never grow */ 04446 ast_str_set(&str2, 0, "%s", ptr + 1); 04447 } 04448 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04449 } else { 04450 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04451 } 04452 ast = ast_channel_release(ast); 04453 } else { 04454 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04455 } 04456 } else { 04457 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04458 } 04459 04460 if (check_mime(vmu->fullname)) { 04461 int first_line = 1; 04462 char *ptr; 04463 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04464 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04465 *ptr = '\0'; 04466 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04467 first_line = 0; 04468 /* Substring is smaller, so this will never grow */ 04469 ast_str_set(&str2, 0, "%s", ptr + 1); 04470 } 04471 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04472 } else { 04473 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04474 } 04475 04476 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04477 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04478 struct ast_channel *ast; 04479 if ((ast = ast_dummy_channel_alloc())) { 04480 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04481 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04482 if (check_mime(ast_str_buffer(str1))) { 04483 int first_line = 1; 04484 char *ptr; 04485 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04486 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04487 *ptr = '\0'; 04488 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04489 first_line = 0; 04490 /* Substring is smaller, so this will never grow */ 04491 ast_str_set(&str2, 0, "%s", ptr + 1); 04492 } 04493 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04494 } else { 04495 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04496 } 04497 ast = ast_channel_release(ast); 04498 } else { 04499 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04500 } 04501 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04502 if (ast_strlen_zero(flag)) { 04503 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04504 } else { 04505 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04506 } 04507 } else { 04508 if (ast_strlen_zero(flag)) { 04509 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04510 } else { 04511 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04512 } 04513 } 04514 04515 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04516 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04517 if (imap) { 04518 /* additional information needed for IMAP searching */ 04519 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04520 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04521 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04522 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04523 #ifdef IMAP_STORAGE 04524 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04525 #else 04526 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04527 #endif 04528 /* flag added for Urgent */ 04529 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04530 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04531 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04532 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04533 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04534 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04535 if (!ast_strlen_zero(category)) { 04536 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04537 } else { 04538 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04539 } 04540 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04541 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04542 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04543 } 04544 if (!ast_strlen_zero(cidnum)) { 04545 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04546 } 04547 if (!ast_strlen_zero(cidname)) { 04548 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04549 } 04550 fprintf(p, "MIME-Version: 1.0" ENDL); 04551 if (attach_user_voicemail) { 04552 /* Something unique. */ 04553 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04554 (int) getpid(), (unsigned int) ast_random()); 04555 04556 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04557 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04558 fprintf(p, "--%s" ENDL, bound); 04559 } 04560 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04561 if (emailbody || vmu->emailbody) { 04562 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04563 struct ast_channel *ast; 04564 if ((ast = ast_dummy_channel_alloc())) { 04565 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04566 ast_str_substitute_variables(&str1, 0, ast, e_body); 04567 #ifdef IMAP_STORAGE 04568 { 04569 /* Convert body to native line terminators for IMAP backend */ 04570 char *line = ast_str_buffer(str1), *next; 04571 do { 04572 /* Terminate line before outputting it to the file */ 04573 if ((next = strchr(line, '\n'))) { 04574 *next++ = '\0'; 04575 } 04576 fprintf(p, "%s" ENDL, line); 04577 line = next; 04578 } while (!ast_strlen_zero(line)); 04579 } 04580 #else 04581 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04582 #endif 04583 ast = ast_channel_release(ast); 04584 } else { 04585 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04586 } 04587 } else if (msgnum > -1) { 04588 if (strcmp(vmu->mailbox, mailbox)) { 04589 /* Forwarded type */ 04590 struct ast_config *msg_cfg; 04591 const char *v; 04592 int inttime; 04593 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04594 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04595 /* Retrieve info from VM attribute file */ 04596 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04597 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04598 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04599 strcat(fromfile, ".txt"); 04600 } 04601 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04602 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04603 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04604 } 04605 04606 /* You might be tempted to do origdate, except that a) it's in the wrong 04607 * format, and b) it's missing for IMAP recordings. */ 04608 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04609 struct timeval tv = { inttime, }; 04610 struct ast_tm tm; 04611 ast_localtime(&tv, &tm, NULL); 04612 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04613 } 04614 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04615 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04616 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04617 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04618 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04619 date, origcallerid, origdate); 04620 ast_config_destroy(msg_cfg); 04621 } else { 04622 goto plain_message; 04623 } 04624 } else { 04625 plain_message: 04626 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04627 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04628 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04629 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04630 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04631 } 04632 } else { 04633 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04634 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04635 } 04636 04637 if (imap || attach_user_voicemail) { 04638 if (!ast_strlen_zero(attach2)) { 04639 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04640 ast_debug(5, "creating second attachment filename %s\n", filename); 04641 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04642 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04643 ast_debug(5, "creating attachment filename %s\n", filename); 04644 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04645 } else { 04646 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04647 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04648 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04649 } 04650 } 04651 ast_free(str1); 04652 ast_free(str2); 04653 }
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 1580 of file app_voicemail_odbcstorage.c.
01581 { 01582 return snprintf(dest, len, "%s/msg%04d", dir, num); 01583 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11303 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.
11304 { 11305 struct ast_vm_user *vmu = NULL; 11306 const char *id = astman_get_header(m, "ActionID"); 11307 char actionid[128] = ""; 11308 11309 if (!ast_strlen_zero(id)) 11310 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11311 11312 AST_LIST_LOCK(&users); 11313 11314 if (AST_LIST_EMPTY(&users)) { 11315 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11316 AST_LIST_UNLOCK(&users); 11317 return RESULT_SUCCESS; 11318 } 11319 11320 astman_send_ack(s, m, "Voicemail user list will follow"); 11321 11322 AST_LIST_TRAVERSE(&users, vmu, list) { 11323 char dirname[256]; 11324 11325 #ifdef IMAP_STORAGE 11326 int new, old; 11327 inboxcount(vmu->mailbox, &new, &old); 11328 #endif 11329 11330 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11331 astman_append(s, 11332 "%s" 11333 "Event: VoicemailUserEntry\r\n" 11334 "VMContext: %s\r\n" 11335 "VoiceMailbox: %s\r\n" 11336 "Fullname: %s\r\n" 11337 "Email: %s\r\n" 11338 "Pager: %s\r\n" 11339 "ServerEmail: %s\r\n" 11340 "MailCommand: %s\r\n" 11341 "Language: %s\r\n" 11342 "TimeZone: %s\r\n" 11343 "Callback: %s\r\n" 11344 "Dialout: %s\r\n" 11345 "UniqueID: %s\r\n" 11346 "ExitContext: %s\r\n" 11347 "SayDurationMinimum: %d\r\n" 11348 "SayEnvelope: %s\r\n" 11349 "SayCID: %s\r\n" 11350 "AttachMessage: %s\r\n" 11351 "AttachmentFormat: %s\r\n" 11352 "DeleteMessage: %s\r\n" 11353 "VolumeGain: %.2f\r\n" 11354 "CanReview: %s\r\n" 11355 "CallOperator: %s\r\n" 11356 "MaxMessageCount: %d\r\n" 11357 "MaxMessageLength: %d\r\n" 11358 "NewMessageCount: %d\r\n" 11359 #ifdef IMAP_STORAGE 11360 "OldMessageCount: %d\r\n" 11361 "IMAPUser: %s\r\n" 11362 #endif 11363 "\r\n", 11364 actionid, 11365 vmu->context, 11366 vmu->mailbox, 11367 vmu->fullname, 11368 vmu->email, 11369 vmu->pager, 11370 vmu->serveremail, 11371 vmu->mailcmd, 11372 vmu->language, 11373 vmu->zonetag, 11374 vmu->callback, 11375 vmu->dialout, 11376 vmu->uniqueid, 11377 vmu->exit, 11378 vmu->saydurationm, 11379 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11380 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11381 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11382 vmu->attachfmt, 11383 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11384 vmu->volgain, 11385 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11386 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11387 vmu->maxmsg, 11388 vmu->maxsecs, 11389 #ifdef IMAP_STORAGE 11390 new, old, vmu->imapuser 11391 #else 11392 count_messages(vmu, dirname) 11393 #endif 11394 ); 11395 } 11396 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11397 11398 AST_LIST_UNLOCK(&users); 11399 11400 return RESULT_SUCCESS; 11401 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11137 of file app_voicemail_odbcstorage.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_lock, and poll_subscribed_mailboxes().
11138 { 11139 while (poll_thread_run) { 11140 struct timespec ts = { 0, }; 11141 struct timeval wait; 11142 11143 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11144 ts.tv_sec = wait.tv_sec; 11145 ts.tv_nsec = wait.tv_usec * 1000; 11146 11147 ast_mutex_lock(&poll_lock); 11148 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11149 ast_mutex_unlock(&poll_lock); 11150 11151 if (!poll_thread_run) 11152 break; 11153 11154 poll_subscribed_mailboxes(); 11155 } 11156 11157 return NULL; 11158 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1641 of file app_voicemail_odbcstorage.c.
References ARRAY_LEN.
01642 { 01643 #ifdef IMAP_STORAGE 01644 if (vmu && id == 0) { 01645 return vmu->imapfolder; 01646 } 01647 #endif 01648 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01649 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5232 of file app_voicemail_odbcstorage.c.
References __has_voicemail().
05233 { 05234 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05235 }
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 11238 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.
11239 { 11240 struct mwi_sub_task *mwist; 11241 11242 if (ast_event_get_type(event) != AST_EVENT_SUB) 11243 return; 11244 11245 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11246 return; 11247 11248 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11249 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11250 return; 11251 } 11252 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11253 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11254 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11255 11256 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11257 ast_free(mwist); 11258 } 11259 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11222 of file app_voicemail_odbcstorage.c.
References ast_calloc, ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, ast_free, ast_taskprocessor_push(), handle_unsubscribe(), mwi_subscription_tps, and mwi_sub_task::uniqueid.
11223 { 11224 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11225 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11226 return; 11227 11228 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11229 return; 11230 11231 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11232 *uniqueid = u; 11233 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11234 ast_free(uniqueid); 11235 } 11236 }
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 6836 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, strsep(), VM_ATTACH, vm_delete(), and VM_DELETE.
06837 { 06838 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06839 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06840 const char *category; 06841 char *myserveremail = serveremail; 06842 06843 ast_channel_lock(chan); 06844 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06845 category = ast_strdupa(category); 06846 } 06847 ast_channel_unlock(chan); 06848 06849 #ifndef IMAP_STORAGE 06850 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 06851 #else 06852 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 06853 #endif 06854 make_file(fn, sizeof(fn), todir, msgnum); 06855 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06856 06857 if (!ast_strlen_zero(vmu->attachfmt)) { 06858 if (strstr(fmt, vmu->attachfmt)) 06859 fmt = vmu->attachfmt; 06860 else 06861 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); 06862 } 06863 06864 /* Attach only the first format */ 06865 fmt = ast_strdupa(fmt); 06866 stringp = fmt; 06867 strsep(&stringp, "|"); 06868 06869 if (!ast_strlen_zero(vmu->serveremail)) 06870 myserveremail = vmu->serveremail; 06871 06872 if (!ast_strlen_zero(vmu->email)) { 06873 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 06874 06875 if (attach_user_voicemail) 06876 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 06877 06878 /* XXX possible imap issue, should category be NULL XXX */ 06879 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 06880 06881 if (attach_user_voicemail) 06882 DISPOSE(todir, msgnum); 06883 } 06884 06885 if (!ast_strlen_zero(vmu->pager)) { 06886 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 06887 } 06888 06889 if (ast_test_flag(vmu, VM_DELETE)) 06890 DELETE(todir, msgnum, fn, vmu); 06891 06892 /* Leave voicemail for someone */ 06893 if (ast_app_has_voicemail(ext_context, NULL)) 06894 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 06895 06896 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 06897 06898 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); 06899 run_externnotify(vmu->context, vmu->mailbox, flag); 06900 06901 #ifdef IMAP_STORAGE 06902 vm_delete(fn); /* Delete the file, but not the IMAP message */ 06903 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 06904 vm_imap_delete(NULL, vms->curmsg, vmu); 06905 vms->newmessages--; /* Fix new message count */ 06906 } 06907 #endif 06908 06909 return 0; 06910 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4106 of file app_voicemail_odbcstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
04107 { 04108 if (bio->linelength >= BASELINELEN) { 04109 if (fputs(ENDL, so) == EOF) { 04110 return -1; 04111 } 04112 04113 bio->linelength = 0; 04114 } 04115 04116 if (putc(((unsigned char) c), so) == EOF) { 04117 return -1; 04118 } 04119 04120 bio->linelength++; 04121 04122 return 1; 04123 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7670 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(), vm_state::username, vm_allocate_dh(), vm_lock_path(), and vm_state::vmbox.
07671 { 07672 int count_msg, last_msg; 07673 07674 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07675 07676 /* Rename the member vmbox HERE so that we don't try to return before 07677 * we know what's going on. 07678 */ 07679 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07680 07681 /* Faster to make the directory than to check if it exists. */ 07682 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07683 07684 /* traverses directory using readdir (or select query for ODBC) */ 07685 count_msg = count_messages(vmu, vms->curdir); 07686 if (count_msg < 0) { 07687 return count_msg; 07688 } else { 07689 vms->lastmsg = count_msg - 1; 07690 } 07691 07692 if (vm_allocate_dh(vms, vmu, count_msg)) { 07693 return -1; 07694 } 07695 07696 /* 07697 The following test is needed in case sequencing gets messed up. 07698 There appears to be more than one way to mess up sequence, so 07699 we will not try to find all of the root causes--just fix it when 07700 detected. 07701 */ 07702 07703 if (vm_lock_path(vms->curdir)) { 07704 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07705 return ERROR_LOCK_PATH; 07706 } 07707 07708 /* for local storage, checks directory for messages up to maxmsg limit */ 07709 last_msg = last_message_index(vmu, vms->curdir); 07710 ast_unlock_path(vms->curdir); 07711 07712 if (last_msg < -1) { 07713 return last_msg; 07714 } else if (vms->lastmsg != last_msg) { 07715 ast_log(LOG_NOTICE, "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); 07716 } 07717 07718 return 0; 07719 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7456 of file app_voicemail_odbcstorage.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, ast_channel::language, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
07457 { 07458 int res = 0; 07459 char filename[256], *cid; 07460 const char *origtime, *context, *category, *duration, *flag; 07461 struct ast_config *msg_cfg; 07462 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07463 07464 vms->starting = 0; 07465 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07466 adsi_message(chan, vms); 07467 if (!vms->curmsg) 07468 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07469 else if (vms->curmsg == vms->lastmsg) 07470 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07471 07472 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07473 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07474 msg_cfg = ast_config_load(filename, config_flags); 07475 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07476 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07477 return 0; 07478 } 07479 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07480 07481 /* Play the word urgent if we are listening to urgent messages */ 07482 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07483 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07484 } 07485 07486 if (!res) { 07487 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07488 /* POLISH syntax */ 07489 if (!strncasecmp(chan->language, "pl", 2)) { 07490 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07491 int ten, one; 07492 char nextmsg[256]; 07493 ten = (vms->curmsg + 1) / 10; 07494 one = (vms->curmsg + 1) % 10; 07495 07496 if (vms->curmsg < 20) { 07497 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07498 res = wait_file2(chan, vms, nextmsg); 07499 } else { 07500 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07501 res = wait_file2(chan, vms, nextmsg); 07502 if (one > 0) { 07503 if (!res) { 07504 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07505 res = wait_file2(chan, vms, nextmsg); 07506 } 07507 } 07508 } 07509 } 07510 if (!res) 07511 res = wait_file2(chan, vms, "vm-message"); 07512 /* HEBREW syntax */ 07513 } else if (!strncasecmp(chan->language, "he", 2)) { 07514 if (!vms->curmsg) { 07515 res = wait_file2(chan, vms, "vm-message"); 07516 res = wait_file2(chan, vms, "vm-first"); 07517 } else if (vms->curmsg == vms->lastmsg) { 07518 res = wait_file2(chan, vms, "vm-message"); 07519 res = wait_file2(chan, vms, "vm-last"); 07520 } else { 07521 res = wait_file2(chan, vms, "vm-message"); 07522 res = wait_file2(chan, vms, "vm-number"); 07523 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07524 } 07525 /* VIETNAMESE syntax */ 07526 } else if (!strncasecmp(chan->language, "vi", 2)) { 07527 if (!vms->curmsg) { 07528 res = wait_file2(chan, vms, "vm-message"); 07529 res = wait_file2(chan, vms, "vm-first"); 07530 } else if (vms->curmsg == vms->lastmsg) { 07531 res = wait_file2(chan, vms, "vm-message"); 07532 res = wait_file2(chan, vms, "vm-last"); 07533 } else { 07534 res = wait_file2(chan, vms, "vm-message"); 07535 res = wait_file2(chan, vms, "vm-number"); 07536 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07537 } 07538 } else { 07539 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07540 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07541 } else { /* DEFAULT syntax */ 07542 res = wait_file2(chan, vms, "vm-message"); 07543 } 07544 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07545 if (!res) { 07546 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07547 } 07548 } 07549 } 07550 } 07551 07552 if (!msg_cfg) { 07553 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07554 return 0; 07555 } 07556 07557 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07558 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07559 DISPOSE(vms->curdir, vms->curmsg); 07560 ast_config_destroy(msg_cfg); 07561 return 0; 07562 } 07563 07564 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07565 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07566 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07567 07568 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07569 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07570 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07571 if (!res) { 07572 res = play_message_category(chan, category); 07573 } 07574 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 07575 res = play_message_datetime(chan, vmu, origtime, filename); 07576 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 07577 res = play_message_callerid(chan, vms, cid, context, 0); 07578 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 07579 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07580 /* Allow pressing '1' to skip envelope / callerid */ 07581 if (res == '1') 07582 res = 0; 07583 ast_config_destroy(msg_cfg); 07584 07585 if (!res) { 07586 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07587 vms->heard[vms->curmsg] = 1; 07588 #ifdef IMAP_STORAGE 07589 /*IMAP storage stores any prepended message from a forward 07590 * as a separate file from the rest of the message 07591 */ 07592 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07593 wait_file(chan, vms, vms->introfn); 07594 } 07595 #endif 07596 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07597 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07598 res = 0; 07599 } 07600 } 07601 DISPOSE(vms->curdir, vms->curmsg); 07602 return res; 07603 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7342 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, and wait_file2().
07343 { 07344 int res = 0; 07345 int i; 07346 char *callerid, *name; 07347 char prefile[PATH_MAX] = ""; 07348 07349 07350 /* If voicemail cid is not enabled, or we didn't get cid or context from 07351 * the attribute file, leave now. 07352 * 07353 * TODO Still need to change this so that if this function is called by the 07354 * message envelope (and someone is explicitly requesting to hear the CID), 07355 * it does not check to see if CID is enabled in the config file. 07356 */ 07357 if ((cid == NULL)||(context == NULL)) 07358 return res; 07359 07360 /* Strip off caller ID number from name */ 07361 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07362 ast_callerid_parse(cid, &name, &callerid); 07363 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07364 /* Check for internal contexts and only */ 07365 /* say extension when the call didn't come from an internal context in the list */ 07366 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07367 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07368 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07369 break; 07370 } 07371 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07372 if (!res) { 07373 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07374 if (!ast_strlen_zero(prefile)) { 07375 /* See if we can find a recorded name for this person instead of their extension number */ 07376 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07377 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07378 if (!callback) 07379 res = wait_file2(chan, vms, "vm-from"); 07380 res = ast_stream_and_wait(chan, prefile, ""); 07381 } else { 07382 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07383 /* Say "from extension" as one saying to sound smoother */ 07384 if (!callback) 07385 res = wait_file2(chan, vms, "vm-from-extension"); 07386 res = ast_say_digit_str(chan, callerid, "", chan->language); 07387 } 07388 } 07389 } 07390 } else if (!res) { 07391 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07392 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07393 if (!callback) 07394 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07395 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07396 } 07397 } else { 07398 /* Number unknown */ 07399 ast_debug(1, "VM-CID: From an unknown number\n"); 07400 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07401 res = wait_file2(chan, vms, "vm-unknown-caller"); 07402 } 07403 return res; 07404 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7253 of file app_voicemail_odbcstorage.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
07254 { 07255 int res = 0; 07256 07257 if (!ast_strlen_zero(category)) 07258 res = ast_play_and_wait(chan, category); 07259 07260 if (res) { 07261 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07262 res = 0; 07263 } 07264 07265 return res; 07266 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7268 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.
07269 { 07270 int res = 0; 07271 struct vm_zone *the_zone = NULL; 07272 time_t t; 07273 07274 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07275 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07276 return 0; 07277 } 07278 07279 /* Does this user have a timezone specified? */ 07280 if (!ast_strlen_zero(vmu->zonetag)) { 07281 /* Find the zone in the list */ 07282 struct vm_zone *z; 07283 AST_LIST_LOCK(&zones); 07284 AST_LIST_TRAVERSE(&zones, z, list) { 07285 if (!strcmp(z->name, vmu->zonetag)) { 07286 the_zone = z; 07287 break; 07288 } 07289 } 07290 AST_LIST_UNLOCK(&zones); 07291 } 07292 07293 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07294 #if 0 07295 /* Set the DIFF_* variables */ 07296 ast_localtime(&t, &time_now, NULL); 07297 tv_now = ast_tvnow(); 07298 ast_localtime(&tv_now, &time_then, NULL); 07299 07300 /* Day difference */ 07301 if (time_now.tm_year == time_then.tm_year) 07302 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07303 else 07304 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07305 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07306 07307 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07308 #endif 07309 if (the_zone) { 07310 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07311 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07312 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07313 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07314 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07315 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07316 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); 07317 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07318 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07319 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07320 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07321 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07322 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07323 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07324 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); 07325 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07326 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07327 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07328 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07329 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07330 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); 07331 } else { 07332 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07333 } 07334 #if 0 07335 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07336 #endif 07337 return res; 07338 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7406 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().
07407 { 07408 int res = 0; 07409 int durationm; 07410 int durations; 07411 /* Verify that we have a duration for the message */ 07412 if (duration == NULL) 07413 return res; 07414 07415 /* Convert from seconds to minutes */ 07416 durations = atoi(duration); 07417 durationm = (durations / 60); 07418 07419 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07420 07421 if ((!res) && (durationm >= minduration)) { 07422 res = wait_file2(chan, vms, "vm-duration"); 07423 07424 /* POLISH syntax */ 07425 if (!strncasecmp(chan->language, "pl", 2)) { 07426 div_t num = div(durationm, 10); 07427 07428 if (durationm == 1) { 07429 res = ast_play_and_wait(chan, "digits/1z"); 07430 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07431 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07432 if (num.rem == 2) { 07433 if (!num.quot) { 07434 res = ast_play_and_wait(chan, "digits/2-ie"); 07435 } else { 07436 res = say_and_wait(chan, durationm - 2 , chan->language); 07437 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07438 } 07439 } else { 07440 res = say_and_wait(chan, durationm, chan->language); 07441 } 07442 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07443 } else { 07444 res = say_and_wait(chan, durationm, chan->language); 07445 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07446 } 07447 /* DEFAULT syntax */ 07448 } else { 07449 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07450 res = wait_file2(chan, vms, "vm-minutes"); 07451 } 07452 } 07453 return res; 07454 }
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, | |||
const char * | unlockdir, | |||
signed char | record_gain, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
Definition at line 12951 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, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
12954 { 12955 /* Record message & let caller review or re-record it, or set options if applicable */ 12956 int res = 0; 12957 int cmd = 0; 12958 int max_attempts = 3; 12959 int attempts = 0; 12960 int recorded = 0; 12961 int msg_exists = 0; 12962 signed char zero_gain = 0; 12963 char tempfile[PATH_MAX]; 12964 char *acceptdtmf = "#"; 12965 char *canceldtmf = ""; 12966 int canceleddtmf = 0; 12967 12968 /* Note that urgent and private are for flagging messages as such in the future */ 12969 12970 /* barf if no pointer passed to store duration in */ 12971 if (duration == NULL) { 12972 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 12973 return -1; 12974 } 12975 12976 if (!outsidecaller) 12977 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 12978 else 12979 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 12980 12981 cmd = '3'; /* Want to start by recording */ 12982 12983 while ((cmd >= 0) && (cmd != 't')) { 12984 switch (cmd) { 12985 case '1': 12986 if (!msg_exists) { 12987 /* In this case, 1 is to record a message */ 12988 cmd = '3'; 12989 break; 12990 } else { 12991 /* Otherwise 1 is to save the existing message */ 12992 ast_verb(3, "Saving message as is\n"); 12993 if (!outsidecaller) 12994 ast_filerename(tempfile, recordfile, NULL); 12995 ast_stream_and_wait(chan, "vm-msgsaved", ""); 12996 if (!outsidecaller) { 12997 /* Saves to IMAP server only if imapgreeting=yes */ 12998 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 12999 DISPOSE(recordfile, -1); 13000 } 13001 cmd = 't'; 13002 return res; 13003 } 13004 case '2': 13005 /* Review */ 13006 ast_verb(3, "Reviewing the message\n"); 13007 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13008 break; 13009 case '3': 13010 msg_exists = 0; 13011 /* Record */ 13012 if (recorded == 1) 13013 ast_verb(3, "Re-recording the message\n"); 13014 else 13015 ast_verb(3, "Recording the message\n"); 13016 13017 if (recorded && outsidecaller) { 13018 cmd = ast_play_and_wait(chan, INTRO); 13019 cmd = ast_play_and_wait(chan, "beep"); 13020 } 13021 recorded = 1; 13022 /* 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 */ 13023 if (record_gain) 13024 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13025 if (ast_test_flag(vmu, VM_OPERATOR)) 13026 canceldtmf = "0"; 13027 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13028 if (strchr(canceldtmf, cmd)) { 13029 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13030 canceleddtmf = 1; 13031 } 13032 if (record_gain) 13033 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13034 if (cmd == -1) { 13035 /* User has hung up, no options to give */ 13036 if (!outsidecaller) { 13037 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13038 ast_filedelete(tempfile, NULL); 13039 } 13040 return cmd; 13041 } 13042 if (cmd == '0') { 13043 break; 13044 } else if (cmd == '*') { 13045 break; 13046 #if 0 13047 } else if (vmu->review && (*duration < 5)) { 13048 /* Message is too short */ 13049 ast_verb(3, "Message too short\n"); 13050 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13051 cmd = ast_filedelete(tempfile, NULL); 13052 break; 13053 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 13054 /* Message is all silence */ 13055 ast_verb(3, "Nothing recorded\n"); 13056 cmd = ast_filedelete(tempfile, NULL); 13057 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13058 if (!cmd) 13059 cmd = ast_play_and_wait(chan, "vm-speakup"); 13060 break; 13061 #endif 13062 } else { 13063 /* If all is well, a message exists */ 13064 msg_exists = 1; 13065 cmd = 0; 13066 } 13067 break; 13068 case '4': 13069 if (outsidecaller) { /* only mark vm messages */ 13070 /* Mark Urgent */ 13071 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13072 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13073 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13074 strcpy(flag, "Urgent"); 13075 } else if (flag) { 13076 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13077 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13078 strcpy(flag, ""); 13079 } else { 13080 ast_play_and_wait(chan, "vm-sorry"); 13081 } 13082 cmd = 0; 13083 } else { 13084 cmd = ast_play_and_wait(chan, "vm-sorry"); 13085 } 13086 break; 13087 case '5': 13088 case '6': 13089 case '7': 13090 case '8': 13091 case '9': 13092 case '*': 13093 case '#': 13094 cmd = ast_play_and_wait(chan, "vm-sorry"); 13095 break; 13096 #if 0 13097 /* XXX Commented out for the moment because of the dangers of deleting 13098 a message while recording (can put the message numbers out of sync) */ 13099 case '*': 13100 /* Cancel recording, delete message, offer to take another message*/ 13101 cmd = ast_play_and_wait(chan, "vm-deleted"); 13102 cmd = ast_filedelete(tempfile, NULL); 13103 if (outsidecaller) { 13104 res = vm_exec(chan, NULL); 13105 return res; 13106 } 13107 else 13108 return 1; 13109 #endif 13110 case '0': 13111 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13112 cmd = ast_play_and_wait(chan, "vm-sorry"); 13113 break; 13114 } 13115 if (msg_exists || recorded) { 13116 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13117 if (!cmd) 13118 cmd = ast_waitfordigit(chan, 3000); 13119 if (cmd == '1') { 13120 ast_filerename(tempfile, recordfile, NULL); 13121 ast_play_and_wait(chan, "vm-msgsaved"); 13122 cmd = '0'; 13123 } else if (cmd == '4') { 13124 if (flag) { 13125 ast_play_and_wait(chan, "vm-marked-urgent"); 13126 strcpy(flag, "Urgent"); 13127 } 13128 ast_play_and_wait(chan, "vm-msgsaved"); 13129 cmd = '0'; 13130 } else { 13131 ast_play_and_wait(chan, "vm-deleted"); 13132 DELETE(tempfile, -1, tempfile, vmu); 13133 cmd = '0'; 13134 } 13135 } 13136 return cmd; 13137 default: 13138 /* If the caller is an ouside caller, and the review option is enabled, 13139 allow them to review the message, but let the owner of the box review 13140 their OGM's */ 13141 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13142 return cmd; 13143 if (msg_exists) { 13144 cmd = ast_play_and_wait(chan, "vm-review"); 13145 if (!cmd && outsidecaller) { 13146 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13147 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13148 } else if (flag) { 13149 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13150 } 13151 } 13152 } else { 13153 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13154 if (!cmd) 13155 cmd = ast_waitfordigit(chan, 600); 13156 } 13157 13158 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13159 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13160 if (!cmd) 13161 cmd = ast_waitfordigit(chan, 600); 13162 } 13163 #if 0 13164 if (!cmd) 13165 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13166 #endif 13167 if (!cmd) 13168 cmd = ast_waitfordigit(chan, 6000); 13169 if (!cmd) { 13170 attempts++; 13171 } 13172 if (attempts > max_attempts) { 13173 cmd = 't'; 13174 } 13175 } 13176 } 13177 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13178 /* Hang up or timeout, so delete the recording. */ 13179 ast_filedelete(tempfile, NULL); 13180 } 13181 13182 if (cmd != 't' && outsidecaller) 13183 ast_play_and_wait(chan, "vm-goodbye"); 13184 13185 return cmd; 13186 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11109 of file app_voicemail_odbcstorage.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
11110 { 11111 int new = 0, old = 0, urgent = 0; 11112 11113 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11114 11115 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11116 mwi_sub->old_urgent = urgent; 11117 mwi_sub->old_new = new; 11118 mwi_sub->old_old = old; 11119 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11120 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11121 } 11122 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11124 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().
11125 { 11126 struct mwi_sub *mwi_sub; 11127 11128 AST_RWLIST_RDLOCK(&mwi_subs); 11129 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11130 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11131 poll_subscribed_mailbox(mwi_sub); 11132 } 11133 } 11134 AST_RWLIST_UNLOCK(&mwi_subs); 11135 }
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 969 of file app_voicemail_odbcstorage.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, 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.
00970 { 00971 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00972 vmu->passwordlocation = passwordlocation; 00973 if (saydurationminfo) { 00974 vmu->saydurationm = saydurationminfo; 00975 } 00976 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 00977 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 00978 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 00979 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 00980 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 00981 if (vmminsecs) { 00982 vmu->minsecs = vmminsecs; 00983 } 00984 if (vmmaxsecs) { 00985 vmu->maxsecs = vmmaxsecs; 00986 } 00987 if (maxmsg) { 00988 vmu->maxmsg = maxmsg; 00989 } 00990 if (maxdeletedmsg) { 00991 vmu->maxdeletedmsg = maxdeletedmsg; 00992 } 00993 vmu->volgain = volgain; 00994 vmu->emailsubject = NULL; 00995 vmu->emailbody = NULL; 00996 #ifdef IMAP_STORAGE 00997 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 00998 #endif 00999 }
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 4194 of file app_voicemail_odbcstorage.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
04195 { 04196 char callerid[256]; 04197 char num[12]; 04198 char fromdir[256], fromfile[256]; 04199 struct ast_config *msg_cfg; 04200 const char *origcallerid, *origtime; 04201 char origcidname[80], origcidnum[80], origdate[80]; 04202 int inttime; 04203 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04204 04205 /* Prepare variables for substitution in email body and subject */ 04206 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04207 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04208 snprintf(num, sizeof(num), "%d", msgnum); 04209 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04210 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04211 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04212 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04213 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04214 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04215 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04216 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04217 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04218 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04219 04220 /* Retrieve info from VM attribute file */ 04221 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04222 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04223 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04224 strcat(fromfile, ".txt"); 04225 } 04226 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04227 if (option_debug > 0) { 04228 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04229 } 04230 return; 04231 } 04232 04233 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04234 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04235 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04236 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04237 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04238 } 04239 04240 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04241 struct timeval tv = { inttime, }; 04242 struct ast_tm tm; 04243 ast_localtime(&tv, &tm, NULL); 04244 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04245 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04246 } 04247 ast_config_destroy(msg_cfg); 04248 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6799 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().
06800 { 06801 struct ast_event *event; 06802 char *mailbox, *context; 06803 06804 /* Strip off @default */ 06805 context = mailbox = ast_strdupa(box); 06806 strsep(&context, "@"); 06807 if (ast_strlen_zero(context)) 06808 context = "default"; 06809 06810 if (!(event = ast_event_new(AST_EVENT_MWI, 06811 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06812 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06813 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06814 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06815 AST_EVENT_IE_END))) { 06816 return; 06817 } 06818 06819 ast_event_queue_and_cache(event); 06820 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12168 of file app_voicemail_odbcstorage.c.
References ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), config_flags, and LOG_NOTICE.
12168 { 12169 struct ast_config *pwconf; 12170 struct ast_flags config_flags = { 0 }; 12171 12172 pwconf = ast_config_load(secretfn, config_flags); 12173 if (pwconf) { 12174 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12175 if (val) { 12176 ast_copy_string(password, val, passwordlen); 12177 return; 12178 } 12179 } 12180 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12181 }
static int reload | ( | void | ) | [static] |
Definition at line 12605 of file app_voicemail_odbcstorage.c.
References load_config().
12606 { 12607 return load_config(1); 12608 }
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 3871 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03872 { 03873 char stxt[PATH_MAX]; 03874 char dtxt[PATH_MAX]; 03875 ast_filerename(sfn, dfn, NULL); 03876 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03877 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03878 if (ast_check_realtime("voicemail_data")) { 03879 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 03880 } 03881 rename(stxt, dtxt); 03882 }
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 1413 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.
01414 { 01415 /* This function could be made to generate one from a database, too */ 01416 struct ast_vm_user *cur; 01417 int res = -1; 01418 AST_LIST_LOCK(&users); 01419 AST_LIST_TRAVERSE(&users, cur, list) { 01420 if ((!context || !strcasecmp(context, cur->context)) && 01421 (!strcasecmp(mailbox, cur->mailbox))) 01422 break; 01423 } 01424 if (cur) { 01425 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01426 res = 0; 01427 } 01428 AST_LIST_UNLOCK(&users); 01429 return res; 01430 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5375 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, ast_smdi_mwi_message::fwd_st, inboxcount2(), smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
05376 { 05377 char arguments[255]; 05378 char ext_context[256] = ""; 05379 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05380 struct ast_smdi_mwi_message *mwi_msg; 05381 05382 if (!ast_strlen_zero(context)) 05383 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05384 else 05385 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05386 05387 if (smdi_iface) { 05388 if (ast_app_has_voicemail(ext_context, NULL)) 05389 ast_smdi_mwi_set(smdi_iface, extension); 05390 else 05391 ast_smdi_mwi_unset(smdi_iface, extension); 05392 05393 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05394 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05395 if (!strncmp(mwi_msg->cause, "INV", 3)) 05396 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05397 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05398 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05399 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05400 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05401 } else { 05402 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05403 } 05404 } 05405 05406 if (!ast_strlen_zero(externnotify)) { 05407 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05408 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05409 } else { 05410 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05411 ast_debug(1, "Executing %s\n", arguments); 05412 ast_safe_system(arguments); 05413 } 05414 } 05415 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6007 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().
06008 { 06009 #ifdef IMAP_STORAGE 06010 /* we must use mbox(x) folder names, and copy the message there */ 06011 /* simple. huh? */ 06012 char sequence[10]; 06013 char mailbox[256]; 06014 int res; 06015 06016 /* get the real IMAP message number for this message */ 06017 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06018 06019 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06020 ast_mutex_lock(&vms->lock); 06021 /* if save to Old folder, put in INBOX as read */ 06022 if (box == OLD_FOLDER) { 06023 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06024 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06025 } else if (box == NEW_FOLDER) { 06026 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06027 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06028 } 06029 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06030 ast_mutex_unlock(&vms->lock); 06031 return 0; 06032 } 06033 /* Create the folder if it don't exist */ 06034 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06035 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06036 if (mail_create(vms->mailstream, mailbox) == NIL) 06037 ast_debug(5, "Folder exists.\n"); 06038 else 06039 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06040 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06041 ast_mutex_unlock(&vms->lock); 06042 return res; 06043 #else 06044 char *dir = vms->curdir; 06045 char *username = vms->username; 06046 char *context = vmu->context; 06047 char sfn[PATH_MAX]; 06048 char dfn[PATH_MAX]; 06049 char ddir[PATH_MAX]; 06050 const char *dbox = mbox(vmu, box); 06051 int x, i; 06052 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06053 06054 if (vm_lock_path(ddir)) 06055 return ERROR_LOCK_PATH; 06056 06057 x = last_message_index(vmu, ddir) + 1; 06058 06059 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06060 x--; 06061 for (i = 1; i <= x; i++) { 06062 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06063 make_file(sfn, sizeof(sfn), ddir, i); 06064 make_file(dfn, sizeof(dfn), ddir, i - 1); 06065 if (EXISTS(ddir, i, sfn, NULL)) { 06066 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06067 } else 06068 break; 06069 } 06070 } else { 06071 if (x >= vmu->maxmsg) { 06072 ast_unlock_path(ddir); 06073 return -1; 06074 } 06075 } 06076 make_file(sfn, sizeof(sfn), dir, msg); 06077 make_file(dfn, sizeof(dfn), ddir, x); 06078 if (strcmp(sfn, dfn)) { 06079 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06080 } 06081 ast_unlock_path(ddir); 06082 #endif 06083 return 0; 06084 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6000 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, and ast_say_number().
06001 { 06002 int d; 06003 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06004 return d; 06005 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12154 of file app_voicemail_odbcstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.
12155 { 12156 int res = -1; 12157 char dir[PATH_MAX]; 12158 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12159 ast_debug(2, "About to try retrieving name file %s\n", dir); 12160 RETRIEVE(dir, -1, mailbox, context); 12161 if (ast_fileexists(dir, NULL, NULL)) { 12162 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12163 } 12164 DISPOSE(dir, -1); 12165 return res; 12166 }
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 4707 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, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().
04708 { 04709 FILE *p = NULL; 04710 char tmp[80] = "/tmp/astmail-XXXXXX"; 04711 char tmp2[256]; 04712 char *stringp; 04713 04714 if (vmu && ast_strlen_zero(vmu->email)) { 04715 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04716 return(0); 04717 } 04718 04719 /* Mail only the first format */ 04720 format = ast_strdupa(format); 04721 stringp = format; 04722 strsep(&stringp, "|"); 04723 04724 if (!strcmp(format, "wav49")) 04725 format = "WAV"; 04726 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)); 04727 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04728 command hangs */ 04729 if ((p = vm_mkftemp(tmp)) == NULL) { 04730 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04731 return -1; 04732 } else { 04733 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04734 fclose(p); 04735 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04736 ast_safe_system(tmp2); 04737 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04738 } 04739 return 0; 04740 }
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 4742 of file app_voicemail_odbcstorage.c.
References ast_channel_release(), ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_log(), ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strftime_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
04743 { 04744 char enc_cidnum[256], enc_cidname[256]; 04745 char date[256]; 04746 char host[MAXHOSTNAMELEN] = ""; 04747 char who[256]; 04748 char dur[PATH_MAX]; 04749 char tmp[80] = "/tmp/astmail-XXXXXX"; 04750 char tmp2[PATH_MAX]; 04751 struct ast_tm tm; 04752 FILE *p; 04753 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04754 04755 if (!str1 || !str2) { 04756 ast_free(str1); 04757 ast_free(str2); 04758 return -1; 04759 } 04760 04761 if (cidnum) { 04762 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04763 } 04764 if (cidname) { 04765 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04766 } 04767 04768 if ((p = vm_mkftemp(tmp)) == NULL) { 04769 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04770 ast_free(str1); 04771 ast_free(str2); 04772 return -1; 04773 } 04774 gethostname(host, sizeof(host)-1); 04775 if (strchr(srcemail, '@')) { 04776 ast_copy_string(who, srcemail, sizeof(who)); 04777 } else { 04778 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04779 } 04780 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04781 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04782 fprintf(p, "Date: %s\n", date); 04783 04784 /* Reformat for custom pager format */ 04785 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04786 04787 if (!ast_strlen_zero(pagerfromstring)) { 04788 struct ast_channel *ast; 04789 if ((ast = ast_dummy_channel_alloc())) { 04790 char *ptr; 04791 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04792 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04793 04794 if (check_mime(ast_str_buffer(str1))) { 04795 int first_line = 1; 04796 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04797 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04798 *ptr = '\0'; 04799 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04800 first_line = 0; 04801 /* Substring is smaller, so this will never grow */ 04802 ast_str_set(&str2, 0, "%s", ptr + 1); 04803 } 04804 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04805 } else { 04806 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04807 } 04808 ast = ast_channel_release(ast); 04809 } else { 04810 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04811 } 04812 } else { 04813 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04814 } 04815 04816 if (check_mime(vmu->fullname)) { 04817 int first_line = 1; 04818 char *ptr; 04819 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04820 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04821 *ptr = '\0'; 04822 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04823 first_line = 0; 04824 /* Substring is smaller, so this will never grow */ 04825 ast_str_set(&str2, 0, "%s", ptr + 1); 04826 } 04827 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04828 } else { 04829 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04830 } 04831 04832 if (!ast_strlen_zero(pagersubject)) { 04833 struct ast_channel *ast; 04834 if ((ast = ast_dummy_channel_alloc())) { 04835 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04836 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04837 if (check_mime(ast_str_buffer(str1))) { 04838 int first_line = 1; 04839 char *ptr; 04840 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04841 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04842 *ptr = '\0'; 04843 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04844 first_line = 0; 04845 /* Substring is smaller, so this will never grow */ 04846 ast_str_set(&str2, 0, "%s", ptr + 1); 04847 } 04848 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04849 } else { 04850 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04851 } 04852 ast = ast_channel_release(ast); 04853 } else { 04854 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04855 } 04856 } else { 04857 if (ast_strlen_zero(flag)) { 04858 fprintf(p, "Subject: New VM\n\n"); 04859 } else { 04860 fprintf(p, "Subject: New %s VM\n\n", flag); 04861 } 04862 } 04863 04864 if (pagerbody) { 04865 struct ast_channel *ast; 04866 if ((ast = ast_dummy_channel_alloc())) { 04867 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04868 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 04869 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04870 ast = ast_channel_release(ast); 04871 } else { 04872 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04873 } 04874 } else { 04875 fprintf(p, "New %s long %s msg in box %s\n" 04876 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04877 } 04878 04879 fclose(p); 04880 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04881 ast_safe_system(tmp2); 04882 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04883 ast_free(str1); 04884 ast_free(str2); 04885 return 0; 04886 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 10766 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.
10767 { 10768 struct ast_config *cfg; 10769 const char *cat = NULL; 10770 10771 if (!(cfg = ast_load_realtime_multientry("voicemail", 10772 "context", context, SENTINEL))) { 10773 return CLI_FAILURE; 10774 } 10775 10776 ast_cli(fd, 10777 "\n" 10778 "=============================================================\n" 10779 "=== Configured Voicemail Users ==============================\n" 10780 "=============================================================\n" 10781 "===\n"); 10782 10783 while ((cat = ast_category_browse(cfg, cat))) { 10784 struct ast_variable *var = NULL; 10785 ast_cli(fd, 10786 "=== Mailbox ...\n" 10787 "===\n"); 10788 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 10789 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 10790 ast_cli(fd, 10791 "===\n" 10792 "=== ---------------------------------------------------------\n" 10793 "===\n"); 10794 } 10795 10796 ast_cli(fd, 10797 "=============================================================\n" 10798 "\n"); 10799 10800 ast_config_destroy(cfg); 10801 10802 return CLI_SUCCESS; 10803 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11261 of file app_voicemail_odbcstorage.c.
References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_pthread_create, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), and mwi_unsub_sub.
11262 { 11263 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11264 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11265 AST_EVENT_IE_END); 11266 11267 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11268 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11269 AST_EVENT_IE_END); 11270 11271 if (mwi_sub_sub) 11272 ast_event_report_subs(mwi_sub_sub); 11273 11274 poll_thread_run = 1; 11275 11276 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11277 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11279 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, and poll_lock.
11280 { 11281 poll_thread_run = 0; 11282 11283 if (mwi_sub_sub) { 11284 ast_event_unsubscribe(mwi_sub_sub); 11285 mwi_sub_sub = NULL; 11286 } 11287 11288 if (mwi_unsub_sub) { 11289 ast_event_unsubscribe(mwi_unsub_sub); 11290 mwi_unsub_sub = NULL; 11291 } 11292 11293 ast_mutex_lock(&poll_lock); 11294 ast_cond_signal(&poll_cond); 11295 ast_mutex_unlock(&poll_lock); 11296 11297 pthread_join(poll_thread, NULL); 11298 11299 poll_thread = AST_PTHREADT_NULL; 11300 }
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 940 of file app_voicemail_odbcstorage.c.
00941 { 00942 char *bufptr = buf; 00943 for (; *input; input++) { 00944 if (*input < 32) { 00945 continue; 00946 } 00947 *bufptr++ = *input; 00948 if (bufptr == buf + buflen - 1) { 00949 break; 00950 } 00951 } 00952 *bufptr = '\0'; 00953 return buf; 00954 }
static const char* substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11425 of file app_voicemail_odbcstorage.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_reset(), ast_str_thread_get(), and str.
11426 { 11427 char *current; 11428 11429 /* Add 16 for fudge factor */ 11430 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11431 11432 ast_str_reset(str); 11433 11434 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11435 for (current = (char *) value; *current; current++) { 11436 if (*current == '\\') { 11437 current++; 11438 if (!*current) { 11439 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11440 break; 11441 } 11442 switch (*current) { 11443 case 'r': 11444 ast_str_append(&str, 0, "\r"); 11445 break; 11446 case 'n': 11447 #ifdef IMAP_STORAGE 11448 if (!str->used || str->str[str->used - 1] != '\r') { 11449 ast_str_append(&str, 0, "\r"); 11450 } 11451 #endif 11452 ast_str_append(&str, 0, "\n"); 11453 break; 11454 case 't': 11455 ast_str_append(&str, 0, "\t"); 11456 break; 11457 default: 11458 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11459 break; 11460 } 11461 } else { 11462 ast_str_append(&str, 0, "%c", *current); 11463 } 11464 } 11465 11466 return ast_str_buffer(str); 11467 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12610 of file app_voicemail_odbcstorage.c.
References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), cli_voicemail, free_vm_users(), free_vm_zones(), inprocess_container, mailbox_exists_acf, mwi_subscription_tps, and stop_poll_thread().
12611 { 12612 int res; 12613 12614 res = ast_unregister_application(app); 12615 res |= ast_unregister_application(app2); 12616 res |= ast_unregister_application(app3); 12617 res |= ast_unregister_application(app4); 12618 res |= ast_unregister_application(sayname_app); 12619 res |= ast_custom_function_unregister(&mailbox_exists_acf); 12620 res |= ast_manager_unregister("VoicemailUsersList"); 12621 res |= ast_data_unregister(NULL); 12622 #ifdef TEST_FRAMEWORK 12623 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 12624 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 12625 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 12626 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 12627 #endif 12628 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 12629 ast_uninstall_vm_functions(); 12630 ao2_ref(inprocess_container, -1); 12631 12632 if (poll_thread != AST_PTHREADT_NULL) 12633 stop_poll_thread(); 12634 12635 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 12636 ast_unload_realtime("voicemail"); 12637 ast_unload_realtime("voicemail_data"); 12638 12639 free_vm_users(); 12640 free_vm_zones(); 12641 return res; 12642 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1679 of file app_voicemail_odbcstorage.c.
References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
01679 { 01680 01681 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01682 if (!vms->dh_arraysize) { 01683 /* initial allocation */ 01684 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01685 return -1; 01686 } 01687 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01688 return -1; 01689 } 01690 vms->dh_arraysize = arraysize; 01691 } else if (vms->dh_arraysize < arraysize) { 01692 if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) { 01693 return -1; 01694 } 01695 if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) { 01696 return -1; 01697 } 01698 memset(vms->deleted, 0, arraysize * sizeof(int)); 01699 memset(vms->heard, 0, arraysize * sizeof(int)); 01700 vms->dh_arraysize = arraysize; 01701 } 01702 01703 return 0; 01704 }
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 9498 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_verb, ast_waitstream(), find_user(), ast_vm_user::password, S_COR, and vm_password.
09501 { 09502 int useadsi = 0, valid = 0, logretries = 0; 09503 char password[AST_MAX_EXTENSION]="", *passptr; 09504 struct ast_vm_user vmus, *vmu = NULL; 09505 09506 /* If ADSI is supported, setup login screen */ 09507 adsi_begin(chan, &useadsi); 09508 if (!skipuser && useadsi) 09509 adsi_login(chan); 09510 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09511 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09512 return -1; 09513 } 09514 09515 /* Authenticate them and get their mailbox/password */ 09516 09517 while (!valid && (logretries < max_logins)) { 09518 /* Prompt for, and read in the username */ 09519 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09520 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09521 return -1; 09522 } 09523 if (ast_strlen_zero(mailbox)) { 09524 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09525 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09526 } else { 09527 ast_verb(3, "Username not entered\n"); 09528 return -1; 09529 } 09530 } else if (mailbox[0] == '*') { 09531 /* user entered '*' */ 09532 if (ast_exists_extension(chan, chan->context, "a", 1, 09533 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09534 return -1; 09535 } 09536 mailbox[0] = '\0'; 09537 } 09538 09539 if (useadsi) 09540 adsi_password(chan); 09541 09542 if (!ast_strlen_zero(prefix)) { 09543 char fullusername[80] = ""; 09544 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09545 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09546 ast_copy_string(mailbox, fullusername, mailbox_size); 09547 } 09548 09549 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09550 vmu = find_user(&vmus, context, mailbox); 09551 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09552 /* saved password is blank, so don't bother asking */ 09553 password[0] = '\0'; 09554 } else { 09555 if (ast_streamfile(chan, vm_password, chan->language)) { 09556 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09557 return -1; 09558 } 09559 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09560 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09561 return -1; 09562 } else if (password[0] == '*') { 09563 /* user entered '*' */ 09564 if (ast_exists_extension(chan, chan->context, "a", 1, 09565 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09566 mailbox[0] = '*'; 09567 return -1; 09568 } 09569 mailbox[0] = '\0'; 09570 } 09571 } 09572 09573 if (vmu) { 09574 passptr = vmu->password; 09575 if (passptr[0] == '-') passptr++; 09576 } 09577 if (vmu && !strcmp(passptr, password)) 09578 valid++; 09579 else { 09580 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09581 if (!ast_strlen_zero(prefix)) 09582 mailbox[0] = '\0'; 09583 } 09584 logretries++; 09585 if (!valid) { 09586 if (skipuser || logretries >= max_logins) { 09587 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09588 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09589 return -1; 09590 } 09591 } else { 09592 if (useadsi) 09593 adsi_login(chan); 09594 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09595 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09596 return -1; 09597 } 09598 } 09599 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09600 return -1; 09601 } 09602 } 09603 if (!valid && (logretries >= max_logins)) { 09604 ast_stopstream(chan); 09605 ast_play_and_wait(chan, "vm-goodbye"); 09606 return -1; 09607 } 09608 if (vmu && !skipuser) { 09609 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09610 } 09611 return 0; 09612 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10661 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().
10662 { 10663 struct ast_vm_user svm; 10664 char *context, *box; 10665 AST_DECLARE_APP_ARGS(args, 10666 AST_APP_ARG(mbox); 10667 AST_APP_ARG(options); 10668 ); 10669 static int dep_warning = 0; 10670 10671 if (ast_strlen_zero(data)) { 10672 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10673 return -1; 10674 } 10675 10676 if (!dep_warning) { 10677 dep_warning = 1; 10678 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10679 } 10680 10681 box = ast_strdupa(data); 10682 10683 AST_STANDARD_APP_ARGS(args, box); 10684 10685 if (args.options) { 10686 } 10687 10688 if ((context = strchr(args.mbox, '@'))) { 10689 *context = '\0'; 10690 context++; 10691 } 10692 10693 if (find_user(&svm, context, args.mbox)) { 10694 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 10695 } else 10696 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 10697 10698 return 0; 10699 }
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 9477 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().
09478 { 09479 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09480 return vm_browse_messages_es(chan, vms, vmu); 09481 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09482 return vm_browse_messages_gr(chan, vms, vmu); 09483 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09484 return vm_browse_messages_he(chan, vms, vmu); 09485 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09486 return vm_browse_messages_it(chan, vms, vmu); 09487 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09488 return vm_browse_messages_pt(chan, vms, vmu); 09489 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09490 return vm_browse_messages_vi(chan, vms, vmu); 09491 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09492 return vm_browse_messages_zh(chan, vms, vmu); 09493 } else { /* Default to English syntax */ 09494 return vm_browse_messages_en(chan, vms, vmu); 09495 } 09496 }
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 9316 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09317 { 09318 int cmd = 0; 09319 09320 if (vms->lastmsg > -1) { 09321 cmd = play_message(chan, vmu, vms); 09322 } else { 09323 cmd = ast_play_and_wait(chan, "vm-youhave"); 09324 if (!cmd) 09325 cmd = ast_play_and_wait(chan, "vm-no"); 09326 if (!cmd) { 09327 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09328 cmd = ast_play_and_wait(chan, vms->fn); 09329 } 09330 if (!cmd) 09331 cmd = ast_play_and_wait(chan, "vm-messages"); 09332 } 09333 return cmd; 09334 }
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 9370 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09371 { 09372 int cmd; 09373 09374 if (vms->lastmsg > -1) { 09375 cmd = play_message(chan, vmu, vms); 09376 } else { 09377 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09378 if (!cmd) 09379 cmd = ast_play_and_wait(chan, "vm-messages"); 09380 if (!cmd) { 09381 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09382 cmd = ast_play_and_wait(chan, vms->fn); 09383 } 09384 } 09385 return cmd; 09386 }
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 9264 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.
09265 { 09266 int cmd = 0; 09267 09268 if (vms->lastmsg > -1) { 09269 cmd = play_message(chan, vmu, vms); 09270 } else { 09271 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09272 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09273 if (!cmd) { 09274 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09275 cmd = ast_play_and_wait(chan, vms->fn); 09276 } 09277 if (!cmd) 09278 cmd = ast_play_and_wait(chan, "vm-messages"); 09279 } else { 09280 if (!cmd) 09281 cmd = ast_play_and_wait(chan, "vm-messages"); 09282 if (!cmd) { 09283 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09284 cmd = ast_play_and_wait(chan, vms->fn); 09285 } 09286 } 09287 } 09288 return cmd; 09289 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9292 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
09293 { 09294 int cmd = 0; 09295 09296 if (vms->lastmsg > -1) { 09297 cmd = play_message(chan, vmu, vms); 09298 } else { 09299 if (!strcasecmp(vms->fn, "INBOX")) { 09300 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09301 } else { 09302 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09303 } 09304 } 09305 return cmd; 09306 }
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 9344 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09345 { 09346 int cmd; 09347 09348 if (vms->lastmsg > -1) { 09349 cmd = play_message(chan, vmu, vms); 09350 } else { 09351 cmd = ast_play_and_wait(chan, "vm-no"); 09352 if (!cmd) 09353 cmd = ast_play_and_wait(chan, "vm-message"); 09354 if (!cmd) { 09355 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09356 cmd = ast_play_and_wait(chan, vms->fn); 09357 } 09358 } 09359 return cmd; 09360 }
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 9396 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09397 { 09398 int cmd; 09399 09400 if (vms->lastmsg > -1) { 09401 cmd = play_message(chan, vmu, vms); 09402 } else { 09403 cmd = ast_play_and_wait(chan, "vm-no"); 09404 if (!cmd) { 09405 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09406 cmd = ast_play_and_wait(chan, vms->fn); 09407 } 09408 if (!cmd) 09409 cmd = ast_play_and_wait(chan, "vm-messages"); 09410 } 09411 return cmd; 09412 }
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 9450 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09451 { 09452 int cmd = 0; 09453 09454 if (vms->lastmsg > -1) { 09455 cmd = play_message(chan, vmu, vms); 09456 } else { 09457 cmd = ast_play_and_wait(chan, "vm-no"); 09458 if (!cmd) { 09459 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09460 cmd = ast_play_and_wait(chan, vms->fn); 09461 } 09462 } 09463 return cmd; 09464 }
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 9422 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09423 { 09424 int cmd; 09425 09426 if (vms->lastmsg > -1) { 09427 cmd = play_message(chan, vmu, vms); 09428 } else { 09429 cmd = ast_play_and_wait(chan, "vm-you"); 09430 if (!cmd) 09431 cmd = ast_play_and_wait(chan, "vm-haveno"); 09432 if (!cmd) 09433 cmd = ast_play_and_wait(chan, "vm-messages"); 09434 if (!cmd) { 09435 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09436 cmd = ast_play_and_wait(chan, vms->fn); 09437 } 09438 } 09439 return cmd; 09440 }
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 1439 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_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), value, var, VOICEMAIL_CONFIG, and write_password_to_file().
01440 { 01441 struct ast_config *cfg = NULL; 01442 struct ast_variable *var = NULL; 01443 struct ast_category *cat = NULL; 01444 char *category = NULL, *value = NULL, *new = NULL; 01445 const char *tmp = NULL; 01446 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01447 char secretfn[PATH_MAX] = ""; 01448 int found = 0; 01449 01450 if (!change_password_realtime(vmu, newpassword)) 01451 return; 01452 01453 /* check if we should store the secret in the spool directory next to the messages */ 01454 switch (vmu->passwordlocation) { 01455 case OPT_PWLOC_SPOOLDIR: 01456 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01457 if (write_password_to_file(secretfn, newpassword) == 0) { 01458 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01459 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01460 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01461 break; 01462 } else { 01463 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01464 } 01465 /* Fall-through */ 01466 case OPT_PWLOC_VOICEMAILCONF: 01467 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01468 while ((category = ast_category_browse(cfg, category))) { 01469 if (!strcasecmp(category, vmu->context)) { 01470 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01471 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01472 break; 01473 } 01474 value = strstr(tmp, ","); 01475 if (!value) { 01476 new = alloca(strlen(newpassword)+1); 01477 sprintf(new, "%s", newpassword); 01478 } else { 01479 new = alloca((strlen(value) + strlen(newpassword) + 1)); 01480 sprintf(new, "%s%s", newpassword, value); 01481 } 01482 if (!(cat = ast_category_get(cfg, category))) { 01483 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01484 break; 01485 } 01486 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01487 found = 1; 01488 } 01489 } 01490 /* save the results */ 01491 if (found) { 01492 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01493 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01494 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01495 break; 01496 } 01497 } 01498 /* Fall-through */ 01499 case OPT_PWLOC_USERSCONF: 01500 /* check users.conf and update the password stored for the mailbox */ 01501 /* if no vmsecret entry exists create one. */ 01502 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01503 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01504 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01505 ast_debug(4, "users.conf: %s\n", category); 01506 if (!strcasecmp(category, vmu->mailbox)) { 01507 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01508 ast_debug(3, "looks like we need to make vmsecret!\n"); 01509 var = ast_variable_new("vmsecret", newpassword, ""); 01510 } else { 01511 var = NULL; 01512 } 01513 new = alloca(strlen(newpassword) + 1); 01514 sprintf(new, "%s", newpassword); 01515 if (!(cat = ast_category_get(cfg, category))) { 01516 ast_debug(4, "failed to get category!\n"); 01517 ast_free(var); 01518 break; 01519 } 01520 if (!var) { 01521 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01522 } else { 01523 ast_variable_append(cat, var); 01524 } 01525 found = 1; 01526 break; 01527 } 01528 } 01529 /* save the results and clean things up */ 01530 if (found) { 01531 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01532 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01533 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01534 } 01535 } 01536 } 01537 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1539 of file app_voicemail_odbcstorage.c.
References ast_copy_string(), ast_safe_system(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
01540 { 01541 char buf[255]; 01542 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01543 if (!ast_safe_system(buf)) { 01544 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01545 /* Reset the password in memory, too */ 01546 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01547 } 01548 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1130 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.
01131 { 01132 int fds[2], pid = 0; 01133 01134 memset(buf, 0, len); 01135 01136 if (pipe(fds)) { 01137 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01138 } else { 01139 /* good to go*/ 01140 pid = ast_safe_fork(0); 01141 01142 if (pid < 0) { 01143 /* ok maybe not */ 01144 close(fds[0]); 01145 close(fds[1]); 01146 snprintf(buf, len, "FAILURE: Fork failed"); 01147 } else if (pid) { 01148 /* parent */ 01149 close(fds[1]); 01150 if (read(fds[0], buf, len) < 0) { 01151 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01152 } 01153 close(fds[0]); 01154 } else { 01155 /* child */ 01156 AST_DECLARE_APP_ARGS(arg, 01157 AST_APP_ARG(v)[20]; 01158 ); 01159 char *mycmd = ast_strdupa(command); 01160 01161 close(fds[0]); 01162 dup2(fds[1], STDOUT_FILENO); 01163 close(fds[1]); 01164 ast_close_fds_above_n(STDOUT_FILENO); 01165 01166 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01167 01168 execv(arg.v[0], arg.v); 01169 printf("FAILURE: %s", strerror(errno)); 01170 _exit(0); 01171 } 01172 } 01173 return buf; 01174 }
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 4048 of file app_voicemail_odbcstorage.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04049 { 04050 char *txt; 04051 int txtsize = 0; 04052 04053 txtsize = (strlen(file) + 5)*sizeof(char); 04054 txt = alloca(txtsize); 04055 /* Sprintf here would safe because we alloca'd exactly the right length, 04056 * but trying to eliminate all sprintf's anyhow 04057 */ 04058 if (ast_check_realtime("voicemail_data")) { 04059 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04060 } 04061 snprintf(txt, txtsize, "%s.txt", file); 04062 unlink(txt); 04063 return ast_filedelete(file, NULL); 04064 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10344 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.
10345 { 10346 int res = 0; 10347 char *tmp; 10348 struct leave_vm_options leave_options; 10349 struct ast_flags flags = { 0 }; 10350 char *opts[OPT_ARG_ARRAY_SIZE]; 10351 AST_DECLARE_APP_ARGS(args, 10352 AST_APP_ARG(argv0); 10353 AST_APP_ARG(argv1); 10354 ); 10355 10356 memset(&leave_options, 0, sizeof(leave_options)); 10357 10358 if (chan->_state != AST_STATE_UP) 10359 ast_answer(chan); 10360 10361 if (!ast_strlen_zero(data)) { 10362 tmp = ast_strdupa(data); 10363 AST_STANDARD_APP_ARGS(args, tmp); 10364 if (args.argc == 2) { 10365 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10366 return -1; 10367 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10368 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10369 int gain; 10370 10371 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10372 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10373 return -1; 10374 } else { 10375 leave_options.record_gain = (signed char) gain; 10376 } 10377 } 10378 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10379 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10380 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10381 } 10382 } 10383 } else { 10384 char temp[256]; 10385 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10386 if (res < 0) 10387 return res; 10388 if (ast_strlen_zero(temp)) 10389 return 0; 10390 args.argv0 = ast_strdupa(temp); 10391 } 10392 10393 res = leave_voicemail(chan, args.argv0, &leave_options); 10394 if (res == 't') { 10395 ast_play_and_wait(chan, "vm-goodbye"); 10396 res = 0; 10397 } 10398 10399 if (res == OPERATOR_EXIT) { 10400 res = 0; 10401 } 10402 10403 if (res == ERROR_LOCK_PATH) { 10404 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10405 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10406 res = 0; 10407 } 10408 10409 return res; 10410 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9614 of file app_voicemail_odbcstorage.c.
References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_goto_if_exists(), ast_log(), AST_LOG_ERROR, ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_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(), 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, and VM_SVMAIL.
09615 { 09616 /* XXX This is, admittedly, some pretty horrendous code. For some 09617 reason it just seemed a lot easier to do with GOTO's. I feel 09618 like I'm back in my GWBASIC days. XXX */ 09619 int res = -1; 09620 int cmd = 0; 09621 int valid = 0; 09622 char prefixstr[80] =""; 09623 char ext_context[256]=""; 09624 int box; 09625 int useadsi = 0; 09626 int skipuser = 0; 09627 struct vm_state vms; 09628 struct ast_vm_user *vmu = NULL, vmus; 09629 char *context = NULL; 09630 int silentexit = 0; 09631 struct ast_flags flags = { 0 }; 09632 signed char record_gain = 0; 09633 int play_auto = 0; 09634 int play_folder = 0; 09635 int in_urgent = 0; 09636 #ifdef IMAP_STORAGE 09637 int deleted = 0; 09638 #endif 09639 09640 /* Add the vm_state to the active list and keep it active */ 09641 memset(&vms, 0, sizeof(vms)); 09642 09643 vms.lastmsg = -1; 09644 09645 memset(&vmus, 0, sizeof(vmus)); 09646 09647 if (chan->_state != AST_STATE_UP) { 09648 ast_debug(1, "Before ast_answer\n"); 09649 ast_answer(chan); 09650 } 09651 09652 if (!ast_strlen_zero(data)) { 09653 char *opts[OPT_ARG_ARRAY_SIZE]; 09654 char *parse; 09655 AST_DECLARE_APP_ARGS(args, 09656 AST_APP_ARG(argv0); 09657 AST_APP_ARG(argv1); 09658 ); 09659 09660 parse = ast_strdupa(data); 09661 09662 AST_STANDARD_APP_ARGS(args, parse); 09663 09664 if (args.argc == 2) { 09665 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09666 return -1; 09667 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09668 int gain; 09669 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09670 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09671 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09672 return -1; 09673 } else { 09674 record_gain = (signed char) gain; 09675 } 09676 } else { 09677 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09678 } 09679 } 09680 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09681 play_auto = 1; 09682 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09683 /* See if it is a folder name first */ 09684 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09685 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09686 play_folder = -1; 09687 } 09688 } else { 09689 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09690 } 09691 } else { 09692 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09693 } 09694 if (play_folder > 9 || play_folder < 0) { 09695 ast_log(AST_LOG_WARNING, 09696 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09697 opts[OPT_ARG_PLAYFOLDER]); 09698 play_folder = 0; 09699 } 09700 } 09701 } else { 09702 /* old style options parsing */ 09703 while (*(args.argv0)) { 09704 if (*(args.argv0) == 's') 09705 ast_set_flag(&flags, OPT_SILENT); 09706 else if (*(args.argv0) == 'p') 09707 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09708 else 09709 break; 09710 (args.argv0)++; 09711 } 09712 09713 } 09714 09715 valid = ast_test_flag(&flags, OPT_SILENT); 09716 09717 if ((context = strchr(args.argv0, '@'))) 09718 *context++ = '\0'; 09719 09720 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09721 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09722 else 09723 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09724 09725 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09726 skipuser++; 09727 else 09728 valid = 0; 09729 } 09730 09731 if (!valid) 09732 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09733 09734 ast_debug(1, "After vm_authenticate\n"); 09735 09736 if (vms.username[0] == '*') { 09737 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09738 09739 /* user entered '*' */ 09740 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09741 res = 0; /* prevent hangup */ 09742 goto out; 09743 } 09744 } 09745 09746 if (!res) { 09747 valid = 1; 09748 if (!skipuser) 09749 vmu = &vmus; 09750 } else { 09751 res = 0; 09752 } 09753 09754 /* If ADSI is supported, setup login screen */ 09755 adsi_begin(chan, &useadsi); 09756 09757 if (!valid) { 09758 goto out; 09759 } 09760 09761 #ifdef IMAP_STORAGE 09762 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 09763 pthread_setspecific(ts_vmstate.key, &vms); 09764 09765 vms.interactive = 1; 09766 vms.updated = 1; 09767 if (vmu) 09768 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 09769 vmstate_insert(&vms); 09770 init_vm_state(&vms); 09771 #endif 09772 /* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */ 09773 if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09774 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 09775 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09776 return -1; 09777 } 09778 if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09779 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 09780 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09781 return -1; 09782 } 09783 09784 /* Set language from config to override channel language */ 09785 if (!ast_strlen_zero(vmu->language)) 09786 ast_string_field_set(chan, language, vmu->language); 09787 09788 /* Retrieve urgent, old and new message counts */ 09789 ast_debug(1, "Before open_mailbox\n"); 09790 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09791 if (res < 0) 09792 goto out; 09793 vms.oldmessages = vms.lastmsg + 1; 09794 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 09795 /* check INBOX */ 09796 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09797 if (res < 0) 09798 goto out; 09799 vms.newmessages = vms.lastmsg + 1; 09800 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 09801 /* Start in Urgent */ 09802 in_urgent = 1; 09803 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 09804 if (res < 0) 09805 goto out; 09806 vms.urgentmessages = vms.lastmsg + 1; 09807 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 09808 09809 /* Select proper mailbox FIRST!! */ 09810 if (play_auto) { 09811 if (vms.urgentmessages) { 09812 in_urgent = 1; 09813 res = open_mailbox(&vms, vmu, 11); 09814 } else { 09815 in_urgent = 0; 09816 res = open_mailbox(&vms, vmu, play_folder); 09817 } 09818 if (res < 0) 09819 goto out; 09820 09821 /* If there are no new messages, inform the user and hangup */ 09822 if (vms.lastmsg == -1) { 09823 in_urgent = 0; 09824 cmd = vm_browse_messages(chan, &vms, vmu); 09825 res = 0; 09826 goto out; 09827 } 09828 } else { 09829 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 09830 /* If we only have old messages start here */ 09831 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09832 in_urgent = 0; 09833 play_folder = 1; 09834 if (res < 0) 09835 goto out; 09836 } else if (!vms.urgentmessages && vms.newmessages) { 09837 /* If we have new messages but none are urgent */ 09838 in_urgent = 0; 09839 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09840 if (res < 0) 09841 goto out; 09842 } 09843 } 09844 09845 if (useadsi) 09846 adsi_status(chan, &vms); 09847 res = 0; 09848 09849 /* Check to see if this is a new user */ 09850 if (!strcasecmp(vmu->mailbox, vmu->password) && 09851 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 09852 if (ast_play_and_wait(chan, "vm-newuser") == -1) 09853 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 09854 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 09855 if ((cmd == 't') || (cmd == '#')) { 09856 /* Timeout */ 09857 res = 0; 09858 goto out; 09859 } else if (cmd < 0) { 09860 /* Hangup */ 09861 res = -1; 09862 goto out; 09863 } 09864 } 09865 #ifdef IMAP_STORAGE 09866 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 09867 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 09868 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 09869 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09870 } 09871 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09872 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 09873 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09874 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09875 } 09876 #endif 09877 if (play_auto) { 09878 cmd = '1'; 09879 } else { 09880 cmd = vm_intro(chan, vmu, &vms); 09881 } 09882 09883 vms.repeats = 0; 09884 vms.starting = 1; 09885 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09886 /* Run main menu */ 09887 switch (cmd) { 09888 case '1': /* First message */ 09889 vms.curmsg = 0; 09890 /* Fall through */ 09891 case '5': /* Play current message */ 09892 cmd = vm_browse_messages(chan, &vms, vmu); 09893 break; 09894 case '2': /* Change folders */ 09895 if (useadsi) 09896 adsi_folders(chan, 0, "Change to folder..."); 09897 cmd = get_folder2(chan, "vm-changeto", 0); 09898 if (cmd == '#') { 09899 cmd = 0; 09900 } else if (cmd > 0) { 09901 cmd = cmd - '0'; 09902 res = close_mailbox(&vms, vmu); 09903 if (res == ERROR_LOCK_PATH) 09904 goto out; 09905 /* If folder is not urgent, set in_urgent to zero! */ 09906 if (cmd != 11) in_urgent = 0; 09907 res = open_mailbox(&vms, vmu, cmd); 09908 if (res < 0) 09909 goto out; 09910 play_folder = cmd; 09911 cmd = 0; 09912 } 09913 if (useadsi) 09914 adsi_status2(chan, &vms); 09915 09916 if (!cmd) 09917 cmd = vm_play_folder_name(chan, vms.vmbox); 09918 09919 vms.starting = 1; 09920 break; 09921 case '3': /* Advanced options */ 09922 cmd = 0; 09923 vms.repeats = 0; 09924 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09925 switch (cmd) { 09926 case '1': /* Reply */ 09927 if (vms.lastmsg > -1 && !vms.starting) { 09928 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 09929 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 09930 res = cmd; 09931 goto out; 09932 } 09933 } else 09934 cmd = ast_play_and_wait(chan, "vm-sorry"); 09935 cmd = 't'; 09936 break; 09937 case '2': /* Callback */ 09938 if (!vms.starting) 09939 ast_verb(3, "Callback Requested\n"); 09940 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 09941 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 09942 if (cmd == 9) { 09943 silentexit = 1; 09944 goto out; 09945 } else if (cmd == ERROR_LOCK_PATH) { 09946 res = cmd; 09947 goto out; 09948 } 09949 } else 09950 cmd = ast_play_and_wait(chan, "vm-sorry"); 09951 cmd = 't'; 09952 break; 09953 case '3': /* Envelope */ 09954 if (vms.lastmsg > -1 && !vms.starting) { 09955 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 09956 if (cmd == ERROR_LOCK_PATH) { 09957 res = cmd; 09958 goto out; 09959 } 09960 } else 09961 cmd = ast_play_and_wait(chan, "vm-sorry"); 09962 cmd = 't'; 09963 break; 09964 case '4': /* Dialout */ 09965 if (!ast_strlen_zero(vmu->dialout)) { 09966 cmd = dialout(chan, vmu, NULL, vmu->dialout); 09967 if (cmd == 9) { 09968 silentexit = 1; 09969 goto out; 09970 } 09971 } else 09972 cmd = ast_play_and_wait(chan, "vm-sorry"); 09973 cmd = 't'; 09974 break; 09975 09976 case '5': /* Leave VoiceMail */ 09977 if (ast_test_flag(vmu, VM_SVMAIL)) { 09978 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 09979 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 09980 res = cmd; 09981 goto out; 09982 } 09983 } else 09984 cmd = ast_play_and_wait(chan, "vm-sorry"); 09985 cmd = 't'; 09986 break; 09987 09988 case '*': /* Return to main menu */ 09989 cmd = 't'; 09990 break; 09991 09992 default: 09993 cmd = 0; 09994 if (!vms.starting) { 09995 cmd = ast_play_and_wait(chan, "vm-toreply"); 09996 } 09997 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 09998 cmd = ast_play_and_wait(chan, "vm-tocallback"); 09999 } 10000 if (!cmd && !vms.starting) { 10001 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10002 } 10003 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10004 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10005 } 10006 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) 10007 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10008 if (!cmd) 10009 cmd = ast_play_and_wait(chan, "vm-starmain"); 10010 if (!cmd) 10011 cmd = ast_waitfordigit(chan, 6000); 10012 if (!cmd) 10013 vms.repeats++; 10014 if (vms.repeats > 3) 10015 cmd = 't'; 10016 } 10017 } 10018 if (cmd == 't') { 10019 cmd = 0; 10020 vms.repeats = 0; 10021 } 10022 break; 10023 case '4': /* Go to the previous message */ 10024 if (vms.curmsg > 0) { 10025 vms.curmsg--; 10026 cmd = play_message(chan, vmu, &vms); 10027 } else { 10028 /* Check if we were listening to new 10029 messages. If so, go to Urgent messages 10030 instead of saying "no more messages" 10031 */ 10032 if (in_urgent == 0 && vms.urgentmessages > 0) { 10033 /* Check for Urgent messages */ 10034 in_urgent = 1; 10035 res = close_mailbox(&vms, vmu); 10036 if (res == ERROR_LOCK_PATH) 10037 goto out; 10038 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10039 if (res < 0) 10040 goto out; 10041 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10042 vms.curmsg = vms.lastmsg; 10043 if (vms.lastmsg < 0) 10044 cmd = ast_play_and_wait(chan, "vm-nomore"); 10045 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10046 vms.curmsg = vms.lastmsg; 10047 cmd = play_message(chan, vmu, &vms); 10048 } else { 10049 cmd = ast_play_and_wait(chan, "vm-nomore"); 10050 } 10051 } 10052 break; 10053 case '6': /* Go to the next message */ 10054 if (vms.curmsg < vms.lastmsg) { 10055 vms.curmsg++; 10056 cmd = play_message(chan, vmu, &vms); 10057 } else { 10058 if (in_urgent && vms.newmessages > 0) { 10059 /* Check if we were listening to urgent 10060 * messages. If so, go to regular new messages 10061 * instead of saying "no more messages" 10062 */ 10063 in_urgent = 0; 10064 res = close_mailbox(&vms, vmu); 10065 if (res == ERROR_LOCK_PATH) 10066 goto out; 10067 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10068 if (res < 0) 10069 goto out; 10070 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10071 vms.curmsg = -1; 10072 if (vms.lastmsg < 0) { 10073 cmd = ast_play_and_wait(chan, "vm-nomore"); 10074 } 10075 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10076 vms.curmsg = 0; 10077 cmd = play_message(chan, vmu, &vms); 10078 } else { 10079 cmd = ast_play_and_wait(chan, "vm-nomore"); 10080 } 10081 } 10082 break; 10083 case '7': /* Delete the current message */ 10084 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10085 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10086 if (useadsi) 10087 adsi_delete(chan, &vms); 10088 if (vms.deleted[vms.curmsg]) { 10089 if (play_folder == 0) { 10090 if (in_urgent) { 10091 vms.urgentmessages--; 10092 } else { 10093 vms.newmessages--; 10094 } 10095 } 10096 else if (play_folder == 1) 10097 vms.oldmessages--; 10098 cmd = ast_play_and_wait(chan, "vm-deleted"); 10099 } else { 10100 if (play_folder == 0) { 10101 if (in_urgent) { 10102 vms.urgentmessages++; 10103 } else { 10104 vms.newmessages++; 10105 } 10106 } 10107 else if (play_folder == 1) 10108 vms.oldmessages++; 10109 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10110 } 10111 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10112 if (vms.curmsg < vms.lastmsg) { 10113 vms.curmsg++; 10114 cmd = play_message(chan, vmu, &vms); 10115 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10116 vms.curmsg = 0; 10117 cmd = play_message(chan, vmu, &vms); 10118 } else { 10119 /* Check if we were listening to urgent 10120 messages. If so, go to regular new messages 10121 instead of saying "no more messages" 10122 */ 10123 if (in_urgent == 1) { 10124 /* Check for new messages */ 10125 in_urgent = 0; 10126 res = close_mailbox(&vms, vmu); 10127 if (res == ERROR_LOCK_PATH) 10128 goto out; 10129 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10130 if (res < 0) 10131 goto out; 10132 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10133 vms.curmsg = -1; 10134 if (vms.lastmsg < 0) 10135 cmd = ast_play_and_wait(chan, "vm-nomore"); 10136 } else { 10137 cmd = ast_play_and_wait(chan, "vm-nomore"); 10138 } 10139 } 10140 } 10141 } else /* Delete not valid if we haven't selected a message */ 10142 cmd = 0; 10143 #ifdef IMAP_STORAGE 10144 deleted = 1; 10145 #endif 10146 break; 10147 10148 case '8': /* Forward the current messgae */ 10149 if (vms.lastmsg > -1) { 10150 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10151 if (cmd == ERROR_LOCK_PATH) { 10152 res = cmd; 10153 goto out; 10154 } 10155 } else { 10156 /* Check if we were listening to urgent 10157 messages. If so, go to regular new messages 10158 instead of saying "no more messages" 10159 */ 10160 if (in_urgent == 1 && vms.newmessages > 0) { 10161 /* Check for new messages */ 10162 in_urgent = 0; 10163 res = close_mailbox(&vms, vmu); 10164 if (res == ERROR_LOCK_PATH) 10165 goto out; 10166 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10167 if (res < 0) 10168 goto out; 10169 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10170 vms.curmsg = -1; 10171 if (vms.lastmsg < 0) 10172 cmd = ast_play_and_wait(chan, "vm-nomore"); 10173 } else { 10174 cmd = ast_play_and_wait(chan, "vm-nomore"); 10175 } 10176 } 10177 break; 10178 case '9': /* Save message to folder */ 10179 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10180 /* No message selected */ 10181 cmd = 0; 10182 break; 10183 } 10184 if (useadsi) 10185 adsi_folders(chan, 1, "Save to folder..."); 10186 cmd = get_folder2(chan, "vm-savefolder", 1); 10187 box = 0; /* Shut up compiler */ 10188 if (cmd == '#') { 10189 cmd = 0; 10190 break; 10191 } else if (cmd > 0) { 10192 box = cmd = cmd - '0'; 10193 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10194 if (cmd == ERROR_LOCK_PATH) { 10195 res = cmd; 10196 goto out; 10197 #ifndef IMAP_STORAGE 10198 } else if (!cmd) { 10199 vms.deleted[vms.curmsg] = 1; 10200 #endif 10201 } else { 10202 vms.deleted[vms.curmsg] = 0; 10203 vms.heard[vms.curmsg] = 0; 10204 } 10205 } 10206 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10207 if (useadsi) 10208 adsi_message(chan, &vms); 10209 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10210 if (!cmd) { 10211 cmd = ast_play_and_wait(chan, "vm-message"); 10212 if (!cmd) 10213 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10214 if (!cmd) 10215 cmd = ast_play_and_wait(chan, "vm-savedto"); 10216 if (!cmd) 10217 cmd = vm_play_folder_name(chan, vms.fn); 10218 } else { 10219 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10220 } 10221 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10222 if (vms.curmsg < vms.lastmsg) { 10223 vms.curmsg++; 10224 cmd = play_message(chan, vmu, &vms); 10225 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10226 vms.curmsg = 0; 10227 cmd = play_message(chan, vmu, &vms); 10228 } else { 10229 /* Check if we were listening to urgent 10230 messages. If so, go to regular new messages 10231 instead of saying "no more messages" 10232 */ 10233 if (in_urgent == 1 && vms.newmessages > 0) { 10234 /* Check for new messages */ 10235 in_urgent = 0; 10236 res = close_mailbox(&vms, vmu); 10237 if (res == ERROR_LOCK_PATH) 10238 goto out; 10239 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10240 if (res < 0) 10241 goto out; 10242 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10243 vms.curmsg = -1; 10244 if (vms.lastmsg < 0) 10245 cmd = ast_play_and_wait(chan, "vm-nomore"); 10246 } else { 10247 cmd = ast_play_and_wait(chan, "vm-nomore"); 10248 } 10249 } 10250 } 10251 break; 10252 case '*': /* Help */ 10253 if (!vms.starting) { 10254 cmd = ast_play_and_wait(chan, "vm-onefor"); 10255 if (!strncasecmp(chan->language, "he", 2)) { 10256 cmd = ast_play_and_wait(chan, "vm-for"); 10257 } 10258 if (!cmd) 10259 cmd = vm_play_folder_name(chan, vms.vmbox); 10260 if (!cmd) 10261 cmd = ast_play_and_wait(chan, "vm-opts"); 10262 if (!cmd) 10263 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10264 } else 10265 cmd = 0; 10266 break; 10267 case '0': /* Mailbox options */ 10268 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10269 if (useadsi) 10270 adsi_status(chan, &vms); 10271 break; 10272 default: /* Nothing */ 10273 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10274 break; 10275 } 10276 } 10277 if ((cmd == 't') || (cmd == '#')) { 10278 /* Timeout */ 10279 res = 0; 10280 } else { 10281 /* Hangup */ 10282 res = -1; 10283 } 10284 10285 out: 10286 if (res > -1) { 10287 ast_stopstream(chan); 10288 adsi_goodbye(chan); 10289 if (valid && res != OPERATOR_EXIT) { 10290 if (silentexit) 10291 res = ast_play_and_wait(chan, "vm-dialout"); 10292 else 10293 res = ast_play_and_wait(chan, "vm-goodbye"); 10294 } 10295 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10296 res = 0; 10297 } 10298 if (useadsi) 10299 ast_adsi_unload_session(chan); 10300 } 10301 if (vmu) 10302 close_mailbox(&vms, vmu); 10303 if (valid) { 10304 int new = 0, old = 0, urgent = 0; 10305 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10306 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10307 /* Urgent flag not passwd to externnotify here */ 10308 run_externnotify(vmu->context, vmu->mailbox, NULL); 10309 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10310 queue_mwi_event(ext_context, urgent, new, old); 10311 } 10312 #ifdef IMAP_STORAGE 10313 /* expunge message - use UID Expunge if supported on IMAP server*/ 10314 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10315 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10316 ast_mutex_lock(&vms.lock); 10317 #ifdef HAVE_IMAP_TK2006 10318 if (LEVELUIDPLUS (vms.mailstream)) { 10319 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10320 } else 10321 #endif 10322 mail_expunge(vms.mailstream); 10323 ast_mutex_unlock(&vms.lock); 10324 } 10325 /* before we delete the state, we should copy pertinent info 10326 * back to the persistent model */ 10327 if (vmu) { 10328 vmstate_delete(&vms); 10329 } 10330 #endif 10331 if (vmu) 10332 free_user(vmu); 10333 if (vms.deleted) 10334 ast_free(vms.deleted); 10335 if (vms.heard) 10336 ast_free(vms.heard); 10337 10338 #ifdef IMAP_STORAGE 10339 pthread_setspecific(ts_vmstate.key, NULL); 10340 #endif 10341 return res; 10342 }
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 6656 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_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, and play_record_review().
06658 { 06659 #ifdef IMAP_STORAGE 06660 int res; 06661 #endif 06662 int cmd = 0; 06663 int retries = 0, prepend_duration = 0, already_recorded = 0; 06664 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06665 char textfile[PATH_MAX]; 06666 struct ast_config *msg_cfg; 06667 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06668 #ifndef IMAP_STORAGE 06669 signed char zero_gain = 0; 06670 #endif 06671 const char *duration_str; 06672 06673 /* Must always populate duration correctly */ 06674 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06675 strcpy(textfile, msgfile); 06676 strcpy(backup, msgfile); 06677 strcpy(backup_textfile, msgfile); 06678 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06679 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06680 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06681 06682 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06683 *duration = atoi(duration_str); 06684 } else { 06685 *duration = 0; 06686 } 06687 06688 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06689 if (cmd) 06690 retries = 0; 06691 switch (cmd) { 06692 case '1': 06693 06694 #ifdef IMAP_STORAGE 06695 /* Record new intro file */ 06696 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06697 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06698 res = ast_play_and_wait(chan, INTRO); 06699 res = ast_play_and_wait(chan, "beep"); 06700 res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, record_gain, vms, flag); 06701 cmd = 't'; 06702 #else 06703 06704 /* prepend a message to the current message, update the metadata and return */ 06705 06706 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06707 strcpy(textfile, msgfile); 06708 strncat(textfile, ".txt", sizeof(textfile) - 1); 06709 *duration = 0; 06710 06711 /* if we can't read the message metadata, stop now */ 06712 if (!msg_cfg) { 06713 cmd = 0; 06714 break; 06715 } 06716 06717 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06718 if (already_recorded) { 06719 ast_filecopy(backup, msgfile, NULL); 06720 copy(backup_textfile, textfile); 06721 } 06722 else { 06723 ast_filecopy(msgfile, backup, NULL); 06724 copy(textfile,backup_textfile); 06725 } 06726 already_recorded = 1; 06727 06728 if (record_gain) 06729 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06730 06731 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence); 06732 if (cmd == 'S') { 06733 ast_filerename(backup, msgfile, NULL); 06734 } 06735 06736 if (record_gain) 06737 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06738 06739 06740 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06741 *duration = atoi(duration_str); 06742 06743 if (prepend_duration) { 06744 struct ast_category *msg_cat; 06745 /* need enough space for a maximum-length message duration */ 06746 char duration_buf[12]; 06747 06748 *duration += prepend_duration; 06749 msg_cat = ast_category_get(msg_cfg, "message"); 06750 snprintf(duration_buf, 11, "%ld", *duration); 06751 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06752 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06753 } 06754 } 06755 06756 #endif 06757 break; 06758 case '2': 06759 /* NULL out introfile so we know there is no intro! */ 06760 #ifdef IMAP_STORAGE 06761 *vms->introfn = '\0'; 06762 #endif 06763 cmd = 't'; 06764 break; 06765 case '*': 06766 cmd = '*'; 06767 break; 06768 default: 06769 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06770 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06771 if (!cmd) 06772 cmd = ast_play_and_wait(chan, "vm-starmain"); 06773 /* "press star to return to the main menu" */ 06774 if (!cmd) 06775 cmd = ast_waitfordigit(chan, 6000); 06776 if (!cmd) 06777 retries++; 06778 if (retries > 3) 06779 cmd = 't'; 06780 } 06781 } 06782 06783 if (msg_cfg) 06784 ast_config_destroy(msg_cfg); 06785 if (prepend_duration) 06786 *duration = prepend_duration; 06787 06788 if (already_recorded && cmd == -1) { 06789 /* restore original message if prepention cancelled */ 06790 ast_filerename(backup, msgfile, NULL); 06791 rename(backup_textfile, textfile); 06792 } 06793 06794 if (cmd == 't' || cmd == 'S') 06795 cmd = 0; 06796 return cmd; 06797 }
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 8955 of file app_voicemail_odbcstorage.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
08956 { 08957 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08958 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 08959 } else { /* Default to ENGLISH */ 08960 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08961 } 08962 }
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 8854 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::newmessages, vm_state::repeats, vm_state::starting, vm_state::urgentmessages, VM_MESSAGEWRAP, vm_play_folder_name(), and vm_state::vmbox.
08855 { 08856 int res = 0; 08857 /* Play instructions and wait for new command */ 08858 while (!res) { 08859 if (vms->starting) { 08860 if (vms->lastmsg > -1) { 08861 if (skipadvanced) 08862 res = ast_play_and_wait(chan, "vm-onefor-full"); 08863 else 08864 res = ast_play_and_wait(chan, "vm-onefor"); 08865 if (!res) 08866 res = vm_play_folder_name(chan, vms->vmbox); 08867 } 08868 if (!res) { 08869 if (skipadvanced) 08870 res = ast_play_and_wait(chan, "vm-opts-full"); 08871 else 08872 res = ast_play_and_wait(chan, "vm-opts"); 08873 } 08874 } else { 08875 /* Added for additional help */ 08876 if (skipadvanced) { 08877 res = ast_play_and_wait(chan, "vm-onefor-full"); 08878 if (!res) 08879 res = vm_play_folder_name(chan, vms->vmbox); 08880 res = ast_play_and_wait(chan, "vm-opts-full"); 08881 } 08882 /* Logic: 08883 * If the current message is not the first OR 08884 * if we're listening to the first new message and there are 08885 * also urgent messages, then prompt for navigation to the 08886 * previous message 08887 */ 08888 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 08889 res = ast_play_and_wait(chan, "vm-prev"); 08890 } 08891 if (!res && !skipadvanced) 08892 res = ast_play_and_wait(chan, "vm-advopts"); 08893 if (!res) 08894 res = ast_play_and_wait(chan, "vm-repeat"); 08895 /* Logic: 08896 * If we're not listening to the last message OR 08897 * we're listening to the last urgent message and there are 08898 * also new non-urgent messages, then prompt for navigation 08899 * to the next message 08900 */ 08901 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 08902 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 08903 res = ast_play_and_wait(chan, "vm-next"); 08904 } 08905 if (!res) { 08906 if (!vms->deleted[vms->curmsg]) 08907 res = ast_play_and_wait(chan, "vm-delete"); 08908 else 08909 res = ast_play_and_wait(chan, "vm-undelete"); 08910 if (!res) 08911 res = ast_play_and_wait(chan, "vm-toforward"); 08912 if (!res) 08913 res = ast_play_and_wait(chan, "vm-savemessage"); 08914 } 08915 } 08916 if (!res) { 08917 res = ast_play_and_wait(chan, "vm-helpexit"); 08918 } 08919 if (!res) 08920 res = ast_waitfordigit(chan, 6000); 08921 if (!res) { 08922 vms->repeats++; 08923 if (vms->repeats > 2) { 08924 res = 't'; 08925 } 08926 } 08927 } 08928 return res; 08929 }
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 8931 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.
08932 { 08933 int res = 0; 08934 /* Play instructions and wait for new command */ 08935 while (!res) { 08936 if (vms->lastmsg > -1) { 08937 res = ast_play_and_wait(chan, "vm-listen"); 08938 if (!res) 08939 res = vm_play_folder_name(chan, vms->vmbox); 08940 if (!res) 08941 res = ast_play_and_wait(chan, "press"); 08942 if (!res) 08943 res = ast_play_and_wait(chan, "digits/1"); 08944 } 08945 if (!res) 08946 res = ast_play_and_wait(chan, "vm-opts"); 08947 if (!res) { 08948 vms->starting = 0; 08949 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08950 } 08951 } 08952 return res; 08953 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 8792 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(), and VM_TEMPGREETWARN.
08793 { 08794 char prefile[256]; 08795 08796 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08797 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08798 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08799 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08800 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08801 ast_play_and_wait(chan, "vm-tempgreetactive"); 08802 } 08803 DISPOSE(prefile, -1); 08804 } 08805 08806 /* Play voicemail intro - syntax is different for different languages */ 08807 if (0) { 08808 return 0; 08809 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 08810 return vm_intro_cs(chan, vms); 08811 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 08812 static int deprecation_warning = 0; 08813 if (deprecation_warning++ % 10 == 0) { 08814 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 08815 } 08816 return vm_intro_cs(chan, vms); 08817 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 08818 return vm_intro_de(chan, vms); 08819 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 08820 return vm_intro_es(chan, vms); 08821 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 08822 return vm_intro_fr(chan, vms); 08823 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 08824 return vm_intro_gr(chan, vms); 08825 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 08826 return vm_intro_he(chan, vms); 08827 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 08828 return vm_intro_it(chan, vms); 08829 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 08830 return vm_intro_nl(chan, vms); 08831 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 08832 return vm_intro_no(chan, vms); 08833 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 08834 return vm_intro_pl(chan, vms); 08835 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 08836 return vm_intro_pt_BR(chan, vms); 08837 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 08838 return vm_intro_pt(chan, vms); 08839 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 08840 return vm_intro_multilang(chan, vms, "n"); 08841 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 08842 return vm_intro_se(chan, vms); 08843 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 08844 return vm_intro_multilang(chan, vms, "n"); 08845 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 08846 return vm_intro_vi(chan, vms); 08847 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08848 return vm_intro_zh(chan, vms); 08849 } else { /* Default to ENGLISH */ 08850 return vm_intro_en(chan, vms); 08851 } 08852 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8662 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.
08663 { 08664 int res; 08665 res = ast_play_and_wait(chan, "vm-youhave"); 08666 if (!res) { 08667 if (vms->newmessages) { 08668 if (vms->newmessages == 1) { 08669 res = ast_play_and_wait(chan, "digits/jednu"); 08670 } else { 08671 res = say_and_wait(chan, vms->newmessages, chan->language); 08672 } 08673 if (!res) { 08674 if ((vms->newmessages == 1)) 08675 res = ast_play_and_wait(chan, "vm-novou"); 08676 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08677 res = ast_play_and_wait(chan, "vm-nove"); 08678 if (vms->newmessages > 4) 08679 res = ast_play_and_wait(chan, "vm-novych"); 08680 } 08681 if (vms->oldmessages && !res) 08682 res = ast_play_and_wait(chan, "vm-and"); 08683 else if (!res) { 08684 if ((vms->newmessages == 1)) 08685 res = ast_play_and_wait(chan, "vm-zpravu"); 08686 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08687 res = ast_play_and_wait(chan, "vm-zpravy"); 08688 if (vms->newmessages > 4) 08689 res = ast_play_and_wait(chan, "vm-zprav"); 08690 } 08691 } 08692 if (!res && vms->oldmessages) { 08693 res = say_and_wait(chan, vms->oldmessages, chan->language); 08694 if (!res) { 08695 if ((vms->oldmessages == 1)) 08696 res = ast_play_and_wait(chan, "vm-starou"); 08697 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08698 res = ast_play_and_wait(chan, "vm-stare"); 08699 if (vms->oldmessages > 4) 08700 res = ast_play_and_wait(chan, "vm-starych"); 08701 } 08702 if (!res) { 08703 if ((vms->oldmessages == 1)) 08704 res = ast_play_and_wait(chan, "vm-zpravu"); 08705 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08706 res = ast_play_and_wait(chan, "vm-zpravy"); 08707 if (vms->oldmessages > 4) 08708 res = ast_play_and_wait(chan, "vm-zprav"); 08709 } 08710 } 08711 if (!res) { 08712 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08713 res = ast_play_and_wait(chan, "vm-no"); 08714 if (!res) 08715 res = ast_play_and_wait(chan, "vm-zpravy"); 08716 } 08717 } 08718 } 08719 return res; 08720 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8358 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.
08359 { 08360 /* Introduce messages they have */ 08361 int res; 08362 res = ast_play_and_wait(chan, "vm-youhave"); 08363 if (!res) { 08364 if (vms->newmessages) { 08365 if ((vms->newmessages == 1)) 08366 res = ast_play_and_wait(chan, "digits/1F"); 08367 else 08368 res = say_and_wait(chan, vms->newmessages, chan->language); 08369 if (!res) 08370 res = ast_play_and_wait(chan, "vm-INBOX"); 08371 if (vms->oldmessages && !res) 08372 res = ast_play_and_wait(chan, "vm-and"); 08373 else if (!res) { 08374 if ((vms->newmessages == 1)) 08375 res = ast_play_and_wait(chan, "vm-message"); 08376 else 08377 res = ast_play_and_wait(chan, "vm-messages"); 08378 } 08379 08380 } 08381 if (!res && vms->oldmessages) { 08382 if (vms->oldmessages == 1) 08383 res = ast_play_and_wait(chan, "digits/1F"); 08384 else 08385 res = say_and_wait(chan, vms->oldmessages, chan->language); 08386 if (!res) 08387 res = ast_play_and_wait(chan, "vm-Old"); 08388 if (!res) { 08389 if (vms->oldmessages == 1) 08390 res = ast_play_and_wait(chan, "vm-message"); 08391 else 08392 res = ast_play_and_wait(chan, "vm-messages"); 08393 } 08394 } 08395 if (!res) { 08396 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08397 res = ast_play_and_wait(chan, "vm-no"); 08398 if (!res) 08399 res = ast_play_and_wait(chan, "vm-messages"); 08400 } 08401 } 08402 } 08403 return res; 08404 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8107 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.
08108 { 08109 int res; 08110 08111 /* Introduce messages they have */ 08112 res = ast_play_and_wait(chan, "vm-youhave"); 08113 if (!res) { 08114 if (vms->urgentmessages) { 08115 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08116 if (!res) 08117 res = ast_play_and_wait(chan, "vm-Urgent"); 08118 if ((vms->oldmessages || vms->newmessages) && !res) { 08119 res = ast_play_and_wait(chan, "vm-and"); 08120 } else if (!res) { 08121 if ((vms->urgentmessages == 1)) 08122 res = ast_play_and_wait(chan, "vm-message"); 08123 else 08124 res = ast_play_and_wait(chan, "vm-messages"); 08125 } 08126 } 08127 if (vms->newmessages) { 08128 res = say_and_wait(chan, vms->newmessages, chan->language); 08129 if (!res) 08130 res = ast_play_and_wait(chan, "vm-INBOX"); 08131 if (vms->oldmessages && !res) 08132 res = ast_play_and_wait(chan, "vm-and"); 08133 else if (!res) { 08134 if ((vms->newmessages == 1)) 08135 res = ast_play_and_wait(chan, "vm-message"); 08136 else 08137 res = ast_play_and_wait(chan, "vm-messages"); 08138 } 08139 08140 } 08141 if (!res && vms->oldmessages) { 08142 res = say_and_wait(chan, vms->oldmessages, chan->language); 08143 if (!res) 08144 res = ast_play_and_wait(chan, "vm-Old"); 08145 if (!res) { 08146 if (vms->oldmessages == 1) 08147 res = ast_play_and_wait(chan, "vm-message"); 08148 else 08149 res = ast_play_and_wait(chan, "vm-messages"); 08150 } 08151 } 08152 if (!res) { 08153 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08154 res = ast_play_and_wait(chan, "vm-no"); 08155 if (!res) 08156 res = ast_play_and_wait(chan, "vm-messages"); 08157 } 08158 } 08159 } 08160 return res; 08161 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8407 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.
08408 { 08409 /* Introduce messages they have */ 08410 int res; 08411 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08412 res = ast_play_and_wait(chan, "vm-youhaveno"); 08413 if (!res) 08414 res = ast_play_and_wait(chan, "vm-messages"); 08415 } else { 08416 res = ast_play_and_wait(chan, "vm-youhave"); 08417 } 08418 if (!res) { 08419 if (vms->newmessages) { 08420 if (!res) { 08421 if ((vms->newmessages == 1)) { 08422 res = ast_play_and_wait(chan, "digits/1M"); 08423 if (!res) 08424 res = ast_play_and_wait(chan, "vm-message"); 08425 if (!res) 08426 res = ast_play_and_wait(chan, "vm-INBOXs"); 08427 } else { 08428 res = say_and_wait(chan, vms->newmessages, chan->language); 08429 if (!res) 08430 res = ast_play_and_wait(chan, "vm-messages"); 08431 if (!res) 08432 res = ast_play_and_wait(chan, "vm-INBOX"); 08433 } 08434 } 08435 if (vms->oldmessages && !res) 08436 res = ast_play_and_wait(chan, "vm-and"); 08437 } 08438 if (vms->oldmessages) { 08439 if (!res) { 08440 if (vms->oldmessages == 1) { 08441 res = ast_play_and_wait(chan, "digits/1M"); 08442 if (!res) 08443 res = ast_play_and_wait(chan, "vm-message"); 08444 if (!res) 08445 res = ast_play_and_wait(chan, "vm-Olds"); 08446 } else { 08447 res = say_and_wait(chan, vms->oldmessages, chan->language); 08448 if (!res) 08449 res = ast_play_and_wait(chan, "vm-messages"); 08450 if (!res) 08451 res = ast_play_and_wait(chan, "vm-Old"); 08452 } 08453 } 08454 } 08455 } 08456 return res; 08457 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8505 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.
08506 { 08507 /* Introduce messages they have */ 08508 int res; 08509 res = ast_play_and_wait(chan, "vm-youhave"); 08510 if (!res) { 08511 if (vms->newmessages) { 08512 res = say_and_wait(chan, vms->newmessages, chan->language); 08513 if (!res) 08514 res = ast_play_and_wait(chan, "vm-INBOX"); 08515 if (vms->oldmessages && !res) 08516 res = ast_play_and_wait(chan, "vm-and"); 08517 else if (!res) { 08518 if ((vms->newmessages == 1)) 08519 res = ast_play_and_wait(chan, "vm-message"); 08520 else 08521 res = ast_play_and_wait(chan, "vm-messages"); 08522 } 08523 08524 } 08525 if (!res && vms->oldmessages) { 08526 res = say_and_wait(chan, vms->oldmessages, chan->language); 08527 if (!res) 08528 res = ast_play_and_wait(chan, "vm-Old"); 08529 if (!res) { 08530 if (vms->oldmessages == 1) 08531 res = ast_play_and_wait(chan, "vm-message"); 08532 else 08533 res = ast_play_and_wait(chan, "vm-messages"); 08534 } 08535 } 08536 if (!res) { 08537 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08538 res = ast_play_and_wait(chan, "vm-no"); 08539 if (!res) 08540 res = ast_play_and_wait(chan, "vm-messages"); 08541 } 08542 } 08543 } 08544 return res; 08545 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7906 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.
07907 { 07908 int res = 0; 07909 07910 if (vms->newmessages) { 07911 res = ast_play_and_wait(chan, "vm-youhave"); 07912 if (!res) 07913 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 07914 if (!res) { 07915 if ((vms->newmessages == 1)) { 07916 res = ast_play_and_wait(chan, "vm-INBOX"); 07917 if (!res) 07918 res = ast_play_and_wait(chan, "vm-message"); 07919 } else { 07920 res = ast_play_and_wait(chan, "vm-INBOXs"); 07921 if (!res) 07922 res = ast_play_and_wait(chan, "vm-messages"); 07923 } 07924 } 07925 } else if (vms->oldmessages){ 07926 res = ast_play_and_wait(chan, "vm-youhave"); 07927 if (!res) 07928 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 07929 if ((vms->oldmessages == 1)){ 07930 res = ast_play_and_wait(chan, "vm-Old"); 07931 if (!res) 07932 res = ast_play_and_wait(chan, "vm-message"); 07933 } else { 07934 res = ast_play_and_wait(chan, "vm-Olds"); 07935 if (!res) 07936 res = ast_play_and_wait(chan, "vm-messages"); 07937 } 07938 } else if (!vms->oldmessages && !vms->newmessages) 07939 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 07940 return res; 07941 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8040 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.
08041 { 08042 int res = 0; 08043 08044 /* Introduce messages they have */ 08045 if (!res) { 08046 if ((vms->newmessages) || (vms->oldmessages)) { 08047 res = ast_play_and_wait(chan, "vm-youhave"); 08048 } 08049 /* 08050 * The word "shtei" refers to the number 2 in hebrew when performing a count 08051 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08052 * an element, this is one of them. 08053 */ 08054 if (vms->newmessages) { 08055 if (!res) { 08056 if (vms->newmessages == 1) { 08057 res = ast_play_and_wait(chan, "vm-INBOX1"); 08058 } else { 08059 if (vms->newmessages == 2) { 08060 res = ast_play_and_wait(chan, "vm-shtei"); 08061 } else { 08062 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08063 } 08064 res = ast_play_and_wait(chan, "vm-INBOX"); 08065 } 08066 } 08067 if (vms->oldmessages && !res) { 08068 res = ast_play_and_wait(chan, "vm-and"); 08069 if (vms->oldmessages == 1) { 08070 res = ast_play_and_wait(chan, "vm-Old1"); 08071 } else { 08072 if (vms->oldmessages == 2) { 08073 res = ast_play_and_wait(chan, "vm-shtei"); 08074 } else { 08075 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08076 } 08077 res = ast_play_and_wait(chan, "vm-Old"); 08078 } 08079 } 08080 } 08081 if (!res && vms->oldmessages && !vms->newmessages) { 08082 if (!res) { 08083 if (vms->oldmessages == 1) { 08084 res = ast_play_and_wait(chan, "vm-Old1"); 08085 } else { 08086 if (vms->oldmessages == 2) { 08087 res = ast_play_and_wait(chan, "vm-shtei"); 08088 } else { 08089 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08090 } 08091 res = ast_play_and_wait(chan, "vm-Old"); 08092 } 08093 } 08094 } 08095 if (!res) { 08096 if (!vms->oldmessages && !vms->newmessages) { 08097 if (!res) { 08098 res = ast_play_and_wait(chan, "vm-nomessages"); 08099 } 08100 } 08101 } 08102 } 08103 return res; 08104 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8164 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.
08165 { 08166 /* Introduce messages they have */ 08167 int res; 08168 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08169 res = ast_play_and_wait(chan, "vm-no") || 08170 ast_play_and_wait(chan, "vm-message"); 08171 else 08172 res = ast_play_and_wait(chan, "vm-youhave"); 08173 if (!res && vms->newmessages) { 08174 res = (vms->newmessages == 1) ? 08175 ast_play_and_wait(chan, "digits/un") || 08176 ast_play_and_wait(chan, "vm-nuovo") || 08177 ast_play_and_wait(chan, "vm-message") : 08178 /* 2 or more new messages */ 08179 say_and_wait(chan, vms->newmessages, chan->language) || 08180 ast_play_and_wait(chan, "vm-nuovi") || 08181 ast_play_and_wait(chan, "vm-messages"); 08182 if (!res && vms->oldmessages) 08183 res = ast_play_and_wait(chan, "vm-and"); 08184 } 08185 if (!res && vms->oldmessages) { 08186 res = (vms->oldmessages == 1) ? 08187 ast_play_and_wait(chan, "digits/un") || 08188 ast_play_and_wait(chan, "vm-vecchio") || 08189 ast_play_and_wait(chan, "vm-message") : 08190 /* 2 or more old messages */ 08191 say_and_wait(chan, vms->oldmessages, chan->language) || 08192 ast_play_and_wait(chan, "vm-vecchi") || 08193 ast_play_and_wait(chan, "vm-messages"); 08194 } 08195 return res; 08196 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8000 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.
08001 { 08002 int res; 08003 int lastnum = 0; 08004 08005 res = ast_play_and_wait(chan, "vm-youhave"); 08006 08007 if (!res && vms->newmessages) { 08008 lastnum = vms->newmessages; 08009 08010 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08011 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08012 } 08013 08014 if (!res && vms->oldmessages) { 08015 res = ast_play_and_wait(chan, "vm-and"); 08016 } 08017 } 08018 08019 if (!res && vms->oldmessages) { 08020 lastnum = vms->oldmessages; 08021 08022 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08023 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08024 } 08025 } 08026 08027 if (!res) { 08028 if (lastnum == 0) { 08029 res = ast_play_and_wait(chan, "vm-no"); 08030 } 08031 if (!res) { 08032 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08033 } 08034 } 08035 08036 return res; 08037 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8548 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.
08549 { 08550 /* Introduce messages they have */ 08551 int res; 08552 res = ast_play_and_wait(chan, "vm-youhave"); 08553 if (!res) { 08554 if (vms->newmessages) { 08555 res = say_and_wait(chan, vms->newmessages, chan->language); 08556 if (!res) { 08557 if (vms->newmessages == 1) 08558 res = ast_play_and_wait(chan, "vm-INBOXs"); 08559 else 08560 res = ast_play_and_wait(chan, "vm-INBOX"); 08561 } 08562 if (vms->oldmessages && !res) 08563 res = ast_play_and_wait(chan, "vm-and"); 08564 else if (!res) { 08565 if ((vms->newmessages == 1)) 08566 res = ast_play_and_wait(chan, "vm-message"); 08567 else 08568 res = ast_play_and_wait(chan, "vm-messages"); 08569 } 08570 08571 } 08572 if (!res && vms->oldmessages) { 08573 res = say_and_wait(chan, vms->oldmessages, chan->language); 08574 if (!res) { 08575 if (vms->oldmessages == 1) 08576 res = ast_play_and_wait(chan, "vm-Olds"); 08577 else 08578 res = ast_play_and_wait(chan, "vm-Old"); 08579 } 08580 if (!res) { 08581 if (vms->oldmessages == 1) 08582 res = ast_play_and_wait(chan, "vm-message"); 08583 else 08584 res = ast_play_and_wait(chan, "vm-messages"); 08585 } 08586 } 08587 if (!res) { 08588 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08589 res = ast_play_and_wait(chan, "vm-no"); 08590 if (!res) 08591 res = ast_play_and_wait(chan, "vm-messages"); 08592 } 08593 } 08594 } 08595 return res; 08596 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8314 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.
08315 { 08316 /* Introduce messages they have */ 08317 int res; 08318 08319 res = ast_play_and_wait(chan, "vm-youhave"); 08320 if (res) 08321 return res; 08322 08323 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08324 res = ast_play_and_wait(chan, "vm-no"); 08325 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08326 return res; 08327 } 08328 08329 if (vms->newmessages) { 08330 if ((vms->newmessages == 1)) { 08331 res = ast_play_and_wait(chan, "digits/1"); 08332 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08333 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08334 } else { 08335 res = say_and_wait(chan, vms->newmessages, chan->language); 08336 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08337 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08338 } 08339 if (!res && vms->oldmessages) 08340 res = ast_play_and_wait(chan, "vm-and"); 08341 } 08342 if (!res && vms->oldmessages) { 08343 if (vms->oldmessages == 1) { 08344 res = ast_play_and_wait(chan, "digits/1"); 08345 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08346 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08347 } else { 08348 res = say_and_wait(chan, vms->oldmessages, chan->language); 08349 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08350 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08351 } 08352 } 08353 08354 return res; 08355 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8199 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08200 { 08201 /* Introduce messages they have */ 08202 int res; 08203 div_t num; 08204 08205 if (!vms->oldmessages && !vms->newmessages) { 08206 res = ast_play_and_wait(chan, "vm-no"); 08207 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08208 return res; 08209 } else { 08210 res = ast_play_and_wait(chan, "vm-youhave"); 08211 } 08212 08213 if (vms->newmessages) { 08214 num = div(vms->newmessages, 10); 08215 if (vms->newmessages == 1) { 08216 res = ast_play_and_wait(chan, "digits/1-a"); 08217 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08218 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08219 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08220 if (num.rem == 2) { 08221 if (!num.quot) { 08222 res = ast_play_and_wait(chan, "digits/2-ie"); 08223 } else { 08224 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08225 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08226 } 08227 } else { 08228 res = say_and_wait(chan, vms->newmessages, chan->language); 08229 } 08230 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08231 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08232 } else { 08233 res = say_and_wait(chan, vms->newmessages, chan->language); 08234 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08235 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08236 } 08237 if (!res && vms->oldmessages) 08238 res = ast_play_and_wait(chan, "vm-and"); 08239 } 08240 if (!res && vms->oldmessages) { 08241 num = div(vms->oldmessages, 10); 08242 if (vms->oldmessages == 1) { 08243 res = ast_play_and_wait(chan, "digits/1-a"); 08244 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08245 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08246 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08247 if (num.rem == 2) { 08248 if (!num.quot) { 08249 res = ast_play_and_wait(chan, "digits/2-ie"); 08250 } else { 08251 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08252 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08253 } 08254 } else { 08255 res = say_and_wait(chan, vms->oldmessages, chan->language); 08256 } 08257 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08258 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08259 } else { 08260 res = say_and_wait(chan, vms->oldmessages, chan->language); 08261 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08262 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08263 } 08264 } 08265 08266 return res; 08267 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8599 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.
08600 { 08601 /* Introduce messages they have */ 08602 int res; 08603 res = ast_play_and_wait(chan, "vm-youhave"); 08604 if (!res) { 08605 if (vms->newmessages) { 08606 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08607 if (!res) { 08608 if ((vms->newmessages == 1)) { 08609 res = ast_play_and_wait(chan, "vm-message"); 08610 if (!res) 08611 res = ast_play_and_wait(chan, "vm-INBOXs"); 08612 } else { 08613 res = ast_play_and_wait(chan, "vm-messages"); 08614 if (!res) 08615 res = ast_play_and_wait(chan, "vm-INBOX"); 08616 } 08617 } 08618 if (vms->oldmessages && !res) 08619 res = ast_play_and_wait(chan, "vm-and"); 08620 } 08621 if (!res && vms->oldmessages) { 08622 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08623 if (!res) { 08624 if (vms->oldmessages == 1) { 08625 res = ast_play_and_wait(chan, "vm-message"); 08626 if (!res) 08627 res = ast_play_and_wait(chan, "vm-Olds"); 08628 } else { 08629 res = ast_play_and_wait(chan, "vm-messages"); 08630 if (!res) 08631 res = ast_play_and_wait(chan, "vm-Old"); 08632 } 08633 } 08634 } 08635 if (!res) { 08636 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08637 res = ast_play_and_wait(chan, "vm-no"); 08638 if (!res) 08639 res = ast_play_and_wait(chan, "vm-messages"); 08640 } 08641 } 08642 } 08643 return res; 08644 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8460 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.
08460 { 08461 /* Introduce messages they have */ 08462 int res; 08463 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08464 res = ast_play_and_wait(chan, "vm-nomessages"); 08465 return res; 08466 } else { 08467 res = ast_play_and_wait(chan, "vm-youhave"); 08468 } 08469 if (vms->newmessages) { 08470 if (!res) 08471 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08472 if ((vms->newmessages == 1)) { 08473 if (!res) 08474 res = ast_play_and_wait(chan, "vm-message"); 08475 if (!res) 08476 res = ast_play_and_wait(chan, "vm-INBOXs"); 08477 } else { 08478 if (!res) 08479 res = ast_play_and_wait(chan, "vm-messages"); 08480 if (!res) 08481 res = ast_play_and_wait(chan, "vm-INBOX"); 08482 } 08483 if (vms->oldmessages && !res) 08484 res = ast_play_and_wait(chan, "vm-and"); 08485 } 08486 if (vms->oldmessages) { 08487 if (!res) 08488 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08489 if (vms->oldmessages == 1) { 08490 if (!res) 08491 res = ast_play_and_wait(chan, "vm-message"); 08492 if (!res) 08493 res = ast_play_and_wait(chan, "vm-Olds"); 08494 } else { 08495 if (!res) 08496 res = ast_play_and_wait(chan, "vm-messages"); 08497 if (!res) 08498 res = ast_play_and_wait(chan, "vm-Old"); 08499 } 08500 } 08501 return res; 08502 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8270 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.
08271 { 08272 /* Introduce messages they have */ 08273 int res; 08274 08275 res = ast_play_and_wait(chan, "vm-youhave"); 08276 if (res) 08277 return res; 08278 08279 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08280 res = ast_play_and_wait(chan, "vm-no"); 08281 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08282 return res; 08283 } 08284 08285 if (vms->newmessages) { 08286 if ((vms->newmessages == 1)) { 08287 res = ast_play_and_wait(chan, "digits/ett"); 08288 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08289 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08290 } else { 08291 res = say_and_wait(chan, vms->newmessages, chan->language); 08292 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08293 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08294 } 08295 if (!res && vms->oldmessages) 08296 res = ast_play_and_wait(chan, "vm-and"); 08297 } 08298 if (!res && vms->oldmessages) { 08299 if (vms->oldmessages == 1) { 08300 res = ast_play_and_wait(chan, "digits/ett"); 08301 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08302 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08303 } else { 08304 res = say_and_wait(chan, vms->oldmessages, chan->language); 08305 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08306 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08307 } 08308 } 08309 08310 return res; 08311 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8762 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08763 { 08764 int res; 08765 08766 /* Introduce messages they have */ 08767 res = ast_play_and_wait(chan, "vm-youhave"); 08768 if (!res) { 08769 if (vms->newmessages) { 08770 res = say_and_wait(chan, vms->newmessages, chan->language); 08771 if (!res) 08772 res = ast_play_and_wait(chan, "vm-INBOX"); 08773 if (vms->oldmessages && !res) 08774 res = ast_play_and_wait(chan, "vm-and"); 08775 } 08776 if (!res && vms->oldmessages) { 08777 res = say_and_wait(chan, vms->oldmessages, chan->language); 08778 if (!res) 08779 res = ast_play_and_wait(chan, "vm-Old"); 08780 } 08781 if (!res) { 08782 if (!vms->oldmessages && !vms->newmessages) { 08783 res = ast_play_and_wait(chan, "vm-no"); 08784 if (!res) 08785 res = ast_play_and_wait(chan, "vm-message"); 08786 } 08787 } 08788 } 08789 return res; 08790 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8723 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08724 { 08725 int res; 08726 /* Introduce messages they have */ 08727 res = ast_play_and_wait(chan, "vm-you"); 08728 08729 if (!res && vms->newmessages) { 08730 res = ast_play_and_wait(chan, "vm-have"); 08731 if (!res) 08732 res = say_and_wait(chan, vms->newmessages, chan->language); 08733 if (!res) 08734 res = ast_play_and_wait(chan, "vm-tong"); 08735 if (!res) 08736 res = ast_play_and_wait(chan, "vm-INBOX"); 08737 if (vms->oldmessages && !res) 08738 res = ast_play_and_wait(chan, "vm-and"); 08739 else if (!res) 08740 res = ast_play_and_wait(chan, "vm-messages"); 08741 } 08742 if (!res && vms->oldmessages) { 08743 res = ast_play_and_wait(chan, "vm-have"); 08744 if (!res) 08745 res = say_and_wait(chan, vms->oldmessages, chan->language); 08746 if (!res) 08747 res = ast_play_and_wait(chan, "vm-tong"); 08748 if (!res) 08749 res = ast_play_and_wait(chan, "vm-Old"); 08750 if (!res) 08751 res = ast_play_and_wait(chan, "vm-messages"); 08752 } 08753 if (!res && !vms->oldmessages && !vms->newmessages) { 08754 res = ast_play_and_wait(chan, "vm-haveno"); 08755 if (!res) 08756 res = ast_play_and_wait(chan, "vm-messages"); 08757 } 08758 return res; 08759 }
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 3180 of file app_voicemail_odbcstorage.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03181 { 03182 switch (ast_lock_path(path)) { 03183 case AST_LOCK_TIMEOUT: 03184 return -1; 03185 default: 03186 return 0; 03187 } 03188 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1586 of file app_voicemail_odbcstorage.c.
References VOICEMAIL_FILE_MODE.
01587 { 01588 FILE *p = NULL; 01589 int pfd = mkstemp(template); 01590 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01591 if (pfd > -1) { 01592 p = fdopen(pfd, "w+"); 01593 if (!p) { 01594 close(pfd); 01595 pfd = -1; 01596 } 01597 } 01598 return p; 01599 }
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 8965 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, check_password(), play_record_review(), 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, and vm_reenterpassword.
08966 { 08967 int cmd = 0; 08968 int duration = 0; 08969 int tries = 0; 08970 char newpassword[80] = ""; 08971 char newpassword2[80] = ""; 08972 char prefile[PATH_MAX] = ""; 08973 unsigned char buf[256]; 08974 int bytes = 0; 08975 08976 if (ast_adsi_available(chan)) { 08977 bytes += adsi_logo(buf + bytes); 08978 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 08979 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08980 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08981 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08982 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08983 } 08984 08985 /* First, have the user change their password 08986 so they won't get here again */ 08987 for (;;) { 08988 newpassword[1] = '\0'; 08989 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08990 if (cmd == '#') 08991 newpassword[0] = '\0'; 08992 if (cmd < 0 || cmd == 't' || cmd == '#') 08993 return cmd; 08994 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 08995 if (cmd < 0 || cmd == 't' || cmd == '#') 08996 return cmd; 08997 cmd = check_password(vmu, newpassword); /* perform password validation */ 08998 if (cmd != 0) { 08999 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09000 cmd = ast_play_and_wait(chan, vm_invalid_password); 09001 } else { 09002 newpassword2[1] = '\0'; 09003 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09004 if (cmd == '#') 09005 newpassword2[0] = '\0'; 09006 if (cmd < 0 || cmd == 't' || cmd == '#') 09007 return cmd; 09008 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09009 if (cmd < 0 || cmd == 't' || cmd == '#') 09010 return cmd; 09011 if (!strcmp(newpassword, newpassword2)) 09012 break; 09013 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09014 cmd = ast_play_and_wait(chan, vm_mismatch); 09015 } 09016 if (++tries == 3) 09017 return -1; 09018 if (cmd != 0) { 09019 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09020 } 09021 } 09022 if (pwdchange & PWDCHANGE_INTERNAL) 09023 vm_change_password(vmu, newpassword); 09024 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09025 vm_change_password_shell(vmu, newpassword); 09026 09027 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09028 cmd = ast_play_and_wait(chan, vm_passchanged); 09029 09030 /* If forcename is set, have the user record their name */ 09031 if (ast_test_flag(vmu, VM_FORCENAME)) { 09032 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09033 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09034 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09035 if (cmd < 0 || cmd == 't' || cmd == '#') 09036 return cmd; 09037 } 09038 } 09039 09040 /* If forcegreetings is set, have the user record their greetings */ 09041 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09042 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09043 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09044 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09045 if (cmd < 0 || cmd == 't' || cmd == '#') 09046 return cmd; 09047 } 09048 09049 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09050 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09051 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09052 if (cmd < 0 || cmd == 't' || cmd == '#') 09053 return cmd; 09054 } 09055 } 09056 09057 return cmd; 09058 }
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 9060 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_waitfordigit(), check_password(), ast_vm_user::context, DISPOSE, ast_vm_user::password, play_record_review(), 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, and vm_tempgreeting().
09061 { 09062 int cmd = 0; 09063 int retries = 0; 09064 int duration = 0; 09065 char newpassword[80] = ""; 09066 char newpassword2[80] = ""; 09067 char prefile[PATH_MAX] = ""; 09068 unsigned char buf[256]; 09069 int bytes = 0; 09070 09071 if (ast_adsi_available(chan)) { 09072 bytes += adsi_logo(buf + bytes); 09073 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09074 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09075 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09076 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09077 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09078 } 09079 while ((cmd >= 0) && (cmd != 't')) { 09080 if (cmd) 09081 retries = 0; 09082 switch (cmd) { 09083 case '1': /* Record your unavailable message */ 09084 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09085 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09086 break; 09087 case '2': /* Record your busy message */ 09088 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09089 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09090 break; 09091 case '3': /* Record greeting */ 09092 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09093 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09094 break; 09095 case '4': /* manage the temporary greeting */ 09096 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09097 break; 09098 case '5': /* change password */ 09099 if (vmu->password[0] == '-') { 09100 cmd = ast_play_and_wait(chan, "vm-no"); 09101 break; 09102 } 09103 newpassword[1] = '\0'; 09104 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09105 if (cmd == '#') 09106 newpassword[0] = '\0'; 09107 else { 09108 if (cmd < 0) 09109 break; 09110 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09111 break; 09112 } 09113 } 09114 cmd = check_password(vmu, newpassword); /* perform password validation */ 09115 if (cmd != 0) { 09116 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09117 cmd = ast_play_and_wait(chan, vm_invalid_password); 09118 if (!cmd) { 09119 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09120 } 09121 break; 09122 } 09123 newpassword2[1] = '\0'; 09124 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09125 if (cmd == '#') 09126 newpassword2[0] = '\0'; 09127 else { 09128 if (cmd < 0) 09129 break; 09130 09131 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09132 break; 09133 } 09134 } 09135 if (strcmp(newpassword, newpassword2)) { 09136 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09137 cmd = ast_play_and_wait(chan, vm_mismatch); 09138 if (!cmd) { 09139 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09140 } 09141 break; 09142 } 09143 if (pwdchange & PWDCHANGE_INTERNAL) 09144 vm_change_password(vmu, newpassword); 09145 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09146 vm_change_password_shell(vmu, newpassword); 09147 09148 ast_debug(1, "User %s set password to %s of length %d\n", 09149 vms->username, newpassword, (int) strlen(newpassword)); 09150 cmd = ast_play_and_wait(chan, vm_passchanged); 09151 break; 09152 case '*': 09153 cmd = 't'; 09154 break; 09155 default: 09156 cmd = 0; 09157 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09158 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09159 if (ast_fileexists(prefile, NULL, NULL)) { 09160 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09161 } 09162 DISPOSE(prefile, -1); 09163 if (!cmd) { 09164 cmd = ast_play_and_wait(chan, "vm-options"); 09165 } 09166 if (!cmd) { 09167 cmd = ast_waitfordigit(chan, 6000); 09168 } 09169 if (!cmd) { 09170 retries++; 09171 } 09172 if (retries > 3) { 09173 cmd = 't'; 09174 } 09175 } 09176 } 09177 if (cmd == 't') 09178 cmd = 0; 09179 return cmd; 09180 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 7869 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().
07870 { 07871 int cmd; 07872 07873 if ( !strncasecmp(chan->language, "it", 2) || 07874 !strncasecmp(chan->language, "es", 2) || 07875 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 07876 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07877 return cmd ? cmd : ast_play_and_wait(chan, box); 07878 } else if (!strncasecmp(chan->language, "gr", 2)) { 07879 return vm_play_folder_name_gr(chan, box); 07880 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 07881 return ast_play_and_wait(chan, box); 07882 } else if (!strncasecmp(chan->language, "pl", 2)) { 07883 return vm_play_folder_name_pl(chan, box); 07884 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 07885 return vm_play_folder_name_ua(chan, box); 07886 } else if (!strncasecmp(chan->language, "vi", 2)) { 07887 return ast_play_and_wait(chan, box); 07888 } else { /* Default English */ 07889 cmd = ast_play_and_wait(chan, box); 07890 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07891 } 07892 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7822 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
07823 { 07824 int cmd; 07825 char *buf; 07826 07827 buf = alloca(strlen(box) + 2); 07828 strcpy(buf, box); 07829 strcat(buf, "s"); 07830 07831 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 07832 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 07833 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07834 } else { 07835 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07836 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 07837 } 07838 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7840 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
07841 { 07842 int cmd; 07843 07844 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 07845 if (!strcasecmp(box, "vm-INBOX")) 07846 cmd = ast_play_and_wait(chan, "vm-new-e"); 07847 else 07848 cmd = ast_play_and_wait(chan, "vm-old-e"); 07849 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07850 } else { 07851 cmd = ast_play_and_wait(chan, "vm-messages"); 07852 return cmd ? cmd : ast_play_and_wait(chan, box); 07853 } 07854 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7856 of file app_voicemail_odbcstorage.c.
References ast_play_and_wait().
07857 { 07858 int cmd; 07859 07860 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 07861 cmd = ast_play_and_wait(chan, "vm-messages"); 07862 return cmd ? cmd : ast_play_and_wait(chan, box); 07863 } else { 07864 cmd = ast_play_and_wait(chan, box); 07865 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07866 } 07867 }
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 9198 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_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.
09199 { 09200 int cmd = 0; 09201 int retries = 0; 09202 int duration = 0; 09203 char prefile[PATH_MAX] = ""; 09204 unsigned char buf[256]; 09205 int bytes = 0; 09206 09207 if (ast_adsi_available(chan)) { 09208 bytes += adsi_logo(buf + bytes); 09209 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09210 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09211 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09212 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09213 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09214 } 09215 09216 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09217 while ((cmd >= 0) && (cmd != 't')) { 09218 if (cmd) 09219 retries = 0; 09220 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09221 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09222 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09223 cmd = 't'; 09224 } else { 09225 switch (cmd) { 09226 case '1': 09227 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09228 break; 09229 case '2': 09230 DELETE(prefile, -1, prefile, vmu); 09231 ast_play_and_wait(chan, "vm-tempremoved"); 09232 cmd = 't'; 09233 break; 09234 case '*': 09235 cmd = 't'; 09236 break; 09237 default: 09238 cmd = ast_play_and_wait(chan, 09239 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09240 "vm-tempgreeting2" : "vm-tempgreeting"); 09241 if (!cmd) 09242 cmd = ast_waitfordigit(chan, 6000); 09243 if (!cmd) 09244 retries++; 09245 if (retries > 3) 09246 cmd = 't'; 09247 } 09248 } 09249 DISPOSE(prefile, -1); 09250 } 09251 if (cmd == 't') 09252 cmd = 0; 09253 return cmd; 09254 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11086 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().
11088 { 11089 struct ast_vm_user *user; 11090 11091 AST_LIST_LOCK(&users); 11092 AST_LIST_TRAVERSE(&users, user, list) { 11093 vm_users_data_provider_get_helper(search, data_root, user); 11094 } 11095 AST_LIST_UNLOCK(&users); 11096 11097 return 0; 11098 }
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 11039 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.
11041 { 11042 struct ast_data *data_user, *data_zone; 11043 struct ast_data *data_state; 11044 struct vm_zone *zone = NULL; 11045 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11046 char ext_context[256] = ""; 11047 11048 data_user = ast_data_add_node(data_root, "user"); 11049 if (!data_user) { 11050 return -1; 11051 } 11052 11053 ast_data_add_structure(ast_vm_user, data_user, user); 11054 11055 AST_LIST_LOCK(&zones); 11056 AST_LIST_TRAVERSE(&zones, zone, list) { 11057 if (!strcmp(zone->name, user->zonetag)) { 11058 break; 11059 } 11060 } 11061 AST_LIST_UNLOCK(&zones); 11062 11063 /* state */ 11064 data_state = ast_data_add_node(data_user, "state"); 11065 if (!data_state) { 11066 return -1; 11067 } 11068 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11069 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11070 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11071 ast_data_add_int(data_state, "newmsg", newmsg); 11072 ast_data_add_int(data_state, "oldmsg", oldmsg); 11073 11074 if (zone) { 11075 data_zone = ast_data_add_node(data_user, "zone"); 11076 ast_data_add_structure(vm_zone, data_zone, zone); 11077 } 11078 11079 if (!ast_data_search_match(search, data_user)) { 11080 ast_data_remove_node(data_root, data_user); 11081 } 11082 11083 return 0; 11084 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10725 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().
10726 { 10727 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 10728 struct ast_vm_user vmus; 10729 char *options = NULL; 10730 int silent = 0, skipuser = 0; 10731 int res = -1; 10732 10733 if (data) { 10734 s = ast_strdupa(data); 10735 user = strsep(&s, ","); 10736 options = strsep(&s, ","); 10737 if (user) { 10738 s = user; 10739 user = strsep(&s, "@"); 10740 context = strsep(&s, ""); 10741 if (!ast_strlen_zero(user)) 10742 skipuser++; 10743 ast_copy_string(mailbox, user, sizeof(mailbox)); 10744 } 10745 } 10746 10747 if (options) { 10748 silent = (strchr(options, 's')) != NULL; 10749 } 10750 10751 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 10752 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 10753 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 10754 ast_play_and_wait(chan, "auth-thankyou"); 10755 res = 0; 10756 } else if (mailbox[0] == '*') { 10757 /* user entered '*' */ 10758 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10759 res = 0; /* prevent hangup */ 10760 } 10761 } 10762 10763 return res; 10764 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12209 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().
12210 { 12211 char *context; 12212 char *args_copy; 12213 int res; 12214 12215 if (ast_strlen_zero(data)) { 12216 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12217 return -1; 12218 } 12219 12220 args_copy = ast_strdupa(data); 12221 if ((context = strchr(args_copy, '@'))) { 12222 *context++ = '\0'; 12223 } else { 12224 context = "default"; 12225 } 12226 12227 if ((res = sayname(chan, args_copy, context) < 0)) { 12228 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12229 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12230 if (!res) { 12231 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12232 } 12233 } 12234 12235 return res; 12236 }
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 4280 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.
04281 { 04282 const struct vm_zone *z = NULL; 04283 struct timeval t = ast_tvnow(); 04284 04285 /* Does this user have a timezone specified? */ 04286 if (!ast_strlen_zero(vmu->zonetag)) { 04287 /* Find the zone in the list */ 04288 AST_LIST_LOCK(&zones); 04289 AST_LIST_TRAVERSE(&zones, z, list) { 04290 if (!strcmp(z->name, vmu->zonetag)) 04291 break; 04292 } 04293 AST_LIST_UNLOCK(&zones); 04294 } 04295 ast_localtime(&t, tm, z ? z->timezone : NULL); 04296 return tm; 04297 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7248 of file app_voicemail_odbcstorage.c.
References ast_control_streamfile(), listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, and listen_control_stop_key.
07249 { 07250 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); 07251 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7240 of file app_voicemail_odbcstorage.c.
References AST_DIGIT_ANY, ast_log(), and ast_stream_and_wait().
07241 { 07242 int res; 07243 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07244 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07245 return res; 07246 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12183 of file app_voicemail_odbcstorage.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
12183 { 12184 struct ast_config *conf; 12185 struct ast_category *cat; 12186 struct ast_variable *var; 12187 12188 if (!(conf=ast_config_new())) { 12189 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12190 return -1; 12191 } 12192 if (!(cat=ast_category_new("general","",1))) { 12193 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12194 return -1; 12195 } 12196 if (!(var=ast_variable_new("password",password,""))) { 12197 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12198 return -1; 12199 } 12200 ast_category_append(conf,cat); 12201 ast_variable_append(cat,var); 12202 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12203 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12204 return -1; 12205 } 12206 return 0; 12207 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13197 of file app_voicemail_odbcstorage.c.
char* addesc = "Comedian Mail" [static] |
Definition at line 739 of file app_voicemail_odbcstorage.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 854 of file app_voicemail_odbcstorage.c.
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 855 of file app_voicemail_odbcstorage.c.
int adsiver = 1 [static] |
Definition at line 856 of file app_voicemail_odbcstorage.c.
char* app = "VoiceMail" [static] |
Definition at line 742 of file app_voicemail_odbcstorage.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 745 of file app_voicemail_odbcstorage.c.
char* app3 = "MailboxExists" [static] |
Definition at line 747 of file app_voicemail_odbcstorage.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 748 of file app_voicemail_odbcstorage.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13197 of file app_voicemail_odbcstorage.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 840 of file app_voicemail_odbcstorage.c.
char charset[32] = "ISO-8859-1" [static] |
Definition at line 852 of file app_voicemail_odbcstorage.c.
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 843 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 10962 of file app_voicemail_odbcstorage.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 839 of file app_voicemail_odbcstorage.c.
char* emailbody = NULL [static] |
Definition at line 846 of file app_voicemail_odbcstorage.c.
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 857 of file app_voicemail_odbcstorage.c.
char* emailsubject = NULL [static] |
Definition at line 847 of file app_voicemail_odbcstorage.c.
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 841 of file app_voicemail_odbcstorage.c.
char ext_pass_check_cmd[128] [static] |
Definition at line 719 of file app_voicemail_odbcstorage.c.
char ext_pass_cmd[128] [static] |
Definition at line 718 of file app_voicemail_odbcstorage.c.
char externnotify[160] [static] |
Definition at line 762 of file app_voicemail_odbcstorage.c.
char fromstring[100] [static] |
Definition at line 850 of file app_voicemail_odbcstorage.c.
struct ast_flags globalflags = {0} [static] |
Definition at line 835 of file app_voicemail_odbcstorage.c.
struct ao2_container* inprocess_container |
Definition at line 877 of file app_voicemail_odbcstorage.c.
char listen_control_forward_key[12] [static] |
Definition at line 820 of file app_voicemail_odbcstorage.c.
char listen_control_pause_key[12] [static] |
Definition at line 822 of file app_voicemail_odbcstorage.c.
char listen_control_restart_key[12] [static] |
Definition at line 823 of file app_voicemail_odbcstorage.c.
char listen_control_reverse_key[12] [static] |
Definition at line 821 of file app_voicemail_odbcstorage.c.
char listen_control_stop_key[12] [static] |
Definition at line 824 of file app_voicemail_odbcstorage.c.
char locale[20] [static] |
Definition at line 755 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 10720 of file app_voicemail_odbcstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1622 of file app_voicemail_odbcstorage.c.
char mailcmd[160] [static] |
Definition at line 761 of file app_voicemail_odbcstorage.c.
int maxdeletedmsg [static] |
Definition at line 758 of file app_voicemail_odbcstorage.c.
int maxgreet [static] |
Definition at line 768 of file app_voicemail_odbcstorage.c.
int maxlogins [static] |
Definition at line 770 of file app_voicemail_odbcstorage.c.
int maxmsg [static] |
Definition at line 757 of file app_voicemail_odbcstorage.c.
int maxsilence [static] |
Definition at line 756 of file app_voicemail_odbcstorage.c.
int minpassword [static] |
Definition at line 771 of file app_voicemail_odbcstorage.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 789 of file app_voicemail_odbcstorage.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 815 of file app_voicemail_odbcstorage.c.
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 791 of file app_voicemail_odbcstorage.c.
int my_umask [static] |
Definition at line 721 of file app_voicemail_odbcstorage.c.
char* pagerbody = NULL [static] |
Definition at line 848 of file app_voicemail_odbcstorage.c.
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 858 of file app_voicemail_odbcstorage.c.
char pagerfromstring[100] [static] |
Definition at line 851 of file app_voicemail_odbcstorage.c.
char* pagersubject = NULL [static] |
Definition at line 849 of file app_voicemail_odbcstorage.c.
int passwordlocation [static] |
Definition at line 772 of file app_voicemail_odbcstorage.c.
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 784 of file app_voicemail_odbcstorage.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 779 of file app_voicemail_odbcstorage.c.
ast_mutex_t poll_lock = { { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } , 1, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP } [static] |
Definition at line 783 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 776 of file app_voicemail_odbcstorage.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 785 of file app_voicemail_odbcstorage.c.
unsigned char poll_thread_run [static] |
Definition at line 786 of file app_voicemail_odbcstorage.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 725 of file app_voicemail_odbcstorage.c.
int saydurationminfo [static] |
Definition at line 837 of file app_voicemail_odbcstorage.c.
char* sayname_app = "VMSayName" [static] |
Definition at line 750 of file app_voicemail_odbcstorage.c.
char serveremail[80] [static] |
Definition at line 760 of file app_voicemail_odbcstorage.c.
int silencethreshold = 128 [static] |
Definition at line 759 of file app_voicemail_odbcstorage.c.
int skipms [static] |
Definition at line 769 of file app_voicemail_odbcstorage.c.
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 763 of file app_voicemail_odbcstorage.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 737 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 506 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 832 of file app_voicemail_odbcstorage.c.
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 831 of file app_voicemail_odbcstorage.c.
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 828 of file app_voicemail_odbcstorage.c.
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 829 of file app_voicemail_odbcstorage.c.
char vm_password[80] = "vm-password" [static] |
Definition at line 827 of file app_voicemail_odbcstorage.c.
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 833 of file app_voicemail_odbcstorage.c.
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 830 of file app_voicemail_odbcstorage.c.
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 716 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 11100 of file app_voicemail_odbcstorage.c.
char vmfmts[80] [static] |
Definition at line 764 of file app_voicemail_odbcstorage.c.
int vmmaxsecs [static] |
Definition at line 767 of file app_voicemail_odbcstorage.c.
int vmminsecs [static] |
Definition at line 766 of file app_voicemail_odbcstorage.c.
double volgain [static] |
Definition at line 765 of file app_voicemail_odbcstorage.c.
char zonetag[80] [static] |
Definition at line 754 of file app_voicemail_odbcstorage.c.