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