#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 | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
static int | vm_box_exists (struct ast_channel *chan, const char *data) |
static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Top level method to invoke the language variant vm_browse_messages_XX function. | |
static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Default English syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Vietnamese syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
static int | vm_delete (char *file) |
Removes the voicemail sound and information file. | |
static int | vm_exec (struct ast_channel *chan, const char *data) |
static int | vm_execmain (struct ast_channel *chan, const char *data) |
static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
presents the option to prepend to an existing message when forwarding it. | |
static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
static int | vm_lock_path (const char *path) |
Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
static FILE * | vm_mkftemp (char *template) |
static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
static int | vm_play_folder_name_gr (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_pl (struct ast_channel *chan, char *box) |
static int | vm_play_folder_name_ua (struct ast_channel *chan, char *box) |
static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
The handler for 'record a temporary greeting'. | |
static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
static int | vmauthenticate (struct ast_channel *chan, const char *data) |
static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
fill in *tm for current time according to the proper timezone, if any. | |
static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char * | sayname_app = "VMSayName" |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char | userscontext [AST_MAX_EXTENSION] = "default" |
static struct ast_app_option | vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} |
static struct ast_data_entry | vm_data_providers [] |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
static char | vm_passchanged [80] = "vm-passchanged" |
static char | vm_password [80] = "vm-password" |
static char | vm_pls_try_again [80] = "vm-pls-try-again" |
static char | vm_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 11057 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 11085 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(), resequence_mailbox(), 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(), resequence_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 5262 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05263 { 05264 DIR *dir; 05265 struct dirent *de; 05266 char fn[256]; 05267 int ret = 0; 05268 05269 /* If no mailbox, return immediately */ 05270 if (ast_strlen_zero(mailbox)) 05271 return 0; 05272 05273 if (ast_strlen_zero(folder)) 05274 folder = "INBOX"; 05275 if (ast_strlen_zero(context)) 05276 context = "default"; 05277 05278 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05279 05280 if (!(dir = opendir(fn))) 05281 return 0; 05282 05283 while ((de = readdir(dir))) { 05284 if (!strncasecmp(de->d_name, "msg", 3)) { 05285 if (shortcircuit) { 05286 ret = 1; 05287 break; 05288 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05289 ret++; 05290 } 05291 } 05292 } 05293 05294 closedir(dir); 05295 05296 return ret; 05297 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13260 of file app_voicemail.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13260 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 10761 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().
10762 { 10763 struct ast_vm_user svm; 10764 AST_DECLARE_APP_ARGS(arg, 10765 AST_APP_ARG(mbox); 10766 AST_APP_ARG(context); 10767 ); 10768 10769 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 10770 10771 if (ast_strlen_zero(arg.mbox)) { 10772 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 10773 return -1; 10774 } 10775 10776 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 10777 return 0; 10778 }
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 4680 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().
04681 { 04682 char tmpdir[256], newtmp[256]; 04683 char fname[256]; 04684 char tmpcmd[256]; 04685 int tmpfd = -1; 04686 04687 /* Eww. We want formats to tell us their own MIME type */ 04688 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04689 04690 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04691 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04692 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04693 tmpfd = mkstemp(newtmp); 04694 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04695 ast_debug(3, "newtmp: %s\n", newtmp); 04696 if (tmpfd > -1) { 04697 int soxstatus; 04698 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04699 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04700 attach = newtmp; 04701 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04702 } else { 04703 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04704 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04705 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04706 } 04707 } 04708 } 04709 fprintf(p, "--%s" ENDL, bound); 04710 if (msgnum > -1) 04711 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04712 else 04713 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04714 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04715 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04716 if (msgnum > -1) 04717 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04718 else 04719 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04720 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04721 base_encode(fname, p); 04722 if (last) 04723 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04724 if (tmpfd > -1) { 04725 unlink(fname); 04726 close(tmpfd); 04727 unlink(newtmp); 04728 } 04729 return 0; 04730 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6278 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().
06279 { 06280 int x; 06281 if (!ast_adsi_available(chan)) 06282 return; 06283 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06284 if (x < 0) 06285 return; 06286 if (!x) { 06287 if (adsi_load_vmail(chan, useadsi)) { 06288 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06289 return; 06290 } 06291 } else 06292 *useadsi = 1; 06293 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6467 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
Referenced by vm_execmain().
06468 { 06469 int bytes = 0; 06470 unsigned char buf[256]; 06471 unsigned char keys[8]; 06472 06473 int x; 06474 06475 if (!ast_adsi_available(chan)) 06476 return; 06477 06478 /* New meaning for keys */ 06479 for (x = 0; x < 5; x++) 06480 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06481 06482 keys[6] = 0x0; 06483 keys[7] = 0x0; 06484 06485 if (!vms->curmsg) { 06486 /* No prev key, provide "Folder" instead */ 06487 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06488 } 06489 if (vms->curmsg >= vms->lastmsg) { 06490 /* If last message ... */ 06491 if (vms->curmsg) { 06492 /* but not only message, provide "Folder" instead */ 06493 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06494 } else { 06495 /* Otherwise if only message, leave blank */ 06496 keys[3] = 1; 06497 } 06498 } 06499 06500 /* If deleted, show "undeleted" */ 06501 if (vms->deleted[vms->curmsg]) 06502 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06503 06504 /* Except "Exit" */ 06505 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06506 bytes += ast_adsi_set_keys(buf + bytes, keys); 06507 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06508 06509 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06510 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6343 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().
06344 { 06345 unsigned char buf[256]; 06346 int bytes = 0; 06347 unsigned char keys[8]; 06348 int x, y; 06349 06350 if (!ast_adsi_available(chan)) 06351 return; 06352 06353 for (x = 0; x < 5; x++) { 06354 y = ADSI_KEY_APPS + 12 + start + x; 06355 if (y > ADSI_KEY_APPS + 12 + 4) 06356 y = 0; 06357 keys[x] = ADSI_KEY_SKT | y; 06358 } 06359 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06360 keys[6] = 0; 06361 keys[7] = 0; 06362 06363 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06364 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06365 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06366 bytes += ast_adsi_set_keys(buf + bytes, keys); 06367 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06368 06369 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06370 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6615 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().
06616 { 06617 unsigned char buf[256]; 06618 int bytes = 0; 06619 06620 if (!ast_adsi_available(chan)) 06621 return; 06622 bytes += adsi_logo(buf + bytes); 06623 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06624 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06625 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06626 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06627 06628 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06629 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6149 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().
06150 { 06151 unsigned char buf[256]; 06152 int bytes = 0; 06153 int x; 06154 char num[5]; 06155 06156 *useadsi = 0; 06157 bytes += ast_adsi_data_mode(buf + bytes); 06158 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06159 06160 bytes = 0; 06161 bytes += adsi_logo(buf); 06162 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06163 #ifdef DISPLAY 06164 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06165 #endif 06166 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06167 bytes += ast_adsi_data_mode(buf + bytes); 06168 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06169 06170 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06171 bytes = 0; 06172 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06173 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06174 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06175 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06176 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06177 return 0; 06178 } 06179 06180 #ifdef DISPLAY 06181 /* Add a dot */ 06182 bytes = 0; 06183 bytes += ast_adsi_logo(buf); 06184 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06185 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06186 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06187 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06188 #endif 06189 bytes = 0; 06190 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06191 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06192 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06193 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06194 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06195 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06196 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06197 06198 #ifdef DISPLAY 06199 /* Add another dot */ 06200 bytes = 0; 06201 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06202 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06203 06204 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06205 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06206 #endif 06207 06208 bytes = 0; 06209 /* These buttons we load but don't use yet */ 06210 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06211 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06212 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06213 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06214 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06215 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06216 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06217 06218 #ifdef DISPLAY 06219 /* Add another dot */ 06220 bytes = 0; 06221 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06222 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06223 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06224 #endif 06225 06226 bytes = 0; 06227 for (x = 0; x < 5; x++) { 06228 snprintf(num, sizeof(num), "%d", x); 06229 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06230 } 06231 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06232 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06233 06234 #ifdef DISPLAY 06235 /* Add another dot */ 06236 bytes = 0; 06237 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06238 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06239 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06240 #endif 06241 06242 if (ast_adsi_end_download(chan)) { 06243 bytes = 0; 06244 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06245 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06246 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06247 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06248 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06249 return 0; 06250 } 06251 bytes = 0; 06252 bytes += ast_adsi_download_disconnect(buf + bytes); 06253 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06254 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06255 06256 ast_debug(1, "Done downloading scripts...\n"); 06257 06258 #ifdef DISPLAY 06259 /* Add last dot */ 06260 bytes = 0; 06261 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06262 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06263 #endif 06264 ast_debug(1, "Restarting session...\n"); 06265 06266 bytes = 0; 06267 /* Load the session now */ 06268 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06269 *useadsi = 1; 06270 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06271 } else 06272 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06273 06274 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06275 return 0; 06276 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6295 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().
06296 { 06297 unsigned char buf[256]; 06298 int bytes = 0; 06299 unsigned char keys[8]; 06300 int x; 06301 if (!ast_adsi_available(chan)) 06302 return; 06303 06304 for (x = 0; x < 8; x++) 06305 keys[x] = 0; 06306 /* Set one key for next */ 06307 keys[3] = ADSI_KEY_APPS + 3; 06308 06309 bytes += adsi_logo(buf + bytes); 06310 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06311 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06312 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06313 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06314 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06315 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06316 bytes += ast_adsi_set_keys(buf + bytes, keys); 06317 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06318 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06319 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6141 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().
06142 { 06143 int bytes = 0; 06144 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06145 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06146 return bytes; 06147 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6372 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().
06373 { 06374 int bytes = 0; 06375 unsigned char buf[256]; 06376 char buf1[256], buf2[256]; 06377 char fn2[PATH_MAX]; 06378 06379 char cid[256] = ""; 06380 char *val; 06381 char *name, *num; 06382 char datetime[21] = ""; 06383 FILE *f; 06384 06385 unsigned char keys[8]; 06386 06387 int x; 06388 06389 if (!ast_adsi_available(chan)) 06390 return; 06391 06392 /* Retrieve important info */ 06393 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06394 f = fopen(fn2, "r"); 06395 if (f) { 06396 while (!feof(f)) { 06397 if (!fgets((char *) buf, sizeof(buf), f)) { 06398 continue; 06399 } 06400 if (!feof(f)) { 06401 char *stringp = NULL; 06402 stringp = (char *) buf; 06403 strsep(&stringp, "="); 06404 val = strsep(&stringp, "="); 06405 if (!ast_strlen_zero(val)) { 06406 if (!strcmp((char *) buf, "callerid")) 06407 ast_copy_string(cid, val, sizeof(cid)); 06408 if (!strcmp((char *) buf, "origdate")) 06409 ast_copy_string(datetime, val, sizeof(datetime)); 06410 } 06411 } 06412 } 06413 fclose(f); 06414 } 06415 /* New meaning for keys */ 06416 for (x = 0; x < 5; x++) 06417 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06418 keys[6] = 0x0; 06419 keys[7] = 0x0; 06420 06421 if (!vms->curmsg) { 06422 /* No prev key, provide "Folder" instead */ 06423 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06424 } 06425 if (vms->curmsg >= vms->lastmsg) { 06426 /* If last message ... */ 06427 if (vms->curmsg) { 06428 /* but not only message, provide "Folder" instead */ 06429 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06430 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06431 06432 } else { 06433 /* Otherwise if only message, leave blank */ 06434 keys[3] = 1; 06435 } 06436 } 06437 06438 if (!ast_strlen_zero(cid)) { 06439 ast_callerid_parse(cid, &name, &num); 06440 if (!name) 06441 name = num; 06442 } else 06443 name = "Unknown Caller"; 06444 06445 /* If deleted, show "undeleted" */ 06446 06447 if (vms->deleted[vms->curmsg]) 06448 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06449 06450 /* Except "Exit" */ 06451 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06452 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06453 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06454 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06455 06456 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06457 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06458 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06459 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06460 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06461 bytes += ast_adsi_set_keys(buf + bytes, keys); 06462 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06463 06464 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06465 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6321 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().
06322 { 06323 unsigned char buf[256]; 06324 int bytes = 0; 06325 unsigned char keys[8]; 06326 int x; 06327 if (!ast_adsi_available(chan)) 06328 return; 06329 06330 for (x = 0; x < 8; x++) 06331 keys[x] = 0; 06332 /* Set one key for next */ 06333 keys[3] = ADSI_KEY_APPS + 3; 06334 06335 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06336 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06337 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06338 bytes += ast_adsi_set_keys(buf + bytes, keys); 06339 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06340 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06341 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6512 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().
06513 { 06514 unsigned char buf[256] = ""; 06515 char buf1[256] = "", buf2[256] = ""; 06516 int bytes = 0; 06517 unsigned char keys[8]; 06518 int x; 06519 06520 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06521 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06522 if (!ast_adsi_available(chan)) 06523 return; 06524 if (vms->newmessages) { 06525 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06526 if (vms->oldmessages) { 06527 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06528 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06529 } else { 06530 snprintf(buf2, sizeof(buf2), "%s.", newm); 06531 } 06532 } else if (vms->oldmessages) { 06533 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06534 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06535 } else { 06536 strcpy(buf1, "You have no messages."); 06537 buf2[0] = ' '; 06538 buf2[1] = '\0'; 06539 } 06540 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06541 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06542 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06543 06544 for (x = 0; x < 6; x++) 06545 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06546 keys[6] = 0; 06547 keys[7] = 0; 06548 06549 /* Don't let them listen if there are none */ 06550 if (vms->lastmsg < 0) 06551 keys[0] = 1; 06552 bytes += ast_adsi_set_keys(buf + bytes, keys); 06553 06554 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06555 06556 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06557 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6559 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().
06560 { 06561 unsigned char buf[256] = ""; 06562 char buf1[256] = "", buf2[256] = ""; 06563 int bytes = 0; 06564 unsigned char keys[8]; 06565 int x; 06566 06567 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06568 06569 if (!ast_adsi_available(chan)) 06570 return; 06571 06572 /* Original command keys */ 06573 for (x = 0; x < 6; x++) 06574 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06575 06576 keys[6] = 0; 06577 keys[7] = 0; 06578 06579 if ((vms->lastmsg + 1) < 1) 06580 keys[0] = 0; 06581 06582 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06583 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06584 06585 if (vms->lastmsg + 1) 06586 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06587 else 06588 strcpy(buf2, "no messages."); 06589 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06590 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06591 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06592 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06593 bytes += ast_adsi_set_keys(buf + bytes, keys); 06594 06595 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06596 06597 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06598 06599 }
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 12826 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().
12827 { 12828 int res = 0; 12829 char filename[PATH_MAX]; 12830 struct ast_config *msg_cfg = NULL; 12831 const char *origtime, *context; 12832 char *name, *num; 12833 int retries = 0; 12834 char *cid; 12835 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 12836 12837 vms->starting = 0; 12838 12839 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 12840 12841 /* Retrieve info from VM attribute file */ 12842 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 12843 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 12844 msg_cfg = ast_config_load(filename, config_flags); 12845 DISPOSE(vms->curdir, vms->curmsg); 12846 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 12847 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 12848 return 0; 12849 } 12850 12851 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 12852 ast_config_destroy(msg_cfg); 12853 return 0; 12854 } 12855 12856 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 12857 12858 context = ast_variable_retrieve(msg_cfg, "message", "context"); 12859 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 12860 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 12861 switch (option) { 12862 case 3: /* Play message envelope */ 12863 if (!res) 12864 res = play_message_datetime(chan, vmu, origtime, filename); 12865 if (!res) 12866 res = play_message_callerid(chan, vms, cid, context, 0); 12867 12868 res = 't'; 12869 break; 12870 12871 case 2: /* Call back */ 12872 12873 if (ast_strlen_zero(cid)) 12874 break; 12875 12876 ast_callerid_parse(cid, &name, &num); 12877 while ((res > -1) && (res != 't')) { 12878 switch (res) { 12879 case '1': 12880 if (num) { 12881 /* Dial the CID number */ 12882 res = dialout(chan, vmu, num, vmu->callback); 12883 if (res) { 12884 ast_config_destroy(msg_cfg); 12885 return 9; 12886 } 12887 } else { 12888 res = '2'; 12889 } 12890 break; 12891 12892 case '2': 12893 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 12894 if (!ast_strlen_zero(vmu->dialout)) { 12895 res = dialout(chan, vmu, NULL, vmu->dialout); 12896 if (res) { 12897 ast_config_destroy(msg_cfg); 12898 return 9; 12899 } 12900 } else { 12901 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 12902 res = ast_play_and_wait(chan, "vm-sorry"); 12903 } 12904 ast_config_destroy(msg_cfg); 12905 return res; 12906 case '*': 12907 res = 't'; 12908 break; 12909 case '3': 12910 case '4': 12911 case '5': 12912 case '6': 12913 case '7': 12914 case '8': 12915 case '9': 12916 case '0': 12917 12918 res = ast_play_and_wait(chan, "vm-sorry"); 12919 retries++; 12920 break; 12921 default: 12922 if (num) { 12923 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 12924 res = ast_play_and_wait(chan, "vm-num-i-have"); 12925 if (!res) 12926 res = play_message_callerid(chan, vms, num, vmu->context, 1); 12927 if (!res) 12928 res = ast_play_and_wait(chan, "vm-tocallnum"); 12929 /* Only prompt for a caller-specified number if there is a dialout context specified */ 12930 if (!ast_strlen_zero(vmu->dialout)) { 12931 if (!res) 12932 res = ast_play_and_wait(chan, "vm-calldiffnum"); 12933 } 12934 } else { 12935 res = ast_play_and_wait(chan, "vm-nonumber"); 12936 if (!ast_strlen_zero(vmu->dialout)) { 12937 if (!res) 12938 res = ast_play_and_wait(chan, "vm-toenternumber"); 12939 } 12940 } 12941 if (!res) 12942 res = ast_play_and_wait(chan, "vm-star-cancel"); 12943 if (!res) 12944 res = ast_waitfordigit(chan, 6000); 12945 if (!res) { 12946 retries++; 12947 if (retries > 3) 12948 res = 't'; 12949 } 12950 break; 12951 12952 } 12953 if (res == 't') 12954 res = 0; 12955 else if (res == '*') 12956 res = -1; 12957 } 12958 break; 12959 12960 case 1: /* Reply */ 12961 /* Send reply directly to sender */ 12962 if (ast_strlen_zero(cid)) 12963 break; 12964 12965 ast_callerid_parse(cid, &name, &num); 12966 if (!num) { 12967 ast_verb(3, "No CID number available, no reply sent\n"); 12968 if (!res) 12969 res = ast_play_and_wait(chan, "vm-nonumber"); 12970 ast_config_destroy(msg_cfg); 12971 return res; 12972 } else { 12973 struct ast_vm_user vmu2; 12974 if (find_user(&vmu2, vmu->context, num)) { 12975 struct leave_vm_options leave_options; 12976 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 12977 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 12978 12979 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 12980 12981 memset(&leave_options, 0, sizeof(leave_options)); 12982 leave_options.record_gain = record_gain; 12983 res = leave_voicemail(chan, mailbox, &leave_options); 12984 if (!res) 12985 res = 't'; 12986 ast_config_destroy(msg_cfg); 12987 return res; 12988 } else { 12989 /* Sender has no mailbox, can't reply */ 12990 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 12991 ast_play_and_wait(chan, "vm-nobox"); 12992 res = 't'; 12993 ast_config_destroy(msg_cfg); 12994 return res; 12995 } 12996 } 12997 res = 0; 12998 12999 break; 13000 } 13001 13002 #ifndef IMAP_STORAGE 13003 ast_config_destroy(msg_cfg); 13004 13005 if (!res) { 13006 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13007 vms->heard[msg] = 1; 13008 res = wait_file(chan, vms, vms->fn); 13009 } 13010 #endif 13011 return res; 13012 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10504 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().
10505 { 10506 /* Assumes lock is already held */ 10507 char *tmp; 10508 char *stringp; 10509 char *s; 10510 struct ast_vm_user *vmu; 10511 char *mailbox_full; 10512 int new = 0, old = 0, urgent = 0; 10513 char secretfn[PATH_MAX] = ""; 10514 10515 tmp = ast_strdupa(data); 10516 10517 if (!(vmu = find_or_create(context, box))) 10518 return -1; 10519 10520 populate_defaults(vmu); 10521 10522 stringp = tmp; 10523 if ((s = strsep(&stringp, ","))) { 10524 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10525 } 10526 if (stringp && (s = strsep(&stringp, ","))) { 10527 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10528 } 10529 if (stringp && (s = strsep(&stringp, ","))) { 10530 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10531 } 10532 if (stringp && (s = strsep(&stringp, ","))) { 10533 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10534 } 10535 if (stringp && (s = strsep(&stringp, ","))) { 10536 apply_options(vmu, s); 10537 } 10538 10539 switch (vmu->passwordlocation) { 10540 case OPT_PWLOC_SPOOLDIR: 10541 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10542 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10543 } 10544 10545 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10546 strcpy(mailbox_full, box); 10547 strcat(mailbox_full, "@"); 10548 strcat(mailbox_full, context); 10549 10550 inboxcount2(mailbox_full, &urgent, &new, &old); 10551 queue_mwi_event(mailbox_full, urgent, new, old); 10552 10553 return 0; 10554 }
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 4355 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.
04356 { 04357 struct ast_str *tmp = ast_str_alloca(80); 04358 int first_section = 1; 04359 04360 ast_str_reset(*end); 04361 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04362 for (; *start; start++) { 04363 int need_encoding = 0; 04364 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04365 need_encoding = 1; 04366 } 04367 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04368 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04369 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04370 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04371 /* Start new line */ 04372 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04373 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04374 first_section = 0; 04375 } 04376 if (need_encoding && *start == ' ') { 04377 ast_str_append(&tmp, -1, "_"); 04378 } else if (need_encoding) { 04379 ast_str_append(&tmp, -1, "=%hhX", *start); 04380 } else { 04381 ast_str_append(&tmp, -1, "%c", *start); 04382 } 04383 } 04384 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04385 return ast_str_buffer(*end); 04386 }
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 4283 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04284 { 04285 const char *ptr; 04286 04287 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04288 ast_str_set(buf, maxlen, "\""); 04289 for (ptr = from; *ptr; ptr++) { 04290 if (*ptr == '"' || *ptr == '\\') { 04291 ast_str_append(buf, maxlen, "\\%c", *ptr); 04292 } else { 04293 ast_str_append(buf, maxlen, "%c", *ptr); 04294 } 04295 } 04296 ast_str_append(buf, maxlen, "\""); 04297 04298 return ast_str_buffer(*buf); 04299 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10556 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.
10557 { 10558 int res = 0; 10559 struct ast_vm_user *vmu; 10560 /* language parameter seems to only be used for display in manager action */ 10561 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10562 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10563 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10564 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10565 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10566 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10567 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir"; 10568 #ifdef IMAP_STORAGE 10569 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10570 "imapfolder=INBOX|imapvmshareid=6000"; 10571 #endif 10572 10573 switch (cmd) { 10574 case TEST_INIT: 10575 info->name = "vmuser"; 10576 info->category = "/apps/app_voicemail/"; 10577 info->summary = "Vmuser unit test"; 10578 info->description = 10579 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10580 return AST_TEST_NOT_RUN; 10581 case TEST_EXECUTE: 10582 break; 10583 } 10584 10585 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10586 return AST_TEST_NOT_RUN; 10587 } 10588 ast_set_flag(vmu, VM_ALLOCED); 10589 10590 apply_options(vmu, options_string); 10591 10592 if (!ast_test_flag(vmu, VM_ATTACH)) { 10593 ast_test_status_update(test, "Parse failure for attach option\n"); 10594 res = 1; 10595 } 10596 if (strcasecmp(vmu->attachfmt, "wav49")) { 10597 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10598 res = 1; 10599 } 10600 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10601 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10602 res = 1; 10603 } 10604 if (strcasecmp(vmu->zonetag, "central")) { 10605 ast_test_status_update(test, "Parse failure for tz option\n"); 10606 res = 1; 10607 } 10608 if (!ast_test_flag(vmu, VM_DELETE)) { 10609 ast_test_status_update(test, "Parse failure for delete option\n"); 10610 res = 1; 10611 } 10612 if (!ast_test_flag(vmu, VM_SAYCID)) { 10613 ast_test_status_update(test, "Parse failure for saycid option\n"); 10614 res = 1; 10615 } 10616 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10617 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10618 res = 1; 10619 } 10620 if (!ast_test_flag(vmu, VM_REVIEW)) { 10621 ast_test_status_update(test, "Parse failure for review option\n"); 10622 res = 1; 10623 } 10624 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10625 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10626 res = 1; 10627 } 10628 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10629 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10630 res = 1; 10631 } 10632 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10633 ast_test_status_update(test, "Parse failure for operator option\n"); 10634 res = 1; 10635 } 10636 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10637 ast_test_status_update(test, "Parse failure for envelope option\n"); 10638 res = 1; 10639 } 10640 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10641 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10642 res = 1; 10643 } 10644 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10645 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10646 res = 1; 10647 } 10648 if (vmu->saydurationm != 5) { 10649 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10650 res = 1; 10651 } 10652 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10653 ast_test_status_update(test, "Parse failure for forcename option\n"); 10654 res = 1; 10655 } 10656 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10657 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10658 res = 1; 10659 } 10660 if (strcasecmp(vmu->callback, "somecontext")) { 10661 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10662 res = 1; 10663 } 10664 if (strcasecmp(vmu->dialout, "somecontext2")) { 10665 ast_test_status_update(test, "Parse failure for dialout option\n"); 10666 res = 1; 10667 } 10668 if (strcasecmp(vmu->exit, "somecontext3")) { 10669 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10670 res = 1; 10671 } 10672 if (vmu->minsecs != 10) { 10673 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10674 res = 1; 10675 } 10676 if (vmu->maxsecs != 100) { 10677 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10678 res = 1; 10679 } 10680 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10681 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10682 res = 1; 10683 } 10684 if (vmu->maxdeletedmsg != 50) { 10685 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10686 res = 1; 10687 } 10688 if (vmu->volgain != 1.3) { 10689 ast_test_status_update(test, "Parse failure for volgain option\n"); 10690 res = 1; 10691 } 10692 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10693 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10694 res = 1; 10695 } 10696 #ifdef IMAP_STORAGE 10697 apply_options(vmu, option_string2); 10698 10699 if (strcasecmp(vmu->imapuser, "imapuser")) { 10700 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10701 res = 1; 10702 } 10703 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10704 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10705 res = 1; 10706 } 10707 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10708 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10709 res = 1; 10710 } 10711 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10712 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10713 res = 1; 10714 } 10715 #endif 10716 10717 free_user(vmu); 10718 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10719 }
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 4159 of file app_voicemail.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04160 { 04161 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04162 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04163 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04164 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04165 int i, hiteof = 0; 04166 FILE *fi; 04167 struct baseio bio; 04168 04169 memset(&bio, 0, sizeof(bio)); 04170 bio.iocp = BASEMAXINLINE; 04171 04172 if (!(fi = fopen(filename, "rb"))) { 04173 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04174 return -1; 04175 } 04176 04177 while (!hiteof){ 04178 unsigned char igroup[3], ogroup[4]; 04179 int c, n; 04180 04181 memset(igroup, 0, sizeof(igroup)); 04182 04183 for (n = 0; n < 3; n++) { 04184 if ((c = inchar(&bio, fi)) == EOF) { 04185 hiteof = 1; 04186 break; 04187 } 04188 04189 igroup[n] = (unsigned char) c; 04190 } 04191 04192 if (n > 0) { 04193 ogroup[0]= dtable[igroup[0] >> 2]; 04194 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04195 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04196 ogroup[3]= dtable[igroup[2] & 0x3F]; 04197 04198 if (n < 3) { 04199 ogroup[3] = '='; 04200 04201 if (n < 2) 04202 ogroup[2] = '='; 04203 } 04204 04205 for (i = 0; i < 4; i++) 04206 ochar(&bio, ogroup[i], so); 04207 } 04208 } 04209 04210 fclose(fi); 04211 04212 if (fputs(ENDL, so) == EOF) { 04213 return 0; 04214 } 04215 04216 return 1; 04217 }
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 4328 of file app_voicemail.c.
04329 { 04330 for (; *str; str++) { 04331 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04332 return 1; 04333 } 04334 } 04335 return 0; 04336 }
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 7782 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().
07783 { 07784 int x = 0; 07785 #ifndef IMAP_STORAGE 07786 int res = 0, nummsg; 07787 char fn2[PATH_MAX]; 07788 #endif 07789 07790 if (vms->lastmsg <= -1) { 07791 goto done; 07792 } 07793 07794 vms->curmsg = -1; 07795 #ifndef IMAP_STORAGE 07796 /* Get the deleted messages fixed */ 07797 if (vm_lock_path(vms->curdir)) { 07798 return ERROR_LOCK_PATH; 07799 } 07800 07801 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07802 for (x = 0; x < vms->lastmsg + 1; x++) { 07803 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07804 /* Save this message. It's not in INBOX or hasn't been heard */ 07805 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07806 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07807 break; 07808 } 07809 vms->curmsg++; 07810 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07811 if (strcmp(vms->fn, fn2)) { 07812 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07813 } 07814 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07815 /* Move to old folder before deleting */ 07816 res = save_to_folder(vmu, vms, x, 1); 07817 if (res == ERROR_LOCK_PATH) { 07818 /* If save failed do not delete the message */ 07819 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07820 vms->deleted[x] = 0; 07821 vms->heard[x] = 0; 07822 --x; 07823 } 07824 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07825 /* Move to deleted folder */ 07826 res = save_to_folder(vmu, vms, x, 10); 07827 if (res == ERROR_LOCK_PATH) { 07828 /* If save failed do not delete the message */ 07829 vms->deleted[x] = 0; 07830 vms->heard[x] = 0; 07831 --x; 07832 } 07833 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07834 /* If realtime storage enabled - we should explicitly delete this message, 07835 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07836 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07837 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07838 DELETE(vms->curdir, x, vms->fn, vmu); 07839 } 07840 } 07841 } 07842 07843 /* Delete ALL remaining messages */ 07844 nummsg = x - 1; 07845 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07846 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07847 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07848 DELETE(vms->curdir, x, vms->fn, vmu); 07849 } 07850 } 07851 ast_unlock_path(vms->curdir); 07852 #else /* defined(IMAP_STORAGE) */ 07853 if (vms->deleted) { 07854 /* Since we now expunge after each delete, deleting in reverse order 07855 * ensures that no reordering occurs between each step. */ 07856 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 07857 if (vms->deleted[x]) { 07858 ast_debug(3, "IMAP delete of %d\n", x); 07859 DELETE(vms->curdir, x, vms->fn, vmu); 07860 } 07861 } 07862 } 07863 #endif 07864 07865 done: 07866 if (vms->deleted && vmu->maxmsg) { 07867 memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 07868 } 07869 if (vms->heard && vmu->maxmsg) { 07870 memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 07871 } 07872 07873 return 0; 07874 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10865 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().
10866 { 10867 int which = 0; 10868 int wordlen; 10869 struct ast_vm_user *vmu; 10870 const char *context = ""; 10871 10872 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 10873 if (pos > 4) 10874 return NULL; 10875 if (pos == 3) 10876 return (state == 0) ? ast_strdup("for") : NULL; 10877 wordlen = strlen(word); 10878 AST_LIST_TRAVERSE(&users, vmu, list) { 10879 if (!strncasecmp(word, vmu->context, wordlen)) { 10880 if (context && strcmp(context, vmu->context) && ++which > state) 10881 return ast_strdup(vmu->context); 10882 /* ignore repeated contexts ? */ 10883 context = vmu->context; 10884 } 10885 } 10886 return NULL; 10887 }
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 3963 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().
03964 { 03965 int ifd; 03966 int ofd; 03967 int res; 03968 int len; 03969 char buf[4096]; 03970 03971 #ifdef HARDLINK_WHEN_POSSIBLE 03972 /* Hard link if possible; saves disk space & is faster */ 03973 if (link(infile, outfile)) { 03974 #endif 03975 if ((ifd = open(infile, O_RDONLY)) < 0) { 03976 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03977 return -1; 03978 } 03979 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03980 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03981 close(ifd); 03982 return -1; 03983 } 03984 do { 03985 len = read(ifd, buf, sizeof(buf)); 03986 if (len < 0) { 03987 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03988 close(ifd); 03989 close(ofd); 03990 unlink(outfile); 03991 } 03992 if (len) { 03993 res = write(ofd, buf, len); 03994 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03995 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03996 close(ifd); 03997 close(ofd); 03998 unlink(outfile); 03999 } 04000 } 04001 } while (len); 04002 close(ifd); 04003 close(ofd); 04004 return 0; 04005 #ifdef HARDLINK_WHEN_POSSIBLE 04006 } else { 04007 /* Hard link succeeded */ 04008 return 0; 04009 } 04010 #endif 04011 }
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 5199 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().
05200 { 05201 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05202 const char *frombox = mbox(vmu, imbox); 05203 int recipmsgnum; 05204 int res = 0; 05205 05206 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05207 05208 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05209 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 05210 } else { 05211 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 05212 } 05213 05214 if (!dir) 05215 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05216 else 05217 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05218 05219 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05220 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 05221 05222 if (vm_lock_path(todir)) 05223 return ERROR_LOCK_PATH; 05224 05225 recipmsgnum = last_message_index(recip, todir) + 1; 05226 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05227 make_file(topath, sizeof(topath), todir, recipmsgnum); 05228 #ifndef ODBC_STORAGE 05229 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05230 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05231 } else { 05232 #endif 05233 /* If we are prepending a message for ODBC, then the message already 05234 * exists in the database, but we want to force copying from the 05235 * filesystem (since only the FS contains the prepend). */ 05236 copy_plain_file(frompath, topath); 05237 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05238 vm_delete(topath); 05239 #ifndef ODBC_STORAGE 05240 } 05241 #endif 05242 } else { 05243 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05244 res = -1; 05245 } 05246 ast_unlock_path(todir); 05247 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05248 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05249 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05250 flag); 05251 05252 return res; 05253 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4022 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().
04023 { 04024 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04025 struct ast_variable *tmp,*var = NULL; 04026 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04027 ast_filecopy(frompath, topath, NULL); 04028 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04029 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04030 if (ast_check_realtime("voicemail_data")) { 04031 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04032 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04033 for (tmp = var; tmp; tmp = tmp->next) { 04034 if (!strcasecmp(tmp->name, "origmailbox")) { 04035 origmailbox = tmp->value; 04036 } else if (!strcasecmp(tmp->name, "context")) { 04037 context = tmp->value; 04038 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04039 macrocontext = tmp->value; 04040 } else if (!strcasecmp(tmp->name, "exten")) { 04041 exten = tmp->value; 04042 } else if (!strcasecmp(tmp->name, "priority")) { 04043 priority = tmp->value; 04044 } else if (!strcasecmp(tmp->name, "callerchan")) { 04045 callerchan = tmp->value; 04046 } else if (!strcasecmp(tmp->name, "callerid")) { 04047 callerid = tmp->value; 04048 } else if (!strcasecmp(tmp->name, "origdate")) { 04049 origdate = tmp->value; 04050 } else if (!strcasecmp(tmp->name, "origtime")) { 04051 origtime = tmp->value; 04052 } else if (!strcasecmp(tmp->name, "category")) { 04053 category = tmp->value; 04054 } else if (!strcasecmp(tmp->name, "duration")) { 04055 duration = tmp->value; 04056 } 04057 } 04058 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); 04059 } 04060 copy(frompath2, topath2); 04061 ast_variables_destroy(var); 04062 }
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 12754 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().
12755 { 12756 int cmd = 0; 12757 char destination[80] = ""; 12758 int retries = 0; 12759 12760 if (!num) { 12761 ast_verb(3, "Destination number will be entered manually\n"); 12762 while (retries < 3 && cmd != 't') { 12763 destination[1] = '\0'; 12764 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 12765 if (!cmd) 12766 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 12767 if (!cmd) 12768 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 12769 if (!cmd) { 12770 cmd = ast_waitfordigit(chan, 6000); 12771 if (cmd) 12772 destination[0] = cmd; 12773 } 12774 if (!cmd) { 12775 retries++; 12776 } else { 12777 12778 if (cmd < 0) 12779 return 0; 12780 if (cmd == '*') { 12781 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 12782 return 0; 12783 } 12784 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 12785 retries++; 12786 else 12787 cmd = 't'; 12788 } 12789 } 12790 if (retries >= 3) { 12791 return 0; 12792 } 12793 12794 } else { 12795 if (option_verbose > 2) 12796 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 12797 ast_copy_string(destination, num, sizeof(destination)); 12798 } 12799 12800 if (!ast_strlen_zero(destination)) { 12801 if (destination[strlen(destination) -1 ] == '*') 12802 return 0; 12803 if (option_verbose > 2) 12804 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 12805 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 12806 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 12807 chan->priority = 0; 12808 return 9; 12809 } 12810 return 0; 12811 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10472 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().
10473 { 10474 struct ast_vm_user *vmu; 10475 10476 AST_LIST_TRAVERSE(&users, vmu, list) { 10477 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10478 if (strcasecmp(vmu->context, context)) { 10479 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10480 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10481 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10482 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10483 } 10484 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10485 return NULL; 10486 } 10487 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10488 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10489 return NULL; 10490 } 10491 } 10492 10493 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10494 return NULL; 10495 10496 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10497 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10498 10499 AST_LIST_INSERT_TAIL(&users, vmu, list); 10500 10501 return vmu; 10502 }
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 6996 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().
06997 { 06998 #ifdef IMAP_STORAGE 06999 int todircount = 0; 07000 struct vm_state *dstvms; 07001 #endif 07002 char username[70]=""; 07003 char fn[PATH_MAX]; /* for playback of name greeting */ 07004 char ecodes[16] = "#"; 07005 int res = 0, cmd = 0; 07006 struct ast_vm_user *receiver = NULL, *vmtmp; 07007 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07008 char *stringp; 07009 const char *s; 07010 int saved_messages = 0; 07011 int valid_extensions = 0; 07012 char *dir; 07013 int curmsg; 07014 char urgent_str[7] = ""; 07015 char tmptxtfile[PATH_MAX]; 07016 int prompt_played = 0; 07017 #ifndef IMAP_STORAGE 07018 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07019 #endif 07020 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07021 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07022 } 07023 07024 if (vms == NULL) return -1; 07025 dir = vms->curdir; 07026 curmsg = vms->curmsg; 07027 07028 tmptxtfile[0] = '\0'; 07029 while (!res && !valid_extensions) { 07030 int use_directory = 0; 07031 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07032 int done = 0; 07033 int retries = 0; 07034 cmd = 0; 07035 while ((cmd >= 0) && !done ){ 07036 if (cmd) 07037 retries = 0; 07038 switch (cmd) { 07039 case '1': 07040 use_directory = 0; 07041 done = 1; 07042 break; 07043 case '2': 07044 use_directory = 1; 07045 done = 1; 07046 break; 07047 case '*': 07048 cmd = 't'; 07049 done = 1; 07050 break; 07051 default: 07052 /* Press 1 to enter an extension press 2 to use the directory */ 07053 cmd = ast_play_and_wait(chan, "vm-forward"); 07054 if (!cmd) 07055 cmd = ast_waitfordigit(chan, 3000); 07056 if (!cmd) 07057 retries++; 07058 if (retries > 3) { 07059 cmd = 't'; 07060 done = 1; 07061 } 07062 07063 } 07064 } 07065 if (cmd < 0 || cmd == 't') 07066 break; 07067 } 07068 07069 if (use_directory) { 07070 /* use app_directory */ 07071 07072 char old_context[sizeof(chan->context)]; 07073 char old_exten[sizeof(chan->exten)]; 07074 int old_priority; 07075 struct ast_app* directory_app; 07076 07077 directory_app = pbx_findapp("Directory"); 07078 if (directory_app) { 07079 char vmcontext[256]; 07080 /* make backup copies */ 07081 memcpy(old_context, chan->context, sizeof(chan->context)); 07082 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07083 old_priority = chan->priority; 07084 07085 /* call the the Directory, changes the channel */ 07086 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07087 res = pbx_exec(chan, directory_app, vmcontext); 07088 07089 ast_copy_string(username, chan->exten, sizeof(username)); 07090 07091 /* restore the old context, exten, and priority */ 07092 memcpy(chan->context, old_context, sizeof(chan->context)); 07093 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07094 chan->priority = old_priority; 07095 } else { 07096 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07097 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07098 } 07099 } else { 07100 /* Ask for an extension */ 07101 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07102 prompt_played++; 07103 if (res || prompt_played > 4) 07104 break; 07105 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07106 break; 07107 } 07108 07109 /* start all over if no username */ 07110 if (ast_strlen_zero(username)) 07111 continue; 07112 stringp = username; 07113 s = strsep(&stringp, "*"); 07114 /* start optimistic */ 07115 valid_extensions = 1; 07116 while (s) { 07117 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07118 int oldmsgs; 07119 int newmsgs; 07120 int capacity; 07121 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07122 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07123 /* Shouldn't happen, but allow trying another extension if it does */ 07124 res = ast_play_and_wait(chan, "pbx-invalid"); 07125 valid_extensions = 0; 07126 break; 07127 } 07128 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07129 if ((newmsgs + oldmsgs) >= capacity) { 07130 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07131 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07132 valid_extensions = 0; 07133 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07134 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07135 free_user(vmtmp); 07136 } 07137 inprocess_count(receiver->mailbox, receiver->context, -1); 07138 break; 07139 } 07140 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07141 } else { 07142 /* XXX Optimization for the future. When we encounter a single bad extension, 07143 * bailing out on all of the extensions may not be the way to go. We should 07144 * probably just bail on that single extension, then allow the user to enter 07145 * several more. XXX 07146 */ 07147 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07148 free_user(receiver); 07149 } 07150 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07151 /* "I am sorry, that's not a valid extension. Please try again." */ 07152 res = ast_play_and_wait(chan, "pbx-invalid"); 07153 valid_extensions = 0; 07154 break; 07155 } 07156 07157 /* play name if available, else play extension number */ 07158 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07159 RETRIEVE(fn, -1, s, receiver->context); 07160 if (ast_fileexists(fn, NULL, NULL) > 0) { 07161 res = ast_stream_and_wait(chan, fn, ecodes); 07162 if (res) { 07163 DISPOSE(fn, -1); 07164 return res; 07165 } 07166 } else { 07167 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07168 } 07169 DISPOSE(fn, -1); 07170 07171 s = strsep(&stringp, "*"); 07172 } 07173 /* break from the loop of reading the extensions */ 07174 if (valid_extensions) 07175 break; 07176 } 07177 /* check if we're clear to proceed */ 07178 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07179 return res; 07180 if (is_new_message == 1) { 07181 struct leave_vm_options leave_options; 07182 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07183 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07184 07185 /* Send VoiceMail */ 07186 memset(&leave_options, 0, sizeof(leave_options)); 07187 leave_options.record_gain = record_gain; 07188 cmd = leave_voicemail(chan, mailbox, &leave_options); 07189 } else { 07190 /* Forward VoiceMail */ 07191 long duration = 0; 07192 struct vm_state vmstmp; 07193 int copy_msg_result = 0; 07194 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07195 07196 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07197 07198 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07199 if (!cmd) { 07200 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07201 #ifdef IMAP_STORAGE 07202 int attach_user_voicemail; 07203 char *myserveremail = serveremail; 07204 07205 /* get destination mailbox */ 07206 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07207 if (!dstvms) { 07208 dstvms = create_vm_state_from_user(vmtmp); 07209 } 07210 if (dstvms) { 07211 init_mailstream(dstvms, 0); 07212 if (!dstvms->mailstream) { 07213 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07214 } else { 07215 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07216 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07217 } 07218 } else { 07219 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07220 } 07221 if (!ast_strlen_zero(vmtmp->serveremail)) 07222 myserveremail = vmtmp->serveremail; 07223 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07224 /* NULL category for IMAP storage */ 07225 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07226 dstvms->curbox, 07227 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07228 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07229 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07230 NULL, urgent_str); 07231 #else 07232 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07233 #endif 07234 saved_messages++; 07235 AST_LIST_REMOVE_CURRENT(list); 07236 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07237 free_user(vmtmp); 07238 if (res) 07239 break; 07240 } 07241 AST_LIST_TRAVERSE_SAFE_END; 07242 if (saved_messages > 0 && !copy_msg_result) { 07243 /* give confirmation that the message was saved */ 07244 /* commented out since we can't forward batches yet 07245 if (saved_messages == 1) 07246 res = ast_play_and_wait(chan, "vm-message"); 07247 else 07248 res = ast_play_and_wait(chan, "vm-messages"); 07249 if (!res) 07250 res = ast_play_and_wait(chan, "vm-saved"); */ 07251 #ifdef IMAP_STORAGE 07252 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07253 if (ast_strlen_zero(vmstmp.introfn)) 07254 #endif 07255 res = ast_play_and_wait(chan, "vm-msgsaved"); 07256 } 07257 #ifndef IMAP_STORAGE 07258 else { 07259 /* with IMAP, mailbox full warning played by imap_check_limits */ 07260 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07261 } 07262 /* Restore original message without prepended message if backup exists */ 07263 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07264 strcpy(textfile, msgfile); 07265 strcpy(backup, msgfile); 07266 strcpy(backup_textfile, msgfile); 07267 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07268 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07269 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07270 if (ast_fileexists(backup, NULL, NULL) > 0) { 07271 ast_filerename(backup, msgfile, NULL); 07272 rename(backup_textfile, textfile); 07273 } 07274 #endif 07275 } 07276 DISPOSE(dir, curmsg); 07277 #ifndef IMAP_STORAGE 07278 if (cmd) { /* assuming hangup, cleanup backup file */ 07279 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07280 strcpy(textfile, msgfile); 07281 strcpy(backup_textfile, msgfile); 07282 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07283 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07284 rename(backup_textfile, textfile); 07285 } 07286 #endif 07287 } 07288 07289 /* If anything failed above, we still have this list to free */ 07290 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07291 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07292 free_user(vmtmp); 07293 } 07294 return res ? res : cmd; 07295 }
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 11464 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().
11465 { 11466 struct ast_vm_user *current; 11467 AST_LIST_LOCK(&users); 11468 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11469 ast_set_flag(current, VM_ALLOCED); 11470 free_user(current); 11471 } 11472 AST_LIST_UNLOCK(&users); 11473 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11476 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().
11477 { 11478 struct vm_zone *zcur; 11479 AST_LIST_LOCK(&zones); 11480 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11481 free_zone(zcur); 11482 AST_LIST_UNLOCK(&zones); 11483 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4966 of file app_voicemail.c.
References ast_free.
04967 { 04968 ast_free(z); 04969 }
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 4922 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
04923 { 04924 struct ast_tm tm; 04925 struct timeval t = ast_tvnow(); 04926 04927 ast_localtime(&t, &tm, "UTC"); 04928 04929 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04930 }
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 6635 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().
06636 { 06637 int x; 06638 int d; 06639 char fn[PATH_MAX]; 06640 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06641 if (d) 06642 return d; 06643 for (x = start; x < 5; x++) { /* For all folders */ 06644 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06645 return d; 06646 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06647 if (d) 06648 return d; 06649 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06650 d = vm_play_folder_name(chan, fn); 06651 if (d) 06652 return d; 06653 d = ast_waitfordigit(chan, 500); 06654 if (d) 06655 return d; 06656 } 06657 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06658 if (d) 06659 return d; 06660 d = ast_waitfordigit(chan, 4000); 06661 return d; 06662 }
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 6676 of file app_voicemail.c.
References ast_play_and_wait(), and get_folder().
Referenced by vm_execmain().
06677 { 06678 int res = 0; 06679 int loops = 0; 06680 res = ast_play_and_wait(chan, fn); /* Folder name */ 06681 while (((res < '0') || (res > '9')) && 06682 (res != '#') && (res >= 0) && 06683 loops < 4) { 06684 res = get_folder(chan, 0); 06685 loops++; 06686 } 06687 if (loops == 4) { /* give up */ 06688 return '#'; 06689 } 06690 return res; 06691 }
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 11247 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().
11248 { 11249 unsigned int len; 11250 struct mwi_sub *mwi_sub; 11251 struct mwi_sub_task *p = datap; 11252 11253 len = sizeof(*mwi_sub); 11254 if (!ast_strlen_zero(p->mailbox)) 11255 len += strlen(p->mailbox); 11256 11257 if (!ast_strlen_zero(p->context)) 11258 len += strlen(p->context) + 1; /* Allow for seperator */ 11259 11260 if (!(mwi_sub = ast_calloc(1, len))) 11261 return -1; 11262 11263 mwi_sub->uniqueid = p->uniqueid; 11264 if (!ast_strlen_zero(p->mailbox)) 11265 strcpy(mwi_sub->mailbox, p->mailbox); 11266 11267 if (!ast_strlen_zero(p->context)) { 11268 strcat(mwi_sub->mailbox, "@"); 11269 strcat(mwi_sub->mailbox, p->context); 11270 } 11271 11272 AST_RWLIST_WRLOCK(&mwi_subs); 11273 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11274 AST_RWLIST_UNLOCK(&mwi_subs); 11275 ast_free((void *) p->mailbox); 11276 ast_free((void *) p->context); 11277 ast_free(p); 11278 poll_subscribed_mailbox(mwi_sub); 11279 return 0; 11280 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11225 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().
11226 { 11227 struct mwi_sub *mwi_sub; 11228 uint32_t *uniqueid = datap; 11229 11230 AST_RWLIST_WRLOCK(&mwi_subs); 11231 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11232 if (mwi_sub->uniqueid == *uniqueid) { 11233 AST_LIST_REMOVE_CURRENT(entry); 11234 break; 11235 } 11236 } 11237 AST_RWLIST_TRAVERSE_SAFE_END 11238 AST_RWLIST_UNLOCK(&mwi_subs); 11239 11240 if (mwi_sub) 11241 mwi_sub_destroy(mwi_sub); 11242 11243 ast_free(uniqueid); 11244 return 0; 11245 }
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 11000 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.
11001 { 11002 switch (cmd) { 11003 case CLI_INIT: 11004 e->command = "voicemail reload"; 11005 e->usage = 11006 "Usage: voicemail reload\n" 11007 " Reload voicemail configuration\n"; 11008 return NULL; 11009 case CLI_GENERATE: 11010 return NULL; 11011 } 11012 11013 if (a->argc != 2) 11014 return CLI_SHOWUSAGE; 11015 11016 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11017 load_config(1); 11018 11019 return CLI_SUCCESS; 11020 }
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 10890 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.
10891 { 10892 struct ast_vm_user *vmu; 10893 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 10894 const char *context = NULL; 10895 int users_counter = 0; 10896 10897 switch (cmd) { 10898 case CLI_INIT: 10899 e->command = "voicemail show users"; 10900 e->usage = 10901 "Usage: voicemail show users [for <context>]\n" 10902 " Lists all mailboxes currently set up\n"; 10903 return NULL; 10904 case CLI_GENERATE: 10905 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 10906 } 10907 10908 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 10909 return CLI_SHOWUSAGE; 10910 if (a->argc == 5) { 10911 if (strcmp(a->argv[3],"for")) 10912 return CLI_SHOWUSAGE; 10913 context = a->argv[4]; 10914 } 10915 10916 if (ast_check_realtime("voicemail")) { 10917 if (!context) { 10918 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 10919 return CLI_SHOWUSAGE; 10920 } 10921 return show_users_realtime(a->fd, context); 10922 } 10923 10924 AST_LIST_LOCK(&users); 10925 if (AST_LIST_EMPTY(&users)) { 10926 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 10927 AST_LIST_UNLOCK(&users); 10928 return CLI_FAILURE; 10929 } 10930 if (a->argc == 3) 10931 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10932 else { 10933 int count = 0; 10934 AST_LIST_TRAVERSE(&users, vmu, list) { 10935 if (!strcmp(context, vmu->context)) 10936 count++; 10937 } 10938 if (count) { 10939 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10940 } else { 10941 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 10942 AST_LIST_UNLOCK(&users); 10943 return CLI_FAILURE; 10944 } 10945 } 10946 AST_LIST_TRAVERSE(&users, vmu, list) { 10947 int newmsgs = 0, oldmsgs = 0; 10948 char count[12], tmp[256] = ""; 10949 10950 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 10951 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 10952 inboxcount(tmp, &newmsgs, &oldmsgs); 10953 snprintf(count, sizeof(count), "%d", newmsgs); 10954 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 10955 users_counter++; 10956 } 10957 } 10958 AST_LIST_UNLOCK(&users); 10959 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 10960 return CLI_SUCCESS; 10961 }
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 10964 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.
10965 { 10966 struct vm_zone *zone; 10967 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 10968 char *res = CLI_SUCCESS; 10969 10970 switch (cmd) { 10971 case CLI_INIT: 10972 e->command = "voicemail show zones"; 10973 e->usage = 10974 "Usage: voicemail show zones\n" 10975 " Lists zone message formats\n"; 10976 return NULL; 10977 case CLI_GENERATE: 10978 return NULL; 10979 } 10980 10981 if (a->argc != 3) 10982 return CLI_SHOWUSAGE; 10983 10984 AST_LIST_LOCK(&zones); 10985 if (!AST_LIST_EMPTY(&zones)) { 10986 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 10987 AST_LIST_TRAVERSE(&zones, zone, list) { 10988 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 10989 } 10990 } else { 10991 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 10992 res = CLI_FAILURE; 10993 } 10994 AST_LIST_UNLOCK(&zones); 10995 10996 return res; 10997 }
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 5308 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().
05309 { 05310 char tmp[256], *tmp2 = tmp, *box, *context; 05311 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05312 if (ast_strlen_zero(folder)) { 05313 folder = "INBOX"; 05314 } 05315 while ((box = strsep(&tmp2, ",&"))) { 05316 if ((context = strchr(box, '@'))) 05317 *context++ = '\0'; 05318 else 05319 context = "default"; 05320 if (__has_voicemail(context, box, folder, 1)) 05321 return 1; 05322 /* If we are checking INBOX, we should check Urgent as well */ 05323 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05324 return 1; 05325 } 05326 } 05327 return 0; 05328 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5390 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), load_module(), and manager_list_voicemail_users().
05391 { 05392 int urgentmsgs = 0; 05393 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05394 if (newmsgs) { 05395 *newmsgs += urgentmsgs; 05396 } 05397 return res; 05398 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5331 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().
05332 { 05333 char tmp[256]; 05334 char *context; 05335 05336 /* If no mailbox, return immediately */ 05337 if (ast_strlen_zero(mailbox)) 05338 return 0; 05339 05340 if (newmsgs) 05341 *newmsgs = 0; 05342 if (oldmsgs) 05343 *oldmsgs = 0; 05344 if (urgentmsgs) 05345 *urgentmsgs = 0; 05346 05347 if (strchr(mailbox, ',')) { 05348 int tmpnew, tmpold, tmpurgent; 05349 char *mb, *cur; 05350 05351 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05352 mb = tmp; 05353 while ((cur = strsep(&mb, ", "))) { 05354 if (!ast_strlen_zero(cur)) { 05355 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05356 return -1; 05357 else { 05358 if (newmsgs) 05359 *newmsgs += tmpnew; 05360 if (oldmsgs) 05361 *oldmsgs += tmpold; 05362 if (urgentmsgs) 05363 *urgentmsgs += tmpurgent; 05364 } 05365 } 05366 } 05367 return 0; 05368 } 05369 05370 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05371 05372 if ((context = strchr(tmp, '@'))) 05373 *context++ = '\0'; 05374 else 05375 context = "default"; 05376 05377 if (newmsgs) 05378 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05379 if (oldmsgs) 05380 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05381 if (urgentmsgs) 05382 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05383 05384 return 0; 05385 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4094 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().
04095 { 04096 int l; 04097 04098 if (bio->ateof) 04099 return 0; 04100 04101 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04102 if (ferror(fi)) 04103 return -1; 04104 04105 bio->ateof = 1; 04106 return 0; 04107 } 04108 04109 bio->iolen = l; 04110 bio->iocp = 0; 04111 04112 return 1; 04113 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4118 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
04119 { 04120 if (bio->iocp>=bio->iolen) { 04121 if (!inbuf(bio, fi)) 04122 return EOF; 04123 } 04124 04125 return bio->iobuf[bio->iocp++]; 04126 }
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 4932 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.
04933 { 04934 int res; 04935 char fn[PATH_MAX]; 04936 char dest[PATH_MAX]; 04937 04938 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04939 04940 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04941 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04942 return -1; 04943 } 04944 04945 RETRIEVE(fn, -1, ext, context); 04946 if (ast_fileexists(fn, NULL, NULL) > 0) { 04947 res = ast_stream_and_wait(chan, fn, ecodes); 04948 if (res) { 04949 DISPOSE(fn, -1); 04950 return res; 04951 } 04952 } else { 04953 /* Dispose just in case */ 04954 DISPOSE(fn, -1); 04955 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04956 if (res) 04957 return res; 04958 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04959 if (res) 04960 return res; 04961 } 04962 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04963 return res; 04964 }
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 ast_debug, 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 char extension[4]; 03920 int stopcount = 0; 03921 03922 /* Reading the entire directory into a file map scales better than 03923 * doing a stat repeatedly on a predicted sequence. I suspect this 03924 * is partially due to stat(2) internally doing a readdir(2) itself to 03925 * find each file. */ 03926 if (!(msgdir = opendir(dir))) { 03927 return -1; 03928 } 03929 03930 while ((msgdirent = readdir(msgdir))) { 03931 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 03932 map[msgdirint] = 1; 03933 stopcount++; 03934 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 03935 } 03936 } 03937 closedir(msgdir); 03938 03939 for (x = 0; x < vmu->maxmsg; x++) { 03940 if (map[x] == 1) { 03941 stopcount--; 03942 } else if (map[x] == 0 && !stopcount) { 03943 break; 03944 } 03945 } 03946 03947 return x - 1; 03948 }
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 5463 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.
05464 { 05465 #ifdef IMAP_STORAGE 05466 int newmsgs, oldmsgs; 05467 #else 05468 char urgdir[PATH_MAX]; 05469 #endif 05470 char txtfile[PATH_MAX]; 05471 char tmptxtfile[PATH_MAX]; 05472 struct vm_state *vms = NULL; 05473 char callerid[256]; 05474 FILE *txt; 05475 char date[256]; 05476 int txtdes; 05477 int res = 0; 05478 int msgnum; 05479 int duration = 0; 05480 int ausemacro = 0; 05481 int ousemacro = 0; 05482 int ouseexten = 0; 05483 char tmpdur[16]; 05484 char priority[16]; 05485 char origtime[16]; 05486 char dir[PATH_MAX]; 05487 char tmpdir[PATH_MAX]; 05488 char fn[PATH_MAX]; 05489 char prefile[PATH_MAX] = ""; 05490 char tempfile[PATH_MAX] = ""; 05491 char ext_context[256] = ""; 05492 char fmt[80]; 05493 char *context; 05494 char ecodes[17] = "#"; 05495 struct ast_str *tmp = ast_str_create(16); 05496 char *tmpptr; 05497 struct ast_vm_user *vmu; 05498 struct ast_vm_user svm; 05499 const char *category = NULL; 05500 const char *code; 05501 const char *alldtmf = "0123456789ABCD*#"; 05502 char flag[80]; 05503 05504 if (!tmp) { 05505 return -1; 05506 } 05507 05508 ast_str_set(&tmp, 0, "%s", ext); 05509 ext = ast_str_buffer(tmp); 05510 if ((context = strchr(ext, '@'))) { 05511 *context++ = '\0'; 05512 tmpptr = strchr(context, '&'); 05513 } else { 05514 tmpptr = strchr(ext, '&'); 05515 } 05516 05517 if (tmpptr) 05518 *tmpptr++ = '\0'; 05519 05520 ast_channel_lock(chan); 05521 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05522 category = ast_strdupa(category); 05523 } 05524 ast_channel_unlock(chan); 05525 05526 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05527 ast_copy_string(flag, "Urgent", sizeof(flag)); 05528 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05529 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05530 } else { 05531 flag[0] = '\0'; 05532 } 05533 05534 ast_debug(3, "Before find_user\n"); 05535 if (!(vmu = find_user(&svm, context, ext))) { 05536 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05537 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05538 ast_free(tmp); 05539 return res; 05540 } 05541 /* Setup pre-file if appropriate */ 05542 if (strcmp(vmu->context, "default")) 05543 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05544 else 05545 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05546 05547 /* Set the path to the prefile. Will be one of 05548 VM_SPOOL_DIRcontext/ext/busy 05549 VM_SPOOL_DIRcontext/ext/unavail 05550 Depending on the flag set in options. 05551 */ 05552 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05553 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05554 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05555 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05556 } 05557 /* Set the path to the tmpfile as 05558 VM_SPOOL_DIR/context/ext/temp 05559 and attempt to create the folder structure. 05560 */ 05561 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05562 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05563 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05564 ast_free(tmp); 05565 return -1; 05566 } 05567 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05568 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05569 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05570 05571 DISPOSE(tempfile, -1); 05572 /* It's easier just to try to make it than to check for its existence */ 05573 #ifndef IMAP_STORAGE 05574 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05575 #else 05576 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05577 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05578 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05579 } 05580 #endif 05581 05582 /* Check current or macro-calling context for special extensions */ 05583 if (ast_test_flag(vmu, VM_OPERATOR)) { 05584 if (!ast_strlen_zero(vmu->exit)) { 05585 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05586 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05587 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05588 ouseexten = 1; 05589 } 05590 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05591 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05592 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05593 ouseexten = 1; 05594 } else if (!ast_strlen_zero(chan->macrocontext) 05595 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05596 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05597 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05598 ousemacro = 1; 05599 } 05600 } 05601 05602 if (!ast_strlen_zero(vmu->exit)) { 05603 if (ast_exists_extension(chan, vmu->exit, "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 } 05607 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05608 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05609 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05610 } else if (!ast_strlen_zero(chan->macrocontext) 05611 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05612 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05613 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05614 ausemacro = 1; 05615 } 05616 05617 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05618 for (code = alldtmf; *code; code++) { 05619 char e[2] = ""; 05620 e[0] = *code; 05621 if (strchr(ecodes, e[0]) == NULL 05622 && ast_canmatch_extension(chan, chan->context, e, 1, 05623 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05624 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05625 } 05626 } 05627 } 05628 05629 /* Play the beginning intro if desired */ 05630 if (!ast_strlen_zero(prefile)) { 05631 #ifdef ODBC_STORAGE 05632 int success = 05633 #endif 05634 RETRIEVE(prefile, -1, ext, context); 05635 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05636 if (ast_streamfile(chan, prefile, chan->language) > -1) 05637 res = ast_waitstream(chan, ecodes); 05638 #ifdef ODBC_STORAGE 05639 if (success == -1) { 05640 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05641 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05642 store_file(prefile, vmu->mailbox, vmu->context, -1); 05643 } 05644 #endif 05645 } else { 05646 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05647 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05648 } 05649 DISPOSE(prefile, -1); 05650 if (res < 0) { 05651 ast_debug(1, "Hang up during prefile playback\n"); 05652 free_user(vmu); 05653 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05654 ast_free(tmp); 05655 return -1; 05656 } 05657 } 05658 if (res == '#') { 05659 /* On a '#' we skip the instructions */ 05660 ast_set_flag(options, OPT_SILENT); 05661 res = 0; 05662 } 05663 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05664 if (vmu->maxmsg == 0) { 05665 if (option_debug > 2) 05666 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05667 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05668 goto leave_vm_out; 05669 } 05670 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05671 res = ast_stream_and_wait(chan, INTRO, ecodes); 05672 if (res == '#') { 05673 ast_set_flag(options, OPT_SILENT); 05674 res = 0; 05675 } 05676 } 05677 if (res > 0) 05678 ast_stopstream(chan); 05679 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05680 other than the operator -- an automated attendant or mailbox login for example */ 05681 if (res == '*') { 05682 chan->exten[0] = 'a'; 05683 chan->exten[1] = '\0'; 05684 if (!ast_strlen_zero(vmu->exit)) { 05685 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05686 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05687 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05688 } 05689 chan->priority = 0; 05690 free_user(vmu); 05691 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05692 ast_free(tmp); 05693 return 0; 05694 } 05695 05696 /* Check for a '0' here */ 05697 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05698 transfer: 05699 if (ouseexten || ousemacro) { 05700 chan->exten[0] = 'o'; 05701 chan->exten[1] = '\0'; 05702 if (!ast_strlen_zero(vmu->exit)) { 05703 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05704 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05705 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05706 } 05707 ast_play_and_wait(chan, "transfer"); 05708 chan->priority = 0; 05709 free_user(vmu); 05710 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05711 } 05712 ast_free(tmp); 05713 return OPERATOR_EXIT; 05714 } 05715 05716 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05717 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05718 if (!ast_strlen_zero(options->exitcontext)) 05719 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05720 free_user(vmu); 05721 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05722 ast_free(tmp); 05723 return res; 05724 } 05725 05726 if (res < 0) { 05727 free_user(vmu); 05728 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05729 ast_free(tmp); 05730 return -1; 05731 } 05732 /* The meat of recording the message... All the announcements and beeps have been played*/ 05733 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05734 if (!ast_strlen_zero(fmt)) { 05735 msgnum = 0; 05736 05737 #ifdef IMAP_STORAGE 05738 /* Is ext a mailbox? */ 05739 /* must open stream for this user to get info! */ 05740 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05741 if (res < 0) { 05742 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05743 ast_free(tmp); 05744 return -1; 05745 } 05746 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05747 /* It is possible under certain circumstances that inboxcount did not 05748 * create a vm_state when it was needed. This is a catchall which will 05749 * rarely be used. 05750 */ 05751 if (!(vms = create_vm_state_from_user(vmu))) { 05752 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05753 ast_free(tmp); 05754 return -1; 05755 } 05756 } 05757 vms->newmessages++; 05758 05759 /* here is a big difference! We add one to it later */ 05760 msgnum = newmsgs + oldmsgs; 05761 ast_debug(3, "Messagecount set to %d\n", msgnum); 05762 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05763 /* set variable for compatibility */ 05764 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05765 05766 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05767 goto leave_vm_out; 05768 } 05769 #else 05770 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05771 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05772 if (!res) 05773 res = ast_waitstream(chan, ""); 05774 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05775 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05776 inprocess_count(vmu->mailbox, vmu->context, -1); 05777 goto leave_vm_out; 05778 } 05779 05780 #endif 05781 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05782 txtdes = mkstemp(tmptxtfile); 05783 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05784 if (txtdes < 0) { 05785 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05786 if (!res) 05787 res = ast_waitstream(chan, ""); 05788 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05789 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05790 inprocess_count(vmu->mailbox, vmu->context, -1); 05791 goto leave_vm_out; 05792 } 05793 05794 /* Now play the beep once we have the message number for our next message. */ 05795 if (res >= 0) { 05796 /* Unless we're *really* silent, try to send the beep */ 05797 res = ast_stream_and_wait(chan, "beep", ""); 05798 } 05799 05800 /* Store information in real-time storage */ 05801 if (ast_check_realtime("voicemail_data")) { 05802 snprintf(priority, sizeof(priority), "%d", chan->priority); 05803 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05804 get_date(date, sizeof(date)); 05805 ast_callerid_merge(callerid, sizeof(callerid), 05806 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05807 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05808 "Unknown"); 05809 ast_store_realtime("voicemail_data", 05810 "origmailbox", ext, 05811 "context", chan->context, 05812 "macrocontext", chan->macrocontext, 05813 "exten", chan->exten, 05814 "priority", priority, 05815 "callerchan", chan->name, 05816 "callerid", callerid, 05817 "origdate", date, 05818 "origtime", origtime, 05819 "category", S_OR(category, ""), 05820 "filename", tmptxtfile, 05821 SENTINEL); 05822 } 05823 05824 /* Store information */ 05825 txt = fdopen(txtdes, "w+"); 05826 if (txt) { 05827 get_date(date, sizeof(date)); 05828 ast_callerid_merge(callerid, sizeof(callerid), 05829 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05830 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05831 "Unknown"); 05832 fprintf(txt, 05833 ";\n" 05834 "; Message Information file\n" 05835 ";\n" 05836 "[message]\n" 05837 "origmailbox=%s\n" 05838 "context=%s\n" 05839 "macrocontext=%s\n" 05840 "exten=%s\n" 05841 "rdnis=%s\n" 05842 "priority=%d\n" 05843 "callerchan=%s\n" 05844 "callerid=%s\n" 05845 "origdate=%s\n" 05846 "origtime=%ld\n" 05847 "category=%s\n", 05848 ext, 05849 chan->context, 05850 chan->macrocontext, 05851 chan->exten, 05852 S_COR(chan->redirecting.from.number.valid, 05853 chan->redirecting.from.number.str, "unknown"), 05854 chan->priority, 05855 chan->name, 05856 callerid, 05857 date, (long) time(NULL), 05858 category ? category : ""); 05859 } else { 05860 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05861 inprocess_count(vmu->mailbox, vmu->context, -1); 05862 if (ast_check_realtime("voicemail_data")) { 05863 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05864 } 05865 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05866 goto leave_vm_out; 05867 } 05868 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05869 05870 if (txt) { 05871 fprintf(txt, "flag=%s\n", flag); 05872 if (duration < vmu->minsecs) { 05873 fclose(txt); 05874 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmu->minsecs); 05875 ast_filedelete(tmptxtfile, NULL); 05876 unlink(tmptxtfile); 05877 if (ast_check_realtime("voicemail_data")) { 05878 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05879 } 05880 inprocess_count(vmu->mailbox, vmu->context, -1); 05881 } else { 05882 fprintf(txt, "duration=%d\n", duration); 05883 fclose(txt); 05884 if (vm_lock_path(dir)) { 05885 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05886 /* Delete files */ 05887 ast_filedelete(tmptxtfile, NULL); 05888 unlink(tmptxtfile); 05889 inprocess_count(vmu->mailbox, vmu->context, -1); 05890 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05891 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05892 unlink(tmptxtfile); 05893 ast_unlock_path(dir); 05894 inprocess_count(vmu->mailbox, vmu->context, -1); 05895 if (ast_check_realtime("voicemail_data")) { 05896 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05897 } 05898 } else { 05899 #ifndef IMAP_STORAGE 05900 msgnum = last_message_index(vmu, dir) + 1; 05901 #endif 05902 make_file(fn, sizeof(fn), dir, msgnum); 05903 05904 /* assign a variable with the name of the voicemail file */ 05905 #ifndef IMAP_STORAGE 05906 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05907 #else 05908 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05909 #endif 05910 05911 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05912 ast_filerename(tmptxtfile, fn, NULL); 05913 rename(tmptxtfile, txtfile); 05914 inprocess_count(vmu->mailbox, vmu->context, -1); 05915 05916 /* Properly set permissions on voicemail text descriptor file. 05917 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05918 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05919 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05920 05921 ast_unlock_path(dir); 05922 if (ast_check_realtime("voicemail_data")) { 05923 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05924 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 05925 } 05926 /* We must store the file first, before copying the message, because 05927 * ODBC storage does the entire copy with SQL. 05928 */ 05929 if (ast_fileexists(fn, NULL, NULL) > 0) { 05930 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05931 } 05932 05933 /* Are there to be more recipients of this message? */ 05934 while (tmpptr) { 05935 struct ast_vm_user recipu, *recip; 05936 char *exten, *cntx; 05937 05938 exten = strsep(&tmpptr, "&"); 05939 cntx = strchr(exten, '@'); 05940 if (cntx) { 05941 *cntx = '\0'; 05942 cntx++; 05943 } 05944 if ((recip = find_user(&recipu, cntx, exten))) { 05945 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05946 free_user(recip); 05947 } 05948 } 05949 #ifndef IMAP_STORAGE 05950 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05951 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05952 char sfn[PATH_MAX]; 05953 char dfn[PATH_MAX]; 05954 int x; 05955 /* It's easier just to try to make it than to check for its existence */ 05956 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05957 x = last_message_index(vmu, urgdir) + 1; 05958 make_file(sfn, sizeof(sfn), dir, msgnum); 05959 make_file(dfn, sizeof(dfn), urgdir, x); 05960 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 05961 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05962 /* Notification must happen for this new message in Urgent folder, not INBOX */ 05963 ast_copy_string(fn, dfn, sizeof(fn)); 05964 msgnum = x; 05965 } 05966 #endif 05967 /* Notification needs to happen after the copy, though. */ 05968 if (ast_fileexists(fn, NULL, NULL)) { 05969 #ifdef IMAP_STORAGE 05970 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 05971 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05972 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05973 flag); 05974 #else 05975 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 05976 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05977 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05978 flag); 05979 #endif 05980 } 05981 05982 /* Disposal needs to happen after the optional move and copy */ 05983 if (ast_fileexists(fn, NULL, NULL)) { 05984 DISPOSE(dir, msgnum); 05985 } 05986 } 05987 } 05988 } else { 05989 inprocess_count(vmu->mailbox, vmu->context, -1); 05990 } 05991 if (res == '0') { 05992 goto transfer; 05993 } else if (res > 0 && res != 't') 05994 res = 0; 05995 05996 if (duration < vmu->minsecs) 05997 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05998 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05999 else 06000 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06001 } else 06002 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06003 leave_vm_out: 06004 free_user(vmu); 06005 06006 #ifdef IMAP_STORAGE 06007 /* expunge message - use UID Expunge if supported on IMAP server*/ 06008 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06009 if (expungeonhangup == 1) { 06010 ast_mutex_lock(&vms->lock); 06011 #ifdef HAVE_IMAP_TK2006 06012 if (LEVELUIDPLUS (vms->mailstream)) { 06013 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06014 } else 06015 #endif 06016 mail_expunge(vms->mailstream); 06017 ast_mutex_unlock(&vms->lock); 06018 } 06019 #endif 06020 06021 ast_free(tmp); 06022 return res; 06023 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11529 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.
11530 { 11531 struct ast_vm_user *current; 11532 struct ast_config *cfg, *ucfg; 11533 char *cat; 11534 struct ast_variable *var; 11535 const char *val; 11536 char *q, *stringp, *tmp; 11537 int x; 11538 int tmpadsi[4]; 11539 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11540 char secretfn[PATH_MAX] = ""; 11541 11542 ast_unload_realtime("voicemail"); 11543 ast_unload_realtime("voicemail_data"); 11544 11545 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11546 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11547 return 0; 11548 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11549 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11550 ucfg = NULL; 11551 } 11552 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11553 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11554 ast_config_destroy(ucfg); 11555 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11556 return 0; 11557 } 11558 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11559 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11560 return 0; 11561 } else { 11562 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11563 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11564 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11565 ucfg = NULL; 11566 } 11567 } 11568 #ifdef IMAP_STORAGE 11569 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11570 #endif 11571 /* set audio control prompts */ 11572 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11573 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11574 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11575 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11576 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11577 11578 /* Free all the users structure */ 11579 free_vm_users(); 11580 11581 /* Free all the zones structure */ 11582 free_vm_zones(); 11583 11584 AST_LIST_LOCK(&users); 11585 11586 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11587 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11588 11589 if (cfg) { 11590 /* General settings */ 11591 11592 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11593 val = "default"; 11594 ast_copy_string(userscontext, val, sizeof(userscontext)); 11595 /* Attach voice message to mail message ? */ 11596 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11597 val = "yes"; 11598 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11599 11600 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11601 val = "no"; 11602 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11603 11604 volgain = 0.0; 11605 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11606 sscanf(val, "%30lf", &volgain); 11607 11608 #ifdef ODBC_STORAGE 11609 strcpy(odbc_database, "asterisk"); 11610 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11611 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11612 } 11613 strcpy(odbc_table, "voicemessages"); 11614 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11615 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11616 } 11617 #endif 11618 /* Mail command */ 11619 strcpy(mailcmd, SENDMAIL); 11620 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11621 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11622 11623 maxsilence = 0; 11624 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11625 maxsilence = atoi(val); 11626 if (maxsilence > 0) 11627 maxsilence *= 1000; 11628 } 11629 11630 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11631 maxmsg = MAXMSG; 11632 } else { 11633 maxmsg = atoi(val); 11634 if (maxmsg < 0) { 11635 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11636 maxmsg = MAXMSG; 11637 } else if (maxmsg > MAXMSGLIMIT) { 11638 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11639 maxmsg = MAXMSGLIMIT; 11640 } 11641 } 11642 11643 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11644 maxdeletedmsg = 0; 11645 } else { 11646 if (sscanf(val, "%30d", &x) == 1) 11647 maxdeletedmsg = x; 11648 else if (ast_true(val)) 11649 maxdeletedmsg = MAXMSG; 11650 else 11651 maxdeletedmsg = 0; 11652 11653 if (maxdeletedmsg < 0) { 11654 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11655 maxdeletedmsg = MAXMSG; 11656 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11657 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11658 maxdeletedmsg = MAXMSGLIMIT; 11659 } 11660 } 11661 11662 /* Load date format config for voicemail mail */ 11663 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11664 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11665 } 11666 11667 /* Load date format config for voicemail pager mail */ 11668 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11669 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11670 } 11671 11672 /* External password changing command */ 11673 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11674 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11675 pwdchange = PWDCHANGE_EXTERNAL; 11676 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11677 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11678 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11679 } 11680 11681 /* External password validation command */ 11682 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11683 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11684 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11685 } 11686 11687 #ifdef IMAP_STORAGE 11688 /* IMAP server address */ 11689 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11690 ast_copy_string(imapserver, val, sizeof(imapserver)); 11691 } else { 11692 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11693 } 11694 /* IMAP server port */ 11695 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11696 ast_copy_string(imapport, val, sizeof(imapport)); 11697 } else { 11698 ast_copy_string(imapport, "143", sizeof(imapport)); 11699 } 11700 /* IMAP server flags */ 11701 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11702 ast_copy_string(imapflags, val, sizeof(imapflags)); 11703 } 11704 /* IMAP server master username */ 11705 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11706 ast_copy_string(authuser, val, sizeof(authuser)); 11707 } 11708 /* IMAP server master password */ 11709 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11710 ast_copy_string(authpassword, val, sizeof(authpassword)); 11711 } 11712 /* Expunge on exit */ 11713 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11714 if (ast_false(val)) 11715 expungeonhangup = 0; 11716 else 11717 expungeonhangup = 1; 11718 } else { 11719 expungeonhangup = 1; 11720 } 11721 /* IMAP voicemail folder */ 11722 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11723 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 11724 } else { 11725 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 11726 } 11727 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 11728 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 11729 } 11730 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 11731 imapgreetings = ast_true(val); 11732 } else { 11733 imapgreetings = 0; 11734 } 11735 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 11736 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11737 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 11738 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 11739 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11740 } else { 11741 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 11742 } 11743 11744 /* There is some very unorthodox casting done here. This is due 11745 * to the way c-client handles the argument passed in. It expects a 11746 * void pointer and casts the pointer directly to a long without 11747 * first dereferencing it. */ 11748 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 11749 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 11750 } else { 11751 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 11752 } 11753 11754 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 11755 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 11756 } else { 11757 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 11758 } 11759 11760 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 11761 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 11762 } else { 11763 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 11764 } 11765 11766 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 11767 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 11768 } else { 11769 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 11770 } 11771 11772 /* Increment configuration version */ 11773 imapversion++; 11774 #endif 11775 /* External voicemail notify application */ 11776 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 11777 ast_copy_string(externnotify, val, sizeof(externnotify)); 11778 ast_debug(1, "found externnotify: %s\n", externnotify); 11779 } else { 11780 externnotify[0] = '\0'; 11781 } 11782 11783 /* SMDI voicemail notification */ 11784 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 11785 ast_debug(1, "Enabled SMDI voicemail notification\n"); 11786 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 11787 smdi_iface = ast_smdi_interface_find(val); 11788 } else { 11789 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 11790 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 11791 } 11792 if (!smdi_iface) { 11793 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 11794 } 11795 } 11796 11797 /* Silence treshold */ 11798 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 11799 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 11800 silencethreshold = atoi(val); 11801 11802 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 11803 val = ASTERISK_USERNAME; 11804 ast_copy_string(serveremail, val, sizeof(serveremail)); 11805 11806 vmmaxsecs = 0; 11807 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 11808 if (sscanf(val, "%30d", &x) == 1) { 11809 vmmaxsecs = x; 11810 } else { 11811 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 11812 } 11813 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 11814 static int maxmessage_deprecate = 0; 11815 if (maxmessage_deprecate == 0) { 11816 maxmessage_deprecate = 1; 11817 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 11818 } 11819 if (sscanf(val, "%30d", &x) == 1) { 11820 vmmaxsecs = x; 11821 } else { 11822 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 11823 } 11824 } 11825 11826 vmminsecs = 0; 11827 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 11828 if (sscanf(val, "%30d", &x) == 1) { 11829 vmminsecs = x; 11830 if (maxsilence / 1000 >= vmminsecs) { 11831 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 11832 } 11833 } else { 11834 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 11835 } 11836 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 11837 static int maxmessage_deprecate = 0; 11838 if (maxmessage_deprecate == 0) { 11839 maxmessage_deprecate = 1; 11840 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 11841 } 11842 if (sscanf(val, "%30d", &x) == 1) { 11843 vmminsecs = x; 11844 if (maxsilence / 1000 >= vmminsecs) { 11845 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 11846 } 11847 } else { 11848 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 11849 } 11850 } 11851 11852 val = ast_variable_retrieve(cfg, "general", "format"); 11853 if (!val) { 11854 val = "wav"; 11855 } else { 11856 tmp = ast_strdupa(val); 11857 val = ast_format_str_reduce(tmp); 11858 if (!val) { 11859 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 11860 val = "wav"; 11861 } 11862 } 11863 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 11864 11865 skipms = 3000; 11866 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 11867 if (sscanf(val, "%30d", &x) == 1) { 11868 maxgreet = x; 11869 } else { 11870 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 11871 } 11872 } 11873 11874 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 11875 if (sscanf(val, "%30d", &x) == 1) { 11876 skipms = x; 11877 } else { 11878 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 11879 } 11880 } 11881 11882 maxlogins = 3; 11883 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 11884 if (sscanf(val, "%30d", &x) == 1) { 11885 maxlogins = x; 11886 } else { 11887 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 11888 } 11889 } 11890 11891 minpassword = MINPASSWORD; 11892 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 11893 if (sscanf(val, "%30d", &x) == 1) { 11894 minpassword = x; 11895 } else { 11896 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 11897 } 11898 } 11899 11900 /* Force new user to record name ? */ 11901 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 11902 val = "no"; 11903 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 11904 11905 /* Force new user to record greetings ? */ 11906 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 11907 val = "no"; 11908 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 11909 11910 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 11911 ast_debug(1, "VM_CID Internal context string: %s\n", val); 11912 stringp = ast_strdupa(val); 11913 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 11914 if (!ast_strlen_zero(stringp)) { 11915 q = strsep(&stringp, ","); 11916 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 11917 q++; 11918 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 11919 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 11920 } else { 11921 cidinternalcontexts[x][0] = '\0'; 11922 } 11923 } 11924 } 11925 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 11926 ast_debug(1, "VM Review Option disabled globally\n"); 11927 val = "no"; 11928 } 11929 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 11930 11931 /* Temporary greeting reminder */ 11932 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 11933 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 11934 val = "no"; 11935 } else { 11936 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 11937 } 11938 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 11939 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 11940 ast_debug(1, "VM next message wrap disabled globally\n"); 11941 val = "no"; 11942 } 11943 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 11944 11945 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 11946 ast_debug(1, "VM Operator break disabled globally\n"); 11947 val = "no"; 11948 } 11949 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 11950 11951 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 11952 ast_debug(1, "VM CID Info before msg disabled globally\n"); 11953 val = "no"; 11954 } 11955 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 11956 11957 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 11958 ast_debug(1, "Send Voicemail msg disabled globally\n"); 11959 val = "no"; 11960 } 11961 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 11962 11963 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 11964 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 11965 val = "yes"; 11966 } 11967 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 11968 11969 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 11970 ast_debug(1, "Move Heard enabled globally\n"); 11971 val = "yes"; 11972 } 11973 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 11974 11975 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 11976 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 11977 val = "no"; 11978 } 11979 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 11980 11981 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 11982 ast_debug(1, "Duration info before msg enabled globally\n"); 11983 val = "yes"; 11984 } 11985 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 11986 11987 saydurationminfo = 2; 11988 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 11989 if (sscanf(val, "%30d", &x) == 1) { 11990 saydurationminfo = x; 11991 } else { 11992 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 11993 } 11994 } 11995 11996 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 11997 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 11998 val = "no"; 11999 } 12000 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12001 12002 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12003 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12004 ast_debug(1, "found dialout context: %s\n", dialcontext); 12005 } else { 12006 dialcontext[0] = '\0'; 12007 } 12008 12009 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12010 ast_copy_string(callcontext, val, sizeof(callcontext)); 12011 ast_debug(1, "found callback context: %s\n", callcontext); 12012 } else { 12013 callcontext[0] = '\0'; 12014 } 12015 12016 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12017 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12018 ast_debug(1, "found operator context: %s\n", exitcontext); 12019 } else { 12020 exitcontext[0] = '\0'; 12021 } 12022 12023 /* load password sounds configuration */ 12024 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12025 ast_copy_string(vm_password, val, sizeof(vm_password)); 12026 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12027 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12028 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12029 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12030 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12031 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12032 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12033 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12034 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12035 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12036 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12037 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12038 } 12039 /* load configurable audio prompts */ 12040 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12041 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12042 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12043 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12044 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12045 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12046 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12047 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12048 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12049 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12050 12051 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12052 val = "no"; 12053 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12054 12055 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12056 val = "voicemail.conf"; 12057 } 12058 if (!(strcmp(val, "spooldir"))) { 12059 passwordlocation = OPT_PWLOC_SPOOLDIR; 12060 } else { 12061 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12062 } 12063 12064 poll_freq = DEFAULT_POLL_FREQ; 12065 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12066 if (sscanf(val, "%30u", &poll_freq) != 1) { 12067 poll_freq = DEFAULT_POLL_FREQ; 12068 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12069 } 12070 } 12071 12072 poll_mailboxes = 0; 12073 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12074 poll_mailboxes = ast_true(val); 12075 12076 if (ucfg) { 12077 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12078 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12079 continue; 12080 if ((current = find_or_create(userscontext, cat))) { 12081 populate_defaults(current); 12082 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12083 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12084 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12085 current->passwordlocation = OPT_PWLOC_USERSCONF; 12086 } 12087 12088 switch (current->passwordlocation) { 12089 case OPT_PWLOC_SPOOLDIR: 12090 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12091 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12092 } 12093 } 12094 } 12095 ast_config_destroy(ucfg); 12096 } 12097 cat = ast_category_browse(cfg, NULL); 12098 while (cat) { 12099 if (strcasecmp(cat, "general")) { 12100 var = ast_variable_browse(cfg, cat); 12101 if (strcasecmp(cat, "zonemessages")) { 12102 /* Process mailboxes in this context */ 12103 while (var) { 12104 append_mailbox(cat, var->name, var->value); 12105 var = var->next; 12106 } 12107 } else { 12108 /* Timezones in this context */ 12109 while (var) { 12110 struct vm_zone *z; 12111 if ((z = ast_malloc(sizeof(*z)))) { 12112 char *msg_format, *tzone; 12113 msg_format = ast_strdupa(var->value); 12114 tzone = strsep(&msg_format, "|,"); 12115 if (msg_format) { 12116 ast_copy_string(z->name, var->name, sizeof(z->name)); 12117 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12118 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12119 AST_LIST_LOCK(&zones); 12120 AST_LIST_INSERT_HEAD(&zones, z, list); 12121 AST_LIST_UNLOCK(&zones); 12122 } else { 12123 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12124 ast_free(z); 12125 } 12126 } else { 12127 AST_LIST_UNLOCK(&users); 12128 ast_config_destroy(cfg); 12129 return -1; 12130 } 12131 var = var->next; 12132 } 12133 } 12134 } 12135 cat = ast_category_browse(cfg, cat); 12136 } 12137 memset(fromstring, 0, sizeof(fromstring)); 12138 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12139 strcpy(charset, "ISO-8859-1"); 12140 if (emailbody) { 12141 ast_free(emailbody); 12142 emailbody = NULL; 12143 } 12144 if (emailsubject) { 12145 ast_free(emailsubject); 12146 emailsubject = NULL; 12147 } 12148 if (pagerbody) { 12149 ast_free(pagerbody); 12150 pagerbody = NULL; 12151 } 12152 if (pagersubject) { 12153 ast_free(pagersubject); 12154 pagersubject = NULL; 12155 } 12156 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12157 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12158 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12159 ast_copy_string(fromstring, val, sizeof(fromstring)); 12160 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12161 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12162 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12163 ast_copy_string(charset, val, sizeof(charset)); 12164 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12165 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12166 for (x = 0; x < 4; x++) { 12167 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12168 } 12169 } 12170 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12171 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12172 for (x = 0; x < 4; x++) { 12173 memcpy(&adsisec[x], &tmpadsi[x], 1); 12174 } 12175 } 12176 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12177 if (atoi(val)) { 12178 adsiver = atoi(val); 12179 } 12180 } 12181 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12182 ast_copy_string(zonetag, val, sizeof(zonetag)); 12183 } 12184 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12185 ast_copy_string(locale, val, sizeof(locale)); 12186 } 12187 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12188 emailsubject = ast_strdup(val); 12189 } 12190 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12191 emailbody = ast_strdup(substitute_escapes(val)); 12192 } 12193 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12194 pagersubject = ast_strdup(val); 12195 } 12196 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12197 pagerbody = ast_strdup(substitute_escapes(val)); 12198 } 12199 AST_LIST_UNLOCK(&users); 12200 ast_config_destroy(cfg); 12201 12202 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12203 start_poll_thread(); 12204 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12205 stop_poll_thread();; 12206 12207 return 0; 12208 } else { 12209 AST_LIST_UNLOCK(&users); 12210 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12211 if (ucfg) 12212 ast_config_destroy(ucfg); 12213 return 0; 12214 } 12215 }
static int load_module | ( | void | ) | [static] |
Definition at line 12707 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().
12708 { 12709 int res; 12710 my_umask = umask(0); 12711 umask(my_umask); 12712 12713 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 12714 return AST_MODULE_LOAD_DECLINE; 12715 } 12716 12717 /* compute the location of the voicemail spool directory */ 12718 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 12719 12720 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 12721 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 12722 } 12723 12724 if ((res = load_config(0))) 12725 return res; 12726 12727 res = ast_register_application_xml(app, vm_exec); 12728 res |= ast_register_application_xml(app2, vm_execmain); 12729 res |= ast_register_application_xml(app3, vm_box_exists); 12730 res |= ast_register_application_xml(app4, vmauthenticate); 12731 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 12732 res |= ast_custom_function_register(&mailbox_exists_acf); 12733 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 12734 #ifdef TEST_FRAMEWORK 12735 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 12736 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 12737 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 12738 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 12739 #endif 12740 12741 if (res) 12742 return res; 12743 12744 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 12745 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 12746 12747 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 12748 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 12749 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 12750 12751 return res; 12752 }
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 4411 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().
04412 { 04413 char date[256]; 04414 char host[MAXHOSTNAMELEN] = ""; 04415 char who[256]; 04416 char bound[256]; 04417 char dur[256]; 04418 struct ast_tm tm; 04419 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04420 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04421 char *greeting_attachment; 04422 char filename[256]; 04423 04424 if (!str1 || !str2) { 04425 ast_free(str1); 04426 ast_free(str2); 04427 return; 04428 } 04429 04430 if (cidnum) { 04431 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04432 } 04433 if (cidname) { 04434 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04435 } 04436 gethostname(host, sizeof(host) - 1); 04437 04438 if (strchr(srcemail, '@')) { 04439 ast_copy_string(who, srcemail, sizeof(who)); 04440 } else { 04441 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04442 } 04443 04444 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04445 if (greeting_attachment) { 04446 *greeting_attachment++ = '\0'; 04447 } 04448 04449 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04450 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04451 fprintf(p, "Date: %s" ENDL, date); 04452 04453 /* Set date format for voicemail mail */ 04454 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04455 04456 if (!ast_strlen_zero(fromstring)) { 04457 struct ast_channel *ast; 04458 if ((ast = ast_dummy_channel_alloc())) { 04459 char *ptr; 04460 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04461 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04462 04463 if (check_mime(ast_str_buffer(str1))) { 04464 int first_line = 1; 04465 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04466 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04467 *ptr = '\0'; 04468 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04469 first_line = 0; 04470 /* Substring is smaller, so this will never grow */ 04471 ast_str_set(&str2, 0, "%s", ptr + 1); 04472 } 04473 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04474 } else { 04475 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04476 } 04477 ast = ast_channel_release(ast); 04478 } else { 04479 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04480 } 04481 } else { 04482 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04483 } 04484 04485 if (check_mime(vmu->fullname)) { 04486 int first_line = 1; 04487 char *ptr; 04488 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04489 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04490 *ptr = '\0'; 04491 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04492 first_line = 0; 04493 /* Substring is smaller, so this will never grow */ 04494 ast_str_set(&str2, 0, "%s", ptr + 1); 04495 } 04496 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04497 } else { 04498 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04499 } 04500 04501 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04502 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04503 struct ast_channel *ast; 04504 if ((ast = ast_dummy_channel_alloc())) { 04505 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04506 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04507 if (check_mime(ast_str_buffer(str1))) { 04508 int first_line = 1; 04509 char *ptr; 04510 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04511 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04512 *ptr = '\0'; 04513 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04514 first_line = 0; 04515 /* Substring is smaller, so this will never grow */ 04516 ast_str_set(&str2, 0, "%s", ptr + 1); 04517 } 04518 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04519 } else { 04520 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04521 } 04522 ast = ast_channel_release(ast); 04523 } else { 04524 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04525 } 04526 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04527 if (ast_strlen_zero(flag)) { 04528 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04529 } else { 04530 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04531 } 04532 } else { 04533 if (ast_strlen_zero(flag)) { 04534 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04535 } else { 04536 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04537 } 04538 } 04539 04540 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04541 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04542 if (imap) { 04543 /* additional information needed for IMAP searching */ 04544 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04545 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04546 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04547 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04548 #ifdef IMAP_STORAGE 04549 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04550 #else 04551 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04552 #endif 04553 /* flag added for Urgent */ 04554 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04555 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04556 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04557 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04558 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04559 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04560 if (!ast_strlen_zero(category)) { 04561 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04562 } else { 04563 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04564 } 04565 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04566 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04567 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04568 } 04569 if (!ast_strlen_zero(cidnum)) { 04570 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04571 } 04572 if (!ast_strlen_zero(cidname)) { 04573 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04574 } 04575 fprintf(p, "MIME-Version: 1.0" ENDL); 04576 if (attach_user_voicemail) { 04577 /* Something unique. */ 04578 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04579 (int) getpid(), (unsigned int) ast_random()); 04580 04581 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04582 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04583 fprintf(p, "--%s" ENDL, bound); 04584 } 04585 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04586 if (emailbody || vmu->emailbody) { 04587 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04588 struct ast_channel *ast; 04589 if ((ast = ast_dummy_channel_alloc())) { 04590 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04591 ast_str_substitute_variables(&str1, 0, ast, e_body); 04592 #ifdef IMAP_STORAGE 04593 { 04594 /* Convert body to native line terminators for IMAP backend */ 04595 char *line = ast_str_buffer(str1), *next; 04596 do { 04597 /* Terminate line before outputting it to the file */ 04598 if ((next = strchr(line, '\n'))) { 04599 *next++ = '\0'; 04600 } 04601 fprintf(p, "%s" ENDL, line); 04602 line = next; 04603 } while (!ast_strlen_zero(line)); 04604 } 04605 #else 04606 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04607 #endif 04608 ast = ast_channel_release(ast); 04609 } else { 04610 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04611 } 04612 } else if (msgnum > -1) { 04613 if (strcmp(vmu->mailbox, mailbox)) { 04614 /* Forwarded type */ 04615 struct ast_config *msg_cfg; 04616 const char *v; 04617 int inttime; 04618 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04619 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04620 /* Retrieve info from VM attribute file */ 04621 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04622 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04623 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04624 strcat(fromfile, ".txt"); 04625 } 04626 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04627 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04628 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04629 } 04630 04631 /* You might be tempted to do origdate, except that a) it's in the wrong 04632 * format, and b) it's missing for IMAP recordings. */ 04633 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04634 struct timeval tv = { inttime, }; 04635 struct ast_tm tm; 04636 ast_localtime(&tv, &tm, NULL); 04637 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04638 } 04639 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04640 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04641 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04642 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04643 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04644 date, origcallerid, origdate); 04645 ast_config_destroy(msg_cfg); 04646 } else { 04647 goto plain_message; 04648 } 04649 } else { 04650 plain_message: 04651 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04652 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04653 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04654 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04655 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04656 } 04657 } else { 04658 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04659 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04660 } 04661 04662 if (imap || attach_user_voicemail) { 04663 if (!ast_strlen_zero(attach2)) { 04664 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04665 ast_debug(5, "creating second attachment filename %s\n", filename); 04666 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04667 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04668 ast_debug(5, "creating attachment filename %s\n", filename); 04669 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04670 } else { 04671 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04672 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04673 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04674 } 04675 } 04676 ast_free(str1); 04677 ast_free(str2); 04678 }
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(), resequence_mailbox(), 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 11363 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().
11364 { 11365 struct ast_vm_user *vmu = NULL; 11366 const char *id = astman_get_header(m, "ActionID"); 11367 char actionid[128] = ""; 11368 11369 if (!ast_strlen_zero(id)) 11370 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11371 11372 AST_LIST_LOCK(&users); 11373 11374 if (AST_LIST_EMPTY(&users)) { 11375 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11376 AST_LIST_UNLOCK(&users); 11377 return RESULT_SUCCESS; 11378 } 11379 11380 astman_send_ack(s, m, "Voicemail user list will follow"); 11381 11382 AST_LIST_TRAVERSE(&users, vmu, list) { 11383 char dirname[256]; 11384 11385 #ifdef IMAP_STORAGE 11386 int new, old; 11387 inboxcount(vmu->mailbox, &new, &old); 11388 #endif 11389 11390 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11391 astman_append(s, 11392 "%s" 11393 "Event: VoicemailUserEntry\r\n" 11394 "VMContext: %s\r\n" 11395 "VoiceMailbox: %s\r\n" 11396 "Fullname: %s\r\n" 11397 "Email: %s\r\n" 11398 "Pager: %s\r\n" 11399 "ServerEmail: %s\r\n" 11400 "MailCommand: %s\r\n" 11401 "Language: %s\r\n" 11402 "TimeZone: %s\r\n" 11403 "Callback: %s\r\n" 11404 "Dialout: %s\r\n" 11405 "UniqueID: %s\r\n" 11406 "ExitContext: %s\r\n" 11407 "SayDurationMinimum: %d\r\n" 11408 "SayEnvelope: %s\r\n" 11409 "SayCID: %s\r\n" 11410 "AttachMessage: %s\r\n" 11411 "AttachmentFormat: %s\r\n" 11412 "DeleteMessage: %s\r\n" 11413 "VolumeGain: %.2f\r\n" 11414 "CanReview: %s\r\n" 11415 "CallOperator: %s\r\n" 11416 "MaxMessageCount: %d\r\n" 11417 "MaxMessageLength: %d\r\n" 11418 "NewMessageCount: %d\r\n" 11419 #ifdef IMAP_STORAGE 11420 "OldMessageCount: %d\r\n" 11421 "IMAPUser: %s\r\n" 11422 #endif 11423 "\r\n", 11424 actionid, 11425 vmu->context, 11426 vmu->mailbox, 11427 vmu->fullname, 11428 vmu->email, 11429 vmu->pager, 11430 vmu->serveremail, 11431 vmu->mailcmd, 11432 vmu->language, 11433 vmu->zonetag, 11434 vmu->callback, 11435 vmu->dialout, 11436 vmu->uniqueid, 11437 vmu->exit, 11438 vmu->saydurationm, 11439 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11440 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11441 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11442 vmu->attachfmt, 11443 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11444 vmu->volgain, 11445 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11446 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11447 vmu->maxmsg, 11448 vmu->maxsecs, 11449 #ifdef IMAP_STORAGE 11450 new, old, vmu->imapuser 11451 #else 11452 count_messages(vmu, dirname) 11453 #endif 11454 ); 11455 } 11456 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11457 11458 AST_LIST_UNLOCK(&users); 11459 11460 return RESULT_SUCCESS; 11461 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11197 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().
11198 { 11199 while (poll_thread_run) { 11200 struct timespec ts = { 0, }; 11201 struct timeval wait; 11202 11203 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11204 ts.tv_sec = wait.tv_sec; 11205 ts.tv_nsec = wait.tv_usec * 1000; 11206 11207 ast_mutex_lock(&poll_lock); 11208 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11209 ast_mutex_unlock(&poll_lock); 11210 11211 if (!poll_thread_run) 11212 break; 11213 11214 poll_subscribed_mailboxes(); 11215 } 11216 11217 return NULL; 11218 }
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 5257 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
05258 { 05259 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05260 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11220 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 11298 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().
11299 { 11300 struct mwi_sub_task *mwist; 11301 11302 if (ast_event_get_type(event) != AST_EVENT_SUB) 11303 return; 11304 11305 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11306 return; 11307 11308 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11309 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11310 return; 11311 } 11312 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11313 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11314 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11315 11316 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11317 ast_free(mwist); 11318 } 11319 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11282 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().
11283 { 11284 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11285 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11286 return; 11287 11288 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11289 return; 11290 11291 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11292 *uniqueid = u; 11293 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11294 ast_free(uniqueid); 11295 } 11296 }
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 6893 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.
06894 { 06895 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06896 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06897 const char *category; 06898 char *myserveremail = serveremail; 06899 06900 ast_channel_lock(chan); 06901 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06902 category = ast_strdupa(category); 06903 } 06904 ast_channel_unlock(chan); 06905 06906 #ifndef IMAP_STORAGE 06907 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 06908 #else 06909 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 06910 #endif 06911 make_file(fn, sizeof(fn), todir, msgnum); 06912 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06913 06914 if (!ast_strlen_zero(vmu->attachfmt)) { 06915 if (strstr(fmt, vmu->attachfmt)) 06916 fmt = vmu->attachfmt; 06917 else 06918 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); 06919 } 06920 06921 /* Attach only the first format */ 06922 fmt = ast_strdupa(fmt); 06923 stringp = fmt; 06924 strsep(&stringp, "|"); 06925 06926 if (!ast_strlen_zero(vmu->serveremail)) 06927 myserveremail = vmu->serveremail; 06928 06929 if (!ast_strlen_zero(vmu->email)) { 06930 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 06931 06932 if (attach_user_voicemail) 06933 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 06934 06935 /* XXX possible imap issue, should category be NULL XXX */ 06936 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 06937 06938 if (attach_user_voicemail) 06939 DISPOSE(todir, msgnum); 06940 } 06941 06942 if (!ast_strlen_zero(vmu->pager)) { 06943 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 06944 } 06945 06946 if (ast_test_flag(vmu, VM_DELETE)) 06947 DELETE(todir, msgnum, fn, vmu); 06948 06949 /* Leave voicemail for someone */ 06950 if (ast_app_has_voicemail(ext_context, NULL)) 06951 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 06952 06953 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 06954 06955 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); 06956 run_externnotify(vmu->context, vmu->mailbox, flag); 06957 06958 #ifdef IMAP_STORAGE 06959 vm_delete(fn); /* Delete the file, but not the IMAP message */ 06960 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 06961 vm_imap_delete(NULL, vms->curmsg, vmu); 06962 vms->newmessages--; /* Fix new message count */ 06963 } 06964 #endif 06965 06966 return 0; 06967 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4131 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
04132 { 04133 if (bio->linelength >= BASELINELEN) { 04134 if (fputs(ENDL, so) == EOF) { 04135 return -1; 04136 } 04137 04138 bio->linelength = 0; 04139 } 04140 04141 if (putc(((unsigned char) c), so) == EOF) { 04142 return -1; 04143 } 04144 04145 bio->linelength++; 04146 04147 return 1; 04148 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7727 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(), resequence_mailbox(), vm_state::username, vm_allocate_dh(), vm_lock_path(), and vm_state::vmbox.
Referenced by vm_execmain().
07728 { 07729 int count_msg, last_msg; 07730 07731 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07732 07733 /* Rename the member vmbox HERE so that we don't try to return before 07734 * we know what's going on. 07735 */ 07736 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07737 07738 /* Faster to make the directory than to check if it exists. */ 07739 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07740 07741 /* traverses directory using readdir (or select query for ODBC) */ 07742 count_msg = count_messages(vmu, vms->curdir); 07743 if (count_msg < 0) { 07744 return count_msg; 07745 } else { 07746 vms->lastmsg = count_msg - 1; 07747 } 07748 07749 if (vm_allocate_dh(vms, vmu, count_msg)) { 07750 return -1; 07751 } 07752 07753 /* 07754 The following test is needed in case sequencing gets messed up. 07755 There appears to be more than one way to mess up sequence, so 07756 we will not try to find all of the root causes--just fix it when 07757 detected. 07758 */ 07759 07760 if (vm_lock_path(vms->curdir)) { 07761 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07762 return ERROR_LOCK_PATH; 07763 } 07764 07765 /* for local storage, checks directory for messages up to maxmsg limit */ 07766 last_msg = last_message_index(vmu, vms->curdir); 07767 ast_unlock_path(vms->curdir); 07768 07769 if (last_msg < -1) { 07770 return last_msg; 07771 #ifndef ODBC_STORAGE 07772 } else if (vms->lastmsg != last_msg) { 07773 ast_log(LOG_NOTICE, "Resequencing mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg); 07774 resequence_mailbox(vmu, vms->curdir, count_msg); 07775 #endif 07776 } 07777 07778 return 0; 07779 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7513 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().
07514 { 07515 int res = 0; 07516 char filename[256], *cid; 07517 const char *origtime, *context, *category, *duration, *flag; 07518 struct ast_config *msg_cfg; 07519 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07520 07521 vms->starting = 0; 07522 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07523 adsi_message(chan, vms); 07524 if (!vms->curmsg) 07525 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07526 else if (vms->curmsg == vms->lastmsg) 07527 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07528 07529 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07530 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07531 msg_cfg = ast_config_load(filename, config_flags); 07532 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07533 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07534 return 0; 07535 } 07536 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07537 07538 /* Play the word urgent if we are listening to urgent messages */ 07539 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07540 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07541 } 07542 07543 if (!res) { 07544 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07545 /* POLISH syntax */ 07546 if (!strncasecmp(chan->language, "pl", 2)) { 07547 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07548 int ten, one; 07549 char nextmsg[256]; 07550 ten = (vms->curmsg + 1) / 10; 07551 one = (vms->curmsg + 1) % 10; 07552 07553 if (vms->curmsg < 20) { 07554 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07555 res = wait_file2(chan, vms, nextmsg); 07556 } else { 07557 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07558 res = wait_file2(chan, vms, nextmsg); 07559 if (one > 0) { 07560 if (!res) { 07561 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07562 res = wait_file2(chan, vms, nextmsg); 07563 } 07564 } 07565 } 07566 } 07567 if (!res) 07568 res = wait_file2(chan, vms, "vm-message"); 07569 /* HEBREW syntax */ 07570 } else if (!strncasecmp(chan->language, "he", 2)) { 07571 if (!vms->curmsg) { 07572 res = wait_file2(chan, vms, "vm-message"); 07573 res = wait_file2(chan, vms, "vm-first"); 07574 } else if (vms->curmsg == vms->lastmsg) { 07575 res = wait_file2(chan, vms, "vm-message"); 07576 res = wait_file2(chan, vms, "vm-last"); 07577 } else { 07578 res = wait_file2(chan, vms, "vm-message"); 07579 res = wait_file2(chan, vms, "vm-number"); 07580 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07581 } 07582 /* VIETNAMESE syntax */ 07583 } else if (!strncasecmp(chan->language, "vi", 2)) { 07584 if (!vms->curmsg) { 07585 res = wait_file2(chan, vms, "vm-message"); 07586 res = wait_file2(chan, vms, "vm-first"); 07587 } else if (vms->curmsg == vms->lastmsg) { 07588 res = wait_file2(chan, vms, "vm-message"); 07589 res = wait_file2(chan, vms, "vm-last"); 07590 } else { 07591 res = wait_file2(chan, vms, "vm-message"); 07592 res = wait_file2(chan, vms, "vm-number"); 07593 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07594 } 07595 } else { 07596 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07597 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07598 } else { /* DEFAULT syntax */ 07599 res = wait_file2(chan, vms, "vm-message"); 07600 } 07601 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07602 if (!res) { 07603 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07604 } 07605 } 07606 } 07607 } 07608 07609 if (!msg_cfg) { 07610 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07611 return 0; 07612 } 07613 07614 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07615 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07616 DISPOSE(vms->curdir, vms->curmsg); 07617 ast_config_destroy(msg_cfg); 07618 return 0; 07619 } 07620 07621 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07622 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07623 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07624 07625 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07626 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07627 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07628 if (!res) { 07629 res = play_message_category(chan, category); 07630 } 07631 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 07632 res = play_message_datetime(chan, vmu, origtime, filename); 07633 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 07634 res = play_message_callerid(chan, vms, cid, context, 0); 07635 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 07636 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07637 /* Allow pressing '1' to skip envelope / callerid */ 07638 if (res == '1') 07639 res = 0; 07640 ast_config_destroy(msg_cfg); 07641 07642 if (!res) { 07643 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07644 vms->heard[vms->curmsg] = 1; 07645 #ifdef IMAP_STORAGE 07646 /*IMAP storage stores any prepended message from a forward 07647 * as a separate file from the rest of the message 07648 */ 07649 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07650 wait_file(chan, vms, vms->introfn); 07651 } 07652 #endif 07653 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07654 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07655 res = 0; 07656 } 07657 } 07658 DISPOSE(vms->curdir, vms->curmsg); 07659 return res; 07660 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7399 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().
07400 { 07401 int res = 0; 07402 int i; 07403 char *callerid, *name; 07404 char prefile[PATH_MAX] = ""; 07405 07406 07407 /* If voicemail cid is not enabled, or we didn't get cid or context from 07408 * the attribute file, leave now. 07409 * 07410 * TODO Still need to change this so that if this function is called by the 07411 * message envelope (and someone is explicitly requesting to hear the CID), 07412 * it does not check to see if CID is enabled in the config file. 07413 */ 07414 if ((cid == NULL)||(context == NULL)) 07415 return res; 07416 07417 /* Strip off caller ID number from name */ 07418 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07419 ast_callerid_parse(cid, &name, &callerid); 07420 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07421 /* Check for internal contexts and only */ 07422 /* say extension when the call didn't come from an internal context in the list */ 07423 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07424 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07425 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07426 break; 07427 } 07428 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07429 if (!res) { 07430 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07431 if (!ast_strlen_zero(prefile)) { 07432 /* See if we can find a recorded name for this person instead of their extension number */ 07433 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07434 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07435 if (!callback) 07436 res = wait_file2(chan, vms, "vm-from"); 07437 res = ast_stream_and_wait(chan, prefile, ""); 07438 } else { 07439 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07440 /* Say "from extension" as one saying to sound smoother */ 07441 if (!callback) 07442 res = wait_file2(chan, vms, "vm-from-extension"); 07443 res = ast_say_digit_str(chan, callerid, "", chan->language); 07444 } 07445 } 07446 } 07447 } else if (!res) { 07448 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07449 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07450 if (!callback) 07451 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07452 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07453 } 07454 } else { 07455 /* Number unknown */ 07456 ast_debug(1, "VM-CID: From an unknown number\n"); 07457 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07458 res = wait_file2(chan, vms, "vm-unknown-caller"); 07459 } 07460 return res; 07461 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7310 of file app_voicemail.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
Referenced by play_message().
07311 { 07312 int res = 0; 07313 07314 if (!ast_strlen_zero(category)) 07315 res = ast_play_and_wait(chan, category); 07316 07317 if (res) { 07318 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07319 res = 0; 07320 } 07321 07322 return res; 07323 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7325 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().
07326 { 07327 int res = 0; 07328 struct vm_zone *the_zone = NULL; 07329 time_t t; 07330 07331 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07332 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07333 return 0; 07334 } 07335 07336 /* Does this user have a timezone specified? */ 07337 if (!ast_strlen_zero(vmu->zonetag)) { 07338 /* Find the zone in the list */ 07339 struct vm_zone *z; 07340 AST_LIST_LOCK(&zones); 07341 AST_LIST_TRAVERSE(&zones, z, list) { 07342 if (!strcmp(z->name, vmu->zonetag)) { 07343 the_zone = z; 07344 break; 07345 } 07346 } 07347 AST_LIST_UNLOCK(&zones); 07348 } 07349 07350 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07351 #if 0 07352 /* Set the DIFF_* variables */ 07353 ast_localtime(&t, &time_now, NULL); 07354 tv_now = ast_tvnow(); 07355 ast_localtime(&tv_now, &time_then, NULL); 07356 07357 /* Day difference */ 07358 if (time_now.tm_year == time_then.tm_year) 07359 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07360 else 07361 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07362 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07363 07364 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07365 #endif 07366 if (the_zone) { 07367 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07368 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07369 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07370 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07371 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07372 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07373 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); 07374 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07375 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07376 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07377 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07378 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07379 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07380 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07381 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); 07382 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07383 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07384 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07385 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07386 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07387 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); 07388 } else { 07389 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07390 } 07391 #if 0 07392 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07393 #endif 07394 return res; 07395 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7463 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().
07464 { 07465 int res = 0; 07466 int durationm; 07467 int durations; 07468 /* Verify that we have a duration for the message */ 07469 if (duration == NULL) 07470 return res; 07471 07472 /* Convert from seconds to minutes */ 07473 durations = atoi(duration); 07474 durationm = (durations / 60); 07475 07476 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07477 07478 if ((!res) && (durationm >= minduration)) { 07479 res = wait_file2(chan, vms, "vm-duration"); 07480 07481 /* POLISH syntax */ 07482 if (!strncasecmp(chan->language, "pl", 2)) { 07483 div_t num = div(durationm, 10); 07484 07485 if (durationm == 1) { 07486 res = ast_play_and_wait(chan, "digits/1z"); 07487 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07488 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07489 if (num.rem == 2) { 07490 if (!num.quot) { 07491 res = ast_play_and_wait(chan, "digits/2-ie"); 07492 } else { 07493 res = say_and_wait(chan, durationm - 2 , chan->language); 07494 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07495 } 07496 } else { 07497 res = say_and_wait(chan, durationm, chan->language); 07498 } 07499 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07500 } else { 07501 res = say_and_wait(chan, durationm, chan->language); 07502 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07503 } 07504 /* DEFAULT syntax */ 07505 } else { 07506 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07507 res = wait_file2(chan, vms, "vm-minutes"); 07508 } 07509 } 07510 return res; 07511 }
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 13014 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.
13017 { 13018 /* Record message & let caller review or re-record it, or set options if applicable */ 13019 int res = 0; 13020 int cmd = 0; 13021 int max_attempts = 3; 13022 int attempts = 0; 13023 int recorded = 0; 13024 int msg_exists = 0; 13025 signed char zero_gain = 0; 13026 char tempfile[PATH_MAX]; 13027 char *acceptdtmf = "#"; 13028 char *canceldtmf = ""; 13029 int canceleddtmf = 0; 13030 13031 /* Note that urgent and private are for flagging messages as such in the future */ 13032 13033 /* barf if no pointer passed to store duration in */ 13034 if (duration == NULL) { 13035 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13036 return -1; 13037 } 13038 13039 if (!outsidecaller) 13040 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13041 else 13042 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13043 13044 cmd = '3'; /* Want to start by recording */ 13045 13046 while ((cmd >= 0) && (cmd != 't')) { 13047 switch (cmd) { 13048 case '1': 13049 if (!msg_exists) { 13050 /* In this case, 1 is to record a message */ 13051 cmd = '3'; 13052 break; 13053 } else { 13054 /* Otherwise 1 is to save the existing message */ 13055 ast_verb(3, "Saving message as is\n"); 13056 if (!outsidecaller) 13057 ast_filerename(tempfile, recordfile, NULL); 13058 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13059 if (!outsidecaller) { 13060 /* Saves to IMAP server only if imapgreeting=yes */ 13061 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13062 DISPOSE(recordfile, -1); 13063 } 13064 cmd = 't'; 13065 return res; 13066 } 13067 case '2': 13068 /* Review */ 13069 ast_verb(3, "Reviewing the message\n"); 13070 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13071 break; 13072 case '3': 13073 msg_exists = 0; 13074 /* Record */ 13075 if (recorded == 1) 13076 ast_verb(3, "Re-recording the message\n"); 13077 else 13078 ast_verb(3, "Recording the message\n"); 13079 13080 if (recorded && outsidecaller) { 13081 cmd = ast_play_and_wait(chan, INTRO); 13082 cmd = ast_play_and_wait(chan, "beep"); 13083 } 13084 recorded = 1; 13085 /* 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 */ 13086 if (record_gain) 13087 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13088 if (ast_test_flag(vmu, VM_OPERATOR)) 13089 canceldtmf = "0"; 13090 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13091 if (strchr(canceldtmf, cmd)) { 13092 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13093 canceleddtmf = 1; 13094 } 13095 if (record_gain) 13096 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13097 if (cmd == -1) { 13098 /* User has hung up, no options to give */ 13099 if (!outsidecaller) { 13100 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13101 ast_filedelete(tempfile, NULL); 13102 } 13103 return cmd; 13104 } 13105 if (cmd == '0') { 13106 break; 13107 } else if (cmd == '*') { 13108 break; 13109 #if 0 13110 } else if (vmu->review && (*duration < 5)) { 13111 /* Message is too short */ 13112 ast_verb(3, "Message too short\n"); 13113 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13114 cmd = ast_filedelete(tempfile, NULL); 13115 break; 13116 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 13117 /* Message is all silence */ 13118 ast_verb(3, "Nothing recorded\n"); 13119 cmd = ast_filedelete(tempfile, NULL); 13120 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13121 if (!cmd) 13122 cmd = ast_play_and_wait(chan, "vm-speakup"); 13123 break; 13124 #endif 13125 } else { 13126 /* If all is well, a message exists */ 13127 msg_exists = 1; 13128 cmd = 0; 13129 } 13130 break; 13131 case '4': 13132 if (outsidecaller) { /* only mark vm messages */ 13133 /* Mark Urgent */ 13134 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13135 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13136 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13137 strcpy(flag, "Urgent"); 13138 } else if (flag) { 13139 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13140 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13141 strcpy(flag, ""); 13142 } else { 13143 ast_play_and_wait(chan, "vm-sorry"); 13144 } 13145 cmd = 0; 13146 } else { 13147 cmd = ast_play_and_wait(chan, "vm-sorry"); 13148 } 13149 break; 13150 case '5': 13151 case '6': 13152 case '7': 13153 case '8': 13154 case '9': 13155 case '*': 13156 case '#': 13157 cmd = ast_play_and_wait(chan, "vm-sorry"); 13158 break; 13159 #if 0 13160 /* XXX Commented out for the moment because of the dangers of deleting 13161 a message while recording (can put the message numbers out of sync) */ 13162 case '*': 13163 /* Cancel recording, delete message, offer to take another message*/ 13164 cmd = ast_play_and_wait(chan, "vm-deleted"); 13165 cmd = ast_filedelete(tempfile, NULL); 13166 if (outsidecaller) { 13167 res = vm_exec(chan, NULL); 13168 return res; 13169 } 13170 else 13171 return 1; 13172 #endif 13173 case '0': 13174 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13175 cmd = ast_play_and_wait(chan, "vm-sorry"); 13176 break; 13177 } 13178 if (msg_exists || recorded) { 13179 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13180 if (!cmd) 13181 cmd = ast_waitfordigit(chan, 3000); 13182 if (cmd == '1') { 13183 ast_filerename(tempfile, recordfile, NULL); 13184 ast_play_and_wait(chan, "vm-msgsaved"); 13185 cmd = '0'; 13186 } else if (cmd == '4') { 13187 if (flag) { 13188 ast_play_and_wait(chan, "vm-marked-urgent"); 13189 strcpy(flag, "Urgent"); 13190 } 13191 ast_play_and_wait(chan, "vm-msgsaved"); 13192 cmd = '0'; 13193 } else { 13194 ast_play_and_wait(chan, "vm-deleted"); 13195 DELETE(tempfile, -1, tempfile, vmu); 13196 cmd = '0'; 13197 } 13198 } 13199 return cmd; 13200 default: 13201 /* If the caller is an ouside caller, and the review option is enabled, 13202 allow them to review the message, but let the owner of the box review 13203 their OGM's */ 13204 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13205 return cmd; 13206 if (msg_exists) { 13207 cmd = ast_play_and_wait(chan, "vm-review"); 13208 if (!cmd && outsidecaller) { 13209 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13210 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13211 } else if (flag) { 13212 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13213 } 13214 } 13215 } else { 13216 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13217 if (!cmd) 13218 cmd = ast_waitfordigit(chan, 600); 13219 } 13220 13221 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13222 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13223 if (!cmd) 13224 cmd = ast_waitfordigit(chan, 600); 13225 } 13226 #if 0 13227 if (!cmd) 13228 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13229 #endif 13230 if (!cmd) 13231 cmd = ast_waitfordigit(chan, 6000); 13232 if (!cmd) { 13233 attempts++; 13234 } 13235 if (attempts > max_attempts) { 13236 cmd = 't'; 13237 } 13238 } 13239 } 13240 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13241 /* Hang up or timeout, so delete the recording. */ 13242 ast_filedelete(tempfile, NULL); 13243 } 13244 13245 if (cmd != 't' && outsidecaller) 13246 ast_play_and_wait(chan, "vm-goodbye"); 13247 13248 return cmd; 13249 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11169 of file app_voicemail.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
11170 { 11171 int new = 0, old = 0, urgent = 0; 11172 11173 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11174 11175 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11176 mwi_sub->old_urgent = urgent; 11177 mwi_sub->old_new = new; 11178 mwi_sub->old_old = old; 11179 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11180 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11181 } 11182 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11184 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().
11185 { 11186 struct mwi_sub *mwi_sub; 11187 11188 AST_RWLIST_RDLOCK(&mwi_subs); 11189 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11190 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11191 poll_subscribed_mailbox(mwi_sub); 11192 } 11193 } 11194 AST_RWLIST_UNLOCK(&mwi_subs); 11195 }
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 4219 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.
04220 { 04221 char callerid[256]; 04222 char num[12]; 04223 char fromdir[256], fromfile[256]; 04224 struct ast_config *msg_cfg; 04225 const char *origcallerid, *origtime; 04226 char origcidname[80], origcidnum[80], origdate[80]; 04227 int inttime; 04228 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04229 04230 /* Prepare variables for substitution in email body and subject */ 04231 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04232 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04233 snprintf(num, sizeof(num), "%d", msgnum); 04234 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04235 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04236 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04237 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04238 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04239 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04240 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04241 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04242 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04243 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04244 04245 /* Retrieve info from VM attribute file */ 04246 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04247 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04248 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04249 strcat(fromfile, ".txt"); 04250 } 04251 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04252 if (option_debug > 0) { 04253 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04254 } 04255 return; 04256 } 04257 04258 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04259 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04260 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04261 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04262 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04263 } 04264 04265 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04266 struct timeval tv = { inttime, }; 04267 struct ast_tm tm; 04268 ast_localtime(&tv, &tm, NULL); 04269 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04270 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04271 } 04272 ast_config_destroy(msg_cfg); 04273 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6856 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().
06857 { 06858 struct ast_event *event; 06859 char *mailbox, *context; 06860 06861 /* Strip off @default */ 06862 context = mailbox = ast_strdupa(box); 06863 strsep(&context, "@"); 06864 if (ast_strlen_zero(context)) 06865 context = "default"; 06866 06867 if (!(event = ast_event_new(AST_EVENT_MWI, 06868 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06869 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06870 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06871 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06872 AST_EVENT_IE_END))) { 06873 return; 06874 } 06875 06876 ast_event_queue_and_cache(event); 06877 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12231 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().
12231 { 12232 struct ast_config *pwconf; 12233 struct ast_flags config_flags = { 0 }; 12234 12235 pwconf = ast_config_load(secretfn, config_flags); 12236 if (pwconf) { 12237 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12238 if (val) { 12239 ast_copy_string(password, val, passwordlen); 12240 return; 12241 } 12242 } 12243 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12244 }
static int reload | ( | void | ) | [static] |
Definition at line 12668 of file app_voicemail.c.
References load_config().
12669 { 12670 return load_config(1); 12671 }
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 resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6026 of file app_voicemail.c.
References ast_unlock_path(), ast_vm_user::context, ERROR_LOCK_PATH, EXISTS, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, RENAME, and vm_lock_path().
Referenced by open_mailbox().
06027 { 06028 /* we know the actual number of messages, so stop process when number is hit */ 06029 06030 int x, dest; 06031 char sfn[PATH_MAX]; 06032 char dfn[PATH_MAX]; 06033 06034 if (vm_lock_path(dir)) 06035 return ERROR_LOCK_PATH; 06036 06037 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06038 make_file(sfn, sizeof(sfn), dir, x); 06039 if (EXISTS(dir, x, sfn, NULL)) { 06040 06041 if (x != dest) { 06042 make_file(dfn, sizeof(dfn), dir, dest); 06043 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06044 } 06045 06046 dest++; 06047 } 06048 } 06049 ast_unlock_path(dir); 06050 06051 return dest; 06052 }
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 5400 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.
05401 { 05402 char arguments[255]; 05403 char ext_context[256] = ""; 05404 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05405 struct ast_smdi_mwi_message *mwi_msg; 05406 05407 if (!ast_strlen_zero(context)) 05408 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05409 else 05410 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05411 05412 if (smdi_iface) { 05413 if (ast_app_has_voicemail(ext_context, NULL)) 05414 ast_smdi_mwi_set(smdi_iface, extension); 05415 else 05416 ast_smdi_mwi_unset(smdi_iface, extension); 05417 05418 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05419 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05420 if (!strncmp(mwi_msg->cause, "INV", 3)) 05421 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05422 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05423 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05424 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05425 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05426 } else { 05427 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05428 } 05429 } 05430 05431 if (!ast_strlen_zero(externnotify)) { 05432 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05433 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05434 } else { 05435 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05436 ast_debug(1, "Executing %s\n", arguments); 05437 ast_safe_system(arguments); 05438 } 05439 } 05440 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6062 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().
06063 { 06064 #ifdef IMAP_STORAGE 06065 /* we must use mbox(x) folder names, and copy the message there */ 06066 /* simple. huh? */ 06067 char sequence[10]; 06068 char mailbox[256]; 06069 int res; 06070 06071 /* get the real IMAP message number for this message */ 06072 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06073 06074 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06075 ast_mutex_lock(&vms->lock); 06076 /* if save to Old folder, put in INBOX as read */ 06077 if (box == OLD_FOLDER) { 06078 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06079 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06080 } else if (box == NEW_FOLDER) { 06081 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06082 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06083 } 06084 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06085 ast_mutex_unlock(&vms->lock); 06086 return 0; 06087 } 06088 /* Create the folder if it don't exist */ 06089 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06090 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06091 if (mail_create(vms->mailstream, mailbox) == NIL) 06092 ast_debug(5, "Folder exists.\n"); 06093 else 06094 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06095 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06096 ast_mutex_unlock(&vms->lock); 06097 return res; 06098 #else 06099 char *dir = vms->curdir; 06100 char *username = vms->username; 06101 char *context = vmu->context; 06102 char sfn[PATH_MAX]; 06103 char dfn[PATH_MAX]; 06104 char ddir[PATH_MAX]; 06105 const char *dbox = mbox(vmu, box); 06106 int x, i; 06107 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06108 06109 if (vm_lock_path(ddir)) 06110 return ERROR_LOCK_PATH; 06111 06112 x = last_message_index(vmu, ddir) + 1; 06113 06114 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06115 x--; 06116 for (i = 1; i <= x; i++) { 06117 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06118 make_file(sfn, sizeof(sfn), ddir, i); 06119 make_file(dfn, sizeof(dfn), ddir, i - 1); 06120 if (EXISTS(ddir, i, sfn, NULL)) { 06121 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06122 } else 06123 break; 06124 } 06125 } else { 06126 if (x >= vmu->maxmsg) { 06127 ast_unlock_path(ddir); 06128 return -1; 06129 } 06130 } 06131 make_file(sfn, sizeof(sfn), dir, msg); 06132 make_file(dfn, sizeof(dfn), ddir, x); 06133 if (strcmp(sfn, dfn)) { 06134 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06135 } 06136 ast_unlock_path(ddir); 06137 #endif 06138 return 0; 06139 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6055 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().
06056 { 06057 int d; 06058 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06059 return d; 06060 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12217 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().
12218 { 12219 int res = -1; 12220 char dir[PATH_MAX]; 12221 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12222 ast_debug(2, "About to try retrieving name file %s\n", dir); 12223 RETRIEVE(dir, -1, mailbox, context); 12224 if (ast_fileexists(dir, NULL, NULL)) { 12225 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12226 } 12227 DISPOSE(dir, -1); 12228 return res; 12229 }
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 4732 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().
04733 { 04734 FILE *p = NULL; 04735 char tmp[80] = "/tmp/astmail-XXXXXX"; 04736 char tmp2[256]; 04737 char *stringp; 04738 04739 if (vmu && ast_strlen_zero(vmu->email)) { 04740 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04741 return(0); 04742 } 04743 04744 /* Mail only the first format */ 04745 format = ast_strdupa(format); 04746 stringp = format; 04747 strsep(&stringp, "|"); 04748 04749 if (!strcmp(format, "wav49")) 04750 format = "WAV"; 04751 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)); 04752 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04753 command hangs */ 04754 if ((p = vm_mkftemp(tmp)) == NULL) { 04755 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04756 return -1; 04757 } else { 04758 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04759 fclose(p); 04760 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04761 ast_safe_system(tmp2); 04762 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04763 } 04764 return 0; 04765 }
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 4767 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().
04768 { 04769 char enc_cidnum[256], enc_cidname[256]; 04770 char date[256]; 04771 char host[MAXHOSTNAMELEN] = ""; 04772 char who[256]; 04773 char dur[PATH_MAX]; 04774 char tmp[80] = "/tmp/astmail-XXXXXX"; 04775 char tmp2[PATH_MAX]; 04776 struct ast_tm tm; 04777 FILE *p; 04778 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04779 04780 if (!str1 || !str2) { 04781 ast_free(str1); 04782 ast_free(str2); 04783 return -1; 04784 } 04785 04786 if (cidnum) { 04787 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04788 } 04789 if (cidname) { 04790 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04791 } 04792 04793 if ((p = vm_mkftemp(tmp)) == NULL) { 04794 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04795 ast_free(str1); 04796 ast_free(str2); 04797 return -1; 04798 } 04799 gethostname(host, sizeof(host)-1); 04800 if (strchr(srcemail, '@')) { 04801 ast_copy_string(who, srcemail, sizeof(who)); 04802 } else { 04803 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04804 } 04805 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04806 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04807 fprintf(p, "Date: %s\n", date); 04808 04809 /* Reformat for custom pager format */ 04810 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04811 04812 if (!ast_strlen_zero(pagerfromstring)) { 04813 struct ast_channel *ast; 04814 if ((ast = ast_dummy_channel_alloc())) { 04815 char *ptr; 04816 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04817 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04818 04819 if (check_mime(ast_str_buffer(str1))) { 04820 int first_line = 1; 04821 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04822 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04823 *ptr = '\0'; 04824 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04825 first_line = 0; 04826 /* Substring is smaller, so this will never grow */ 04827 ast_str_set(&str2, 0, "%s", ptr + 1); 04828 } 04829 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04830 } else { 04831 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04832 } 04833 ast = ast_channel_release(ast); 04834 } else { 04835 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04836 } 04837 } else { 04838 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04839 } 04840 04841 if (check_mime(vmu->fullname)) { 04842 int first_line = 1; 04843 char *ptr; 04844 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04845 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04846 *ptr = '\0'; 04847 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04848 first_line = 0; 04849 /* Substring is smaller, so this will never grow */ 04850 ast_str_set(&str2, 0, "%s", ptr + 1); 04851 } 04852 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04853 } else { 04854 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04855 } 04856 04857 if (!ast_strlen_zero(pagersubject)) { 04858 struct ast_channel *ast; 04859 if ((ast = ast_dummy_channel_alloc())) { 04860 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04861 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04862 if (check_mime(ast_str_buffer(str1))) { 04863 int first_line = 1; 04864 char *ptr; 04865 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04866 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04867 *ptr = '\0'; 04868 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04869 first_line = 0; 04870 /* Substring is smaller, so this will never grow */ 04871 ast_str_set(&str2, 0, "%s", ptr + 1); 04872 } 04873 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04874 } else { 04875 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04876 } 04877 ast = ast_channel_release(ast); 04878 } else { 04879 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04880 } 04881 } else { 04882 if (ast_strlen_zero(flag)) { 04883 fprintf(p, "Subject: New VM\n\n"); 04884 } else { 04885 fprintf(p, "Subject: New %s VM\n\n", flag); 04886 } 04887 } 04888 04889 if (pagerbody) { 04890 struct ast_channel *ast; 04891 if ((ast = ast_dummy_channel_alloc())) { 04892 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04893 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 04894 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04895 ast = ast_channel_release(ast); 04896 } else { 04897 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04898 } 04899 } else { 04900 fprintf(p, "New %s long %s msg in box %s\n" 04901 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04902 } 04903 04904 fclose(p); 04905 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04906 ast_safe_system(tmp2); 04907 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04908 ast_free(str1); 04909 ast_free(str2); 04910 return 0; 04911 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 10826 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().
10827 { 10828 struct ast_config *cfg; 10829 const char *cat = NULL; 10830 10831 if (!(cfg = ast_load_realtime_multientry("voicemail", 10832 "context", context, SENTINEL))) { 10833 return CLI_FAILURE; 10834 } 10835 10836 ast_cli(fd, 10837 "\n" 10838 "=============================================================\n" 10839 "=== Configured Voicemail Users ==============================\n" 10840 "=============================================================\n" 10841 "===\n"); 10842 10843 while ((cat = ast_category_browse(cfg, cat))) { 10844 struct ast_variable *var = NULL; 10845 ast_cli(fd, 10846 "=== Mailbox ...\n" 10847 "===\n"); 10848 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 10849 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 10850 ast_cli(fd, 10851 "===\n" 10852 "=== ---------------------------------------------------------\n" 10853 "===\n"); 10854 } 10855 10856 ast_cli(fd, 10857 "=============================================================\n" 10858 "\n"); 10859 10860 ast_config_destroy(cfg); 10861 10862 return CLI_SUCCESS; 10863 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11321 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().
11322 { 11323 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11324 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11325 AST_EVENT_IE_END); 11326 11327 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11328 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11329 AST_EVENT_IE_END); 11330 11331 if (mwi_sub_sub) 11332 ast_event_report_subs(mwi_sub_sub); 11333 11334 poll_thread_run = 1; 11335 11336 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11337 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11339 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().
11340 { 11341 poll_thread_run = 0; 11342 11343 if (mwi_sub_sub) { 11344 ast_event_unsubscribe(mwi_sub_sub); 11345 mwi_sub_sub = NULL; 11346 } 11347 11348 if (mwi_unsub_sub) { 11349 ast_event_unsubscribe(mwi_unsub_sub); 11350 mwi_unsub_sub = NULL; 11351 } 11352 11353 ast_mutex_lock(&poll_lock); 11354 ast_cond_signal(&poll_cond); 11355 ast_mutex_unlock(&poll_lock); 11356 11357 pthread_join(poll_thread, NULL); 11358 11359 poll_thread = AST_PTHREADT_NULL; 11360 }
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 11485 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().
11486 { 11487 char *current; 11488 11489 /* Add 16 for fudge factor */ 11490 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11491 11492 ast_str_reset(str); 11493 11494 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11495 for (current = (char *) value; *current; current++) { 11496 if (*current == '\\') { 11497 current++; 11498 if (!*current) { 11499 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11500 break; 11501 } 11502 switch (*current) { 11503 case 'r': 11504 ast_str_append(&str, 0, "\r"); 11505 break; 11506 case 'n': 11507 #ifdef IMAP_STORAGE 11508 if (!str->used || str->str[str->used - 1] != '\r') { 11509 ast_str_append(&str, 0, "\r"); 11510 } 11511 #endif 11512 ast_str_append(&str, 0, "\n"); 11513 break; 11514 case 't': 11515 ast_str_append(&str, 0, "\t"); 11516 break; 11517 default: 11518 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11519 break; 11520 } 11521 } else { 11522 ast_str_append(&str, 0, "%c", *current); 11523 } 11524 } 11525 11526 return ast_str_buffer(str); 11527 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12673 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().
12674 { 12675 int res; 12676 12677 res = ast_unregister_application(app); 12678 res |= ast_unregister_application(app2); 12679 res |= ast_unregister_application(app3); 12680 res |= ast_unregister_application(app4); 12681 res |= ast_unregister_application(sayname_app); 12682 res |= ast_custom_function_unregister(&mailbox_exists_acf); 12683 res |= ast_manager_unregister("VoicemailUsersList"); 12684 res |= ast_data_unregister(NULL); 12685 #ifdef TEST_FRAMEWORK 12686 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 12687 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 12688 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 12689 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 12690 #endif 12691 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 12692 ast_uninstall_vm_functions(); 12693 ao2_ref(inprocess_container, -1); 12694 12695 if (poll_thread != AST_PTHREADT_NULL) 12696 stop_poll_thread(); 12697 12698 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 12699 ast_unload_realtime("voicemail"); 12700 ast_unload_realtime("voicemail_data"); 12701 12702 free_vm_users(); 12703 free_vm_zones(); 12704 return res; 12705 }
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 9558 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().
09561 { 09562 int useadsi = 0, valid = 0, logretries = 0; 09563 char password[AST_MAX_EXTENSION]="", *passptr; 09564 struct ast_vm_user vmus, *vmu = NULL; 09565 09566 /* If ADSI is supported, setup login screen */ 09567 adsi_begin(chan, &useadsi); 09568 if (!skipuser && useadsi) 09569 adsi_login(chan); 09570 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09571 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09572 return -1; 09573 } 09574 09575 /* Authenticate them and get their mailbox/password */ 09576 09577 while (!valid && (logretries < max_logins)) { 09578 /* Prompt for, and read in the username */ 09579 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09580 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09581 return -1; 09582 } 09583 if (ast_strlen_zero(mailbox)) { 09584 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09585 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09586 } else { 09587 ast_verb(3, "Username not entered\n"); 09588 return -1; 09589 } 09590 } else if (mailbox[0] == '*') { 09591 /* user entered '*' */ 09592 if (ast_exists_extension(chan, chan->context, "a", 1, 09593 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09594 return -1; 09595 } 09596 mailbox[0] = '\0'; 09597 } 09598 09599 if (useadsi) 09600 adsi_password(chan); 09601 09602 if (!ast_strlen_zero(prefix)) { 09603 char fullusername[80] = ""; 09604 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09605 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09606 ast_copy_string(mailbox, fullusername, mailbox_size); 09607 } 09608 09609 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09610 vmu = find_user(&vmus, context, mailbox); 09611 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09612 /* saved password is blank, so don't bother asking */ 09613 password[0] = '\0'; 09614 } else { 09615 if (ast_streamfile(chan, vm_password, chan->language)) { 09616 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09617 return -1; 09618 } 09619 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09620 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09621 return -1; 09622 } else if (password[0] == '*') { 09623 /* user entered '*' */ 09624 if (ast_exists_extension(chan, chan->context, "a", 1, 09625 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09626 mailbox[0] = '*'; 09627 return -1; 09628 } 09629 mailbox[0] = '\0'; 09630 } 09631 } 09632 09633 if (vmu) { 09634 passptr = vmu->password; 09635 if (passptr[0] == '-') passptr++; 09636 } 09637 if (vmu && !strcmp(passptr, password)) 09638 valid++; 09639 else { 09640 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09641 if (!ast_strlen_zero(prefix)) 09642 mailbox[0] = '\0'; 09643 } 09644 logretries++; 09645 if (!valid) { 09646 if (skipuser || logretries >= max_logins) { 09647 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09648 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09649 return -1; 09650 } 09651 } else { 09652 if (useadsi) 09653 adsi_login(chan); 09654 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09655 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09656 return -1; 09657 } 09658 } 09659 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09660 return -1; 09661 } 09662 } 09663 if (!valid && (logretries >= max_logins)) { 09664 ast_stopstream(chan); 09665 ast_play_and_wait(chan, "vm-goodbye"); 09666 return -1; 09667 } 09668 if (vmu && !skipuser) { 09669 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09670 } 09671 return 0; 09672 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10721 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().
10722 { 10723 struct ast_vm_user svm; 10724 char *context, *box; 10725 AST_DECLARE_APP_ARGS(args, 10726 AST_APP_ARG(mbox); 10727 AST_APP_ARG(options); 10728 ); 10729 static int dep_warning = 0; 10730 10731 if (ast_strlen_zero(data)) { 10732 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10733 return -1; 10734 } 10735 10736 if (!dep_warning) { 10737 dep_warning = 1; 10738 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10739 } 10740 10741 box = ast_strdupa(data); 10742 10743 AST_STANDARD_APP_ARGS(args, box); 10744 10745 if (args.options) { 10746 } 10747 10748 if ((context = strchr(args.mbox, '@'))) { 10749 *context = '\0'; 10750 context++; 10751 } 10752 10753 if (find_user(&svm, context, args.mbox)) { 10754 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 10755 } else 10756 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 10757 10758 return 0; 10759 }
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 9537 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().
09538 { 09539 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09540 return vm_browse_messages_es(chan, vms, vmu); 09541 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09542 return vm_browse_messages_gr(chan, vms, vmu); 09543 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09544 return vm_browse_messages_he(chan, vms, vmu); 09545 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09546 return vm_browse_messages_it(chan, vms, vmu); 09547 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09548 return vm_browse_messages_pt(chan, vms, vmu); 09549 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09550 return vm_browse_messages_vi(chan, vms, vmu); 09551 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09552 return vm_browse_messages_zh(chan, vms, vmu); 09553 } else { /* Default to English syntax */ 09554 return vm_browse_messages_en(chan, vms, vmu); 09555 } 09556 }
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 9376 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().
09377 { 09378 int cmd = 0; 09379 09380 if (vms->lastmsg > -1) { 09381 cmd = play_message(chan, vmu, vms); 09382 } else { 09383 cmd = ast_play_and_wait(chan, "vm-youhave"); 09384 if (!cmd) 09385 cmd = ast_play_and_wait(chan, "vm-no"); 09386 if (!cmd) { 09387 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09388 cmd = ast_play_and_wait(chan, vms->fn); 09389 } 09390 if (!cmd) 09391 cmd = ast_play_and_wait(chan, "vm-messages"); 09392 } 09393 return cmd; 09394 }
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 9430 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().
09431 { 09432 int cmd; 09433 09434 if (vms->lastmsg > -1) { 09435 cmd = play_message(chan, vmu, vms); 09436 } else { 09437 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09438 if (!cmd) 09439 cmd = ast_play_and_wait(chan, "vm-messages"); 09440 if (!cmd) { 09441 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09442 cmd = ast_play_and_wait(chan, vms->fn); 09443 } 09444 } 09445 return cmd; 09446 }
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 9324 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().
09325 { 09326 int cmd = 0; 09327 09328 if (vms->lastmsg > -1) { 09329 cmd = play_message(chan, vmu, vms); 09330 } else { 09331 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09332 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09333 if (!cmd) { 09334 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09335 cmd = ast_play_and_wait(chan, vms->fn); 09336 } 09337 if (!cmd) 09338 cmd = ast_play_and_wait(chan, "vm-messages"); 09339 } else { 09340 if (!cmd) 09341 cmd = ast_play_and_wait(chan, "vm-messages"); 09342 if (!cmd) { 09343 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09344 cmd = ast_play_and_wait(chan, vms->fn); 09345 } 09346 } 09347 } 09348 return cmd; 09349 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9352 of file app_voicemail.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
09353 { 09354 int cmd = 0; 09355 09356 if (vms->lastmsg > -1) { 09357 cmd = play_message(chan, vmu, vms); 09358 } else { 09359 if (!strcasecmp(vms->fn, "INBOX")) { 09360 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09361 } else { 09362 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09363 } 09364 } 09365 return cmd; 09366 }
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 9404 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().
09405 { 09406 int cmd; 09407 09408 if (vms->lastmsg > -1) { 09409 cmd = play_message(chan, vmu, vms); 09410 } else { 09411 cmd = ast_play_and_wait(chan, "vm-no"); 09412 if (!cmd) 09413 cmd = ast_play_and_wait(chan, "vm-message"); 09414 if (!cmd) { 09415 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09416 cmd = ast_play_and_wait(chan, vms->fn); 09417 } 09418 } 09419 return cmd; 09420 }
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 9456 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().
09457 { 09458 int cmd; 09459 09460 if (vms->lastmsg > -1) { 09461 cmd = play_message(chan, vmu, vms); 09462 } else { 09463 cmd = ast_play_and_wait(chan, "vm-no"); 09464 if (!cmd) { 09465 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09466 cmd = ast_play_and_wait(chan, vms->fn); 09467 } 09468 if (!cmd) 09469 cmd = ast_play_and_wait(chan, "vm-messages"); 09470 } 09471 return cmd; 09472 }
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 9510 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().
09511 { 09512 int cmd = 0; 09513 09514 if (vms->lastmsg > -1) { 09515 cmd = play_message(chan, vmu, vms); 09516 } else { 09517 cmd = ast_play_and_wait(chan, "vm-no"); 09518 if (!cmd) { 09519 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09520 cmd = ast_play_and_wait(chan, vms->fn); 09521 } 09522 } 09523 return cmd; 09524 }
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 9482 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().
09483 { 09484 int cmd; 09485 09486 if (vms->lastmsg > -1) { 09487 cmd = play_message(chan, vmu, vms); 09488 } else { 09489 cmd = ast_play_and_wait(chan, "vm-you"); 09490 if (!cmd) 09491 cmd = ast_play_and_wait(chan, "vm-haveno"); 09492 if (!cmd) 09493 cmd = ast_play_and_wait(chan, "vm-messages"); 09494 if (!cmd) { 09495 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09496 cmd = ast_play_and_wait(chan, vms->fn); 09497 } 09498 } 09499 return cmd; 09500 }
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 4073 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04074 { 04075 char *txt; 04076 int txtsize = 0; 04077 04078 txtsize = (strlen(file) + 5)*sizeof(char); 04079 txt = alloca(txtsize); 04080 /* Sprintf here would safe because we alloca'd exactly the right length, 04081 * but trying to eliminate all sprintf's anyhow 04082 */ 04083 if (ast_check_realtime("voicemail_data")) { 04084 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04085 } 04086 snprintf(txt, txtsize, "%s.txt", file); 04087 unlink(txt); 04088 return ast_filedelete(file, NULL); 04089 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10404 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().
10405 { 10406 int res = 0; 10407 char *tmp; 10408 struct leave_vm_options leave_options; 10409 struct ast_flags flags = { 0 }; 10410 char *opts[OPT_ARG_ARRAY_SIZE]; 10411 AST_DECLARE_APP_ARGS(args, 10412 AST_APP_ARG(argv0); 10413 AST_APP_ARG(argv1); 10414 ); 10415 10416 memset(&leave_options, 0, sizeof(leave_options)); 10417 10418 if (chan->_state != AST_STATE_UP) 10419 ast_answer(chan); 10420 10421 if (!ast_strlen_zero(data)) { 10422 tmp = ast_strdupa(data); 10423 AST_STANDARD_APP_ARGS(args, tmp); 10424 if (args.argc == 2) { 10425 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10426 return -1; 10427 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10428 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10429 int gain; 10430 10431 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10432 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10433 return -1; 10434 } else { 10435 leave_options.record_gain = (signed char) gain; 10436 } 10437 } 10438 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10439 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10440 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10441 } 10442 } 10443 } else { 10444 char temp[256]; 10445 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10446 if (res < 0) 10447 return res; 10448 if (ast_strlen_zero(temp)) 10449 return 0; 10450 args.argv0 = ast_strdupa(temp); 10451 } 10452 10453 res = leave_voicemail(chan, args.argv0, &leave_options); 10454 if (res == 't') { 10455 ast_play_and_wait(chan, "vm-goodbye"); 10456 res = 0; 10457 } 10458 10459 if (res == OPERATOR_EXIT) { 10460 res = 0; 10461 } 10462 10463 if (res == ERROR_LOCK_PATH) { 10464 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10465 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10466 res = 0; 10467 } 10468 10469 return res; 10470 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9674 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().
09675 { 09676 /* XXX This is, admittedly, some pretty horrendous code. For some 09677 reason it just seemed a lot easier to do with GOTO's. I feel 09678 like I'm back in my GWBASIC days. XXX */ 09679 int res = -1; 09680 int cmd = 0; 09681 int valid = 0; 09682 char prefixstr[80] =""; 09683 char ext_context[256]=""; 09684 int box; 09685 int useadsi = 0; 09686 int skipuser = 0; 09687 struct vm_state vms; 09688 struct ast_vm_user *vmu = NULL, vmus; 09689 char *context = NULL; 09690 int silentexit = 0; 09691 struct ast_flags flags = { 0 }; 09692 signed char record_gain = 0; 09693 int play_auto = 0; 09694 int play_folder = 0; 09695 int in_urgent = 0; 09696 #ifdef IMAP_STORAGE 09697 int deleted = 0; 09698 #endif 09699 09700 /* Add the vm_state to the active list and keep it active */ 09701 memset(&vms, 0, sizeof(vms)); 09702 09703 vms.lastmsg = -1; 09704 09705 memset(&vmus, 0, sizeof(vmus)); 09706 09707 if (chan->_state != AST_STATE_UP) { 09708 ast_debug(1, "Before ast_answer\n"); 09709 ast_answer(chan); 09710 } 09711 09712 if (!ast_strlen_zero(data)) { 09713 char *opts[OPT_ARG_ARRAY_SIZE]; 09714 char *parse; 09715 AST_DECLARE_APP_ARGS(args, 09716 AST_APP_ARG(argv0); 09717 AST_APP_ARG(argv1); 09718 ); 09719 09720 parse = ast_strdupa(data); 09721 09722 AST_STANDARD_APP_ARGS(args, parse); 09723 09724 if (args.argc == 2) { 09725 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09726 return -1; 09727 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09728 int gain; 09729 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09730 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09731 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09732 return -1; 09733 } else { 09734 record_gain = (signed char) gain; 09735 } 09736 } else { 09737 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09738 } 09739 } 09740 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09741 play_auto = 1; 09742 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09743 /* See if it is a folder name first */ 09744 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09745 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09746 play_folder = -1; 09747 } 09748 } else { 09749 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09750 } 09751 } else { 09752 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09753 } 09754 if (play_folder > 9 || play_folder < 0) { 09755 ast_log(AST_LOG_WARNING, 09756 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09757 opts[OPT_ARG_PLAYFOLDER]); 09758 play_folder = 0; 09759 } 09760 } 09761 } else { 09762 /* old style options parsing */ 09763 while (*(args.argv0)) { 09764 if (*(args.argv0) == 's') 09765 ast_set_flag(&flags, OPT_SILENT); 09766 else if (*(args.argv0) == 'p') 09767 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09768 else 09769 break; 09770 (args.argv0)++; 09771 } 09772 09773 } 09774 09775 valid = ast_test_flag(&flags, OPT_SILENT); 09776 09777 if ((context = strchr(args.argv0, '@'))) 09778 *context++ = '\0'; 09779 09780 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09781 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09782 else 09783 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09784 09785 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09786 skipuser++; 09787 else 09788 valid = 0; 09789 } 09790 09791 if (!valid) 09792 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09793 09794 ast_debug(1, "After vm_authenticate\n"); 09795 09796 if (vms.username[0] == '*') { 09797 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09798 09799 /* user entered '*' */ 09800 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09801 res = 0; /* prevent hangup */ 09802 goto out; 09803 } 09804 } 09805 09806 if (!res) { 09807 valid = 1; 09808 if (!skipuser) 09809 vmu = &vmus; 09810 } else { 09811 res = 0; 09812 } 09813 09814 /* If ADSI is supported, setup login screen */ 09815 adsi_begin(chan, &useadsi); 09816 09817 if (!valid) { 09818 goto out; 09819 } 09820 09821 #ifdef IMAP_STORAGE 09822 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 09823 pthread_setspecific(ts_vmstate.key, &vms); 09824 09825 vms.interactive = 1; 09826 vms.updated = 1; 09827 if (vmu) 09828 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 09829 vmstate_insert(&vms); 09830 init_vm_state(&vms); 09831 #endif 09832 /* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */ 09833 if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09834 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 09835 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09836 return -1; 09837 } 09838 if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09839 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 09840 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09841 return -1; 09842 } 09843 09844 /* Set language from config to override channel language */ 09845 if (!ast_strlen_zero(vmu->language)) 09846 ast_string_field_set(chan, language, vmu->language); 09847 09848 /* Retrieve urgent, old and new message counts */ 09849 ast_debug(1, "Before open_mailbox\n"); 09850 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09851 if (res < 0) 09852 goto out; 09853 vms.oldmessages = vms.lastmsg + 1; 09854 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 09855 /* check INBOX */ 09856 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09857 if (res < 0) 09858 goto out; 09859 vms.newmessages = vms.lastmsg + 1; 09860 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 09861 /* Start in Urgent */ 09862 in_urgent = 1; 09863 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 09864 if (res < 0) 09865 goto out; 09866 vms.urgentmessages = vms.lastmsg + 1; 09867 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 09868 09869 /* Select proper mailbox FIRST!! */ 09870 if (play_auto) { 09871 if (vms.urgentmessages) { 09872 in_urgent = 1; 09873 res = open_mailbox(&vms, vmu, 11); 09874 } else { 09875 in_urgent = 0; 09876 res = open_mailbox(&vms, vmu, play_folder); 09877 } 09878 if (res < 0) 09879 goto out; 09880 09881 /* If there are no new messages, inform the user and hangup */ 09882 if (vms.lastmsg == -1) { 09883 in_urgent = 0; 09884 cmd = vm_browse_messages(chan, &vms, vmu); 09885 res = 0; 09886 goto out; 09887 } 09888 } else { 09889 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 09890 /* If we only have old messages start here */ 09891 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09892 in_urgent = 0; 09893 play_folder = 1; 09894 if (res < 0) 09895 goto out; 09896 } else if (!vms.urgentmessages && vms.newmessages) { 09897 /* If we have new messages but none are urgent */ 09898 in_urgent = 0; 09899 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09900 if (res < 0) 09901 goto out; 09902 } 09903 } 09904 09905 if (useadsi) 09906 adsi_status(chan, &vms); 09907 res = 0; 09908 09909 /* Check to see if this is a new user */ 09910 if (!strcasecmp(vmu->mailbox, vmu->password) && 09911 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 09912 if (ast_play_and_wait(chan, "vm-newuser") == -1) 09913 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 09914 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 09915 if ((cmd == 't') || (cmd == '#')) { 09916 /* Timeout */ 09917 res = 0; 09918 goto out; 09919 } else if (cmd < 0) { 09920 /* Hangup */ 09921 res = -1; 09922 goto out; 09923 } 09924 } 09925 #ifdef IMAP_STORAGE 09926 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 09927 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 09928 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 09929 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09930 } 09931 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09932 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 09933 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09934 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09935 } 09936 #endif 09937 if (play_auto) { 09938 cmd = '1'; 09939 } else { 09940 cmd = vm_intro(chan, vmu, &vms); 09941 } 09942 09943 vms.repeats = 0; 09944 vms.starting = 1; 09945 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09946 /* Run main menu */ 09947 switch (cmd) { 09948 case '1': /* First message */ 09949 vms.curmsg = 0; 09950 /* Fall through */ 09951 case '5': /* Play current message */ 09952 cmd = vm_browse_messages(chan, &vms, vmu); 09953 break; 09954 case '2': /* Change folders */ 09955 if (useadsi) 09956 adsi_folders(chan, 0, "Change to folder..."); 09957 cmd = get_folder2(chan, "vm-changeto", 0); 09958 if (cmd == '#') { 09959 cmd = 0; 09960 } else if (cmd > 0) { 09961 cmd = cmd - '0'; 09962 res = close_mailbox(&vms, vmu); 09963 if (res == ERROR_LOCK_PATH) 09964 goto out; 09965 /* If folder is not urgent, set in_urgent to zero! */ 09966 if (cmd != 11) in_urgent = 0; 09967 res = open_mailbox(&vms, vmu, cmd); 09968 if (res < 0) 09969 goto out; 09970 play_folder = cmd; 09971 cmd = 0; 09972 } 09973 if (useadsi) 09974 adsi_status2(chan, &vms); 09975 09976 if (!cmd) 09977 cmd = vm_play_folder_name(chan, vms.vmbox); 09978 09979 vms.starting = 1; 09980 break; 09981 case '3': /* Advanced options */ 09982 cmd = 0; 09983 vms.repeats = 0; 09984 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09985 switch (cmd) { 09986 case '1': /* Reply */ 09987 if (vms.lastmsg > -1 && !vms.starting) { 09988 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 09989 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 09990 res = cmd; 09991 goto out; 09992 } 09993 } else 09994 cmd = ast_play_and_wait(chan, "vm-sorry"); 09995 cmd = 't'; 09996 break; 09997 case '2': /* Callback */ 09998 if (!vms.starting) 09999 ast_verb(3, "Callback Requested\n"); 10000 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10001 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10002 if (cmd == 9) { 10003 silentexit = 1; 10004 goto out; 10005 } else if (cmd == ERROR_LOCK_PATH) { 10006 res = cmd; 10007 goto out; 10008 } 10009 } else 10010 cmd = ast_play_and_wait(chan, "vm-sorry"); 10011 cmd = 't'; 10012 break; 10013 case '3': /* Envelope */ 10014 if (vms.lastmsg > -1 && !vms.starting) { 10015 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10016 if (cmd == ERROR_LOCK_PATH) { 10017 res = cmd; 10018 goto out; 10019 } 10020 } else 10021 cmd = ast_play_and_wait(chan, "vm-sorry"); 10022 cmd = 't'; 10023 break; 10024 case '4': /* Dialout */ 10025 if (!ast_strlen_zero(vmu->dialout)) { 10026 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10027 if (cmd == 9) { 10028 silentexit = 1; 10029 goto out; 10030 } 10031 } else 10032 cmd = ast_play_and_wait(chan, "vm-sorry"); 10033 cmd = 't'; 10034 break; 10035 10036 case '5': /* Leave VoiceMail */ 10037 if (ast_test_flag(vmu, VM_SVMAIL)) { 10038 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10039 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10040 res = cmd; 10041 goto out; 10042 } 10043 } else 10044 cmd = ast_play_and_wait(chan, "vm-sorry"); 10045 cmd = 't'; 10046 break; 10047 10048 case '*': /* Return to main menu */ 10049 cmd = 't'; 10050 break; 10051 10052 default: 10053 cmd = 0; 10054 if (!vms.starting) { 10055 cmd = ast_play_and_wait(chan, "vm-toreply"); 10056 } 10057 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10058 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10059 } 10060 if (!cmd && !vms.starting) { 10061 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10062 } 10063 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10064 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10065 } 10066 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) 10067 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10068 if (!cmd) 10069 cmd = ast_play_and_wait(chan, "vm-starmain"); 10070 if (!cmd) 10071 cmd = ast_waitfordigit(chan, 6000); 10072 if (!cmd) 10073 vms.repeats++; 10074 if (vms.repeats > 3) 10075 cmd = 't'; 10076 } 10077 } 10078 if (cmd == 't') { 10079 cmd = 0; 10080 vms.repeats = 0; 10081 } 10082 break; 10083 case '4': /* Go to the previous message */ 10084 if (vms.curmsg > 0) { 10085 vms.curmsg--; 10086 cmd = play_message(chan, vmu, &vms); 10087 } else { 10088 /* Check if we were listening to new 10089 messages. If so, go to Urgent messages 10090 instead of saying "no more messages" 10091 */ 10092 if (in_urgent == 0 && vms.urgentmessages > 0) { 10093 /* Check for Urgent messages */ 10094 in_urgent = 1; 10095 res = close_mailbox(&vms, vmu); 10096 if (res == ERROR_LOCK_PATH) 10097 goto out; 10098 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10099 if (res < 0) 10100 goto out; 10101 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10102 vms.curmsg = vms.lastmsg; 10103 if (vms.lastmsg < 0) 10104 cmd = ast_play_and_wait(chan, "vm-nomore"); 10105 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10106 vms.curmsg = vms.lastmsg; 10107 cmd = play_message(chan, vmu, &vms); 10108 } else { 10109 cmd = ast_play_and_wait(chan, "vm-nomore"); 10110 } 10111 } 10112 break; 10113 case '6': /* Go to the next message */ 10114 if (vms.curmsg < vms.lastmsg) { 10115 vms.curmsg++; 10116 cmd = play_message(chan, vmu, &vms); 10117 } else { 10118 if (in_urgent && vms.newmessages > 0) { 10119 /* Check if we were listening to urgent 10120 * messages. If so, go to regular new messages 10121 * instead of saying "no more messages" 10122 */ 10123 in_urgent = 0; 10124 res = close_mailbox(&vms, vmu); 10125 if (res == ERROR_LOCK_PATH) 10126 goto out; 10127 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10128 if (res < 0) 10129 goto out; 10130 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10131 vms.curmsg = -1; 10132 if (vms.lastmsg < 0) { 10133 cmd = ast_play_and_wait(chan, "vm-nomore"); 10134 } 10135 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10136 vms.curmsg = 0; 10137 cmd = play_message(chan, vmu, &vms); 10138 } else { 10139 cmd = ast_play_and_wait(chan, "vm-nomore"); 10140 } 10141 } 10142 break; 10143 case '7': /* Delete the current message */ 10144 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10145 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10146 if (useadsi) 10147 adsi_delete(chan, &vms); 10148 if (vms.deleted[vms.curmsg]) { 10149 if (play_folder == 0) { 10150 if (in_urgent) { 10151 vms.urgentmessages--; 10152 } else { 10153 vms.newmessages--; 10154 } 10155 } 10156 else if (play_folder == 1) 10157 vms.oldmessages--; 10158 cmd = ast_play_and_wait(chan, "vm-deleted"); 10159 } else { 10160 if (play_folder == 0) { 10161 if (in_urgent) { 10162 vms.urgentmessages++; 10163 } else { 10164 vms.newmessages++; 10165 } 10166 } 10167 else if (play_folder == 1) 10168 vms.oldmessages++; 10169 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10170 } 10171 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10172 if (vms.curmsg < vms.lastmsg) { 10173 vms.curmsg++; 10174 cmd = play_message(chan, vmu, &vms); 10175 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10176 vms.curmsg = 0; 10177 cmd = play_message(chan, vmu, &vms); 10178 } else { 10179 /* Check if we were listening to urgent 10180 messages. If so, go to regular new messages 10181 instead of saying "no more messages" 10182 */ 10183 if (in_urgent == 1) { 10184 /* Check for new messages */ 10185 in_urgent = 0; 10186 res = close_mailbox(&vms, vmu); 10187 if (res == ERROR_LOCK_PATH) 10188 goto out; 10189 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10190 if (res < 0) 10191 goto out; 10192 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10193 vms.curmsg = -1; 10194 if (vms.lastmsg < 0) 10195 cmd = ast_play_and_wait(chan, "vm-nomore"); 10196 } else { 10197 cmd = ast_play_and_wait(chan, "vm-nomore"); 10198 } 10199 } 10200 } 10201 } else /* Delete not valid if we haven't selected a message */ 10202 cmd = 0; 10203 #ifdef IMAP_STORAGE 10204 deleted = 1; 10205 #endif 10206 break; 10207 10208 case '8': /* Forward the current messgae */ 10209 if (vms.lastmsg > -1) { 10210 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10211 if (cmd == ERROR_LOCK_PATH) { 10212 res = cmd; 10213 goto out; 10214 } 10215 } else { 10216 /* Check if we were listening to urgent 10217 messages. If so, go to regular new messages 10218 instead of saying "no more messages" 10219 */ 10220 if (in_urgent == 1 && vms.newmessages > 0) { 10221 /* Check for new messages */ 10222 in_urgent = 0; 10223 res = close_mailbox(&vms, vmu); 10224 if (res == ERROR_LOCK_PATH) 10225 goto out; 10226 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10227 if (res < 0) 10228 goto out; 10229 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10230 vms.curmsg = -1; 10231 if (vms.lastmsg < 0) 10232 cmd = ast_play_and_wait(chan, "vm-nomore"); 10233 } else { 10234 cmd = ast_play_and_wait(chan, "vm-nomore"); 10235 } 10236 } 10237 break; 10238 case '9': /* Save message to folder */ 10239 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10240 /* No message selected */ 10241 cmd = 0; 10242 break; 10243 } 10244 if (useadsi) 10245 adsi_folders(chan, 1, "Save to folder..."); 10246 cmd = get_folder2(chan, "vm-savefolder", 1); 10247 box = 0; /* Shut up compiler */ 10248 if (cmd == '#') { 10249 cmd = 0; 10250 break; 10251 } else if (cmd > 0) { 10252 box = cmd = cmd - '0'; 10253 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10254 if (cmd == ERROR_LOCK_PATH) { 10255 res = cmd; 10256 goto out; 10257 #ifndef IMAP_STORAGE 10258 } else if (!cmd) { 10259 vms.deleted[vms.curmsg] = 1; 10260 #endif 10261 } else { 10262 vms.deleted[vms.curmsg] = 0; 10263 vms.heard[vms.curmsg] = 0; 10264 } 10265 } 10266 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10267 if (useadsi) 10268 adsi_message(chan, &vms); 10269 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10270 if (!cmd) { 10271 cmd = ast_play_and_wait(chan, "vm-message"); 10272 if (!cmd) 10273 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10274 if (!cmd) 10275 cmd = ast_play_and_wait(chan, "vm-savedto"); 10276 if (!cmd) 10277 cmd = vm_play_folder_name(chan, vms.fn); 10278 } else { 10279 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10280 } 10281 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10282 if (vms.curmsg < vms.lastmsg) { 10283 vms.curmsg++; 10284 cmd = play_message(chan, vmu, &vms); 10285 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10286 vms.curmsg = 0; 10287 cmd = play_message(chan, vmu, &vms); 10288 } else { 10289 /* Check if we were listening to urgent 10290 messages. If so, go to regular new messages 10291 instead of saying "no more messages" 10292 */ 10293 if (in_urgent == 1 && vms.newmessages > 0) { 10294 /* Check for new messages */ 10295 in_urgent = 0; 10296 res = close_mailbox(&vms, vmu); 10297 if (res == ERROR_LOCK_PATH) 10298 goto out; 10299 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10300 if (res < 0) 10301 goto out; 10302 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10303 vms.curmsg = -1; 10304 if (vms.lastmsg < 0) 10305 cmd = ast_play_and_wait(chan, "vm-nomore"); 10306 } else { 10307 cmd = ast_play_and_wait(chan, "vm-nomore"); 10308 } 10309 } 10310 } 10311 break; 10312 case '*': /* Help */ 10313 if (!vms.starting) { 10314 cmd = ast_play_and_wait(chan, "vm-onefor"); 10315 if (!strncasecmp(chan->language, "he", 2)) { 10316 cmd = ast_play_and_wait(chan, "vm-for"); 10317 } 10318 if (!cmd) 10319 cmd = vm_play_folder_name(chan, vms.vmbox); 10320 if (!cmd) 10321 cmd = ast_play_and_wait(chan, "vm-opts"); 10322 if (!cmd) 10323 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10324 } else 10325 cmd = 0; 10326 break; 10327 case '0': /* Mailbox options */ 10328 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10329 if (useadsi) 10330 adsi_status(chan, &vms); 10331 break; 10332 default: /* Nothing */ 10333 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10334 break; 10335 } 10336 } 10337 if ((cmd == 't') || (cmd == '#')) { 10338 /* Timeout */ 10339 res = 0; 10340 } else { 10341 /* Hangup */ 10342 res = -1; 10343 } 10344 10345 out: 10346 if (res > -1) { 10347 ast_stopstream(chan); 10348 adsi_goodbye(chan); 10349 if (valid && res != OPERATOR_EXIT) { 10350 if (silentexit) 10351 res = ast_play_and_wait(chan, "vm-dialout"); 10352 else 10353 res = ast_play_and_wait(chan, "vm-goodbye"); 10354 } 10355 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10356 res = 0; 10357 } 10358 if (useadsi) 10359 ast_adsi_unload_session(chan); 10360 } 10361 if (vmu) 10362 close_mailbox(&vms, vmu); 10363 if (valid) { 10364 int new = 0, old = 0, urgent = 0; 10365 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10366 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10367 /* Urgent flag not passwd to externnotify here */ 10368 run_externnotify(vmu->context, vmu->mailbox, NULL); 10369 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10370 queue_mwi_event(ext_context, urgent, new, old); 10371 } 10372 #ifdef IMAP_STORAGE 10373 /* expunge message - use UID Expunge if supported on IMAP server*/ 10374 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10375 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10376 ast_mutex_lock(&vms.lock); 10377 #ifdef HAVE_IMAP_TK2006 10378 if (LEVELUIDPLUS (vms.mailstream)) { 10379 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10380 } else 10381 #endif 10382 mail_expunge(vms.mailstream); 10383 ast_mutex_unlock(&vms.lock); 10384 } 10385 /* before we delete the state, we should copy pertinent info 10386 * back to the persistent model */ 10387 if (vmu) { 10388 vmstate_delete(&vms); 10389 } 10390 #endif 10391 if (vmu) 10392 free_user(vmu); 10393 if (vms.deleted) 10394 ast_free(vms.deleted); 10395 if (vms.heard) 10396 ast_free(vms.heard); 10397 10398 #ifdef IMAP_STORAGE 10399 pthread_setspecific(ts_vmstate.key, NULL); 10400 #endif 10401 return res; 10402 }
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 6711 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().
06713 { 06714 #ifdef IMAP_STORAGE 06715 int res; 06716 #endif 06717 int cmd = 0; 06718 int retries = 0, prepend_duration = 0, already_recorded = 0; 06719 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06720 char textfile[PATH_MAX]; 06721 struct ast_config *msg_cfg; 06722 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06723 #ifndef IMAP_STORAGE 06724 signed char zero_gain = 0; 06725 #endif 06726 const char *duration_str; 06727 06728 /* Must always populate duration correctly */ 06729 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06730 strcpy(textfile, msgfile); 06731 strcpy(backup, msgfile); 06732 strcpy(backup_textfile, msgfile); 06733 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06734 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06735 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06736 06737 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06738 *duration = atoi(duration_str); 06739 } else { 06740 *duration = 0; 06741 } 06742 06743 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06744 if (cmd) 06745 retries = 0; 06746 switch (cmd) { 06747 case '1': 06748 06749 #ifdef IMAP_STORAGE 06750 /* Record new intro file */ 06751 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06752 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06753 res = ast_play_and_wait(chan, INTRO); 06754 res = ast_play_and_wait(chan, "beep"); 06755 res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, record_gain, vms, flag); 06756 cmd = 't'; 06757 #else 06758 06759 /* prepend a message to the current message, update the metadata and return */ 06760 06761 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06762 strcpy(textfile, msgfile); 06763 strncat(textfile, ".txt", sizeof(textfile) - 1); 06764 *duration = 0; 06765 06766 /* if we can't read the message metadata, stop now */ 06767 if (!msg_cfg) { 06768 cmd = 0; 06769 break; 06770 } 06771 06772 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06773 #ifndef IMAP_STORAGE 06774 if (already_recorded) { 06775 ast_filecopy(backup, msgfile, NULL); 06776 copy(backup_textfile, textfile); 06777 } 06778 else { 06779 ast_filecopy(msgfile, backup, NULL); 06780 copy(textfile, backup_textfile); 06781 } 06782 #endif 06783 already_recorded = 1; 06784 06785 if (record_gain) 06786 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06787 06788 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence); 06789 if (cmd == 'S') { 06790 ast_filerename(backup, msgfile, NULL); 06791 } 06792 06793 if (record_gain) 06794 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06795 06796 06797 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06798 *duration = atoi(duration_str); 06799 06800 if (prepend_duration) { 06801 struct ast_category *msg_cat; 06802 /* need enough space for a maximum-length message duration */ 06803 char duration_buf[12]; 06804 06805 *duration += prepend_duration; 06806 msg_cat = ast_category_get(msg_cfg, "message"); 06807 snprintf(duration_buf, 11, "%ld", *duration); 06808 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06809 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06810 } 06811 } 06812 06813 #endif 06814 break; 06815 case '2': 06816 /* NULL out introfile so we know there is no intro! */ 06817 #ifdef IMAP_STORAGE 06818 *vms->introfn = '\0'; 06819 #endif 06820 cmd = 't'; 06821 break; 06822 case '*': 06823 cmd = '*'; 06824 break; 06825 default: 06826 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06827 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06828 if (!cmd) 06829 cmd = ast_play_and_wait(chan, "vm-starmain"); 06830 /* "press star to return to the main menu" */ 06831 if (!cmd) 06832 cmd = ast_waitfordigit(chan, 6000); 06833 if (!cmd) 06834 retries++; 06835 if (retries > 3) 06836 cmd = 't'; 06837 } 06838 } 06839 06840 if (msg_cfg) 06841 ast_config_destroy(msg_cfg); 06842 if (prepend_duration) 06843 *duration = prepend_duration; 06844 06845 if (already_recorded && cmd == -1) { 06846 /* restore original message if prepention cancelled */ 06847 ast_filerename(backup, msgfile, NULL); 06848 rename(backup_textfile, textfile); 06849 } 06850 06851 if (cmd == 't' || cmd == 'S') 06852 cmd = 0; 06853 return cmd; 06854 }
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 9015 of file app_voicemail.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
09016 { 09017 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09018 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09019 } else { /* Default to ENGLISH */ 09020 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09021 } 09022 }
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 8914 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().
08915 { 08916 int res = 0; 08917 /* Play instructions and wait for new command */ 08918 while (!res) { 08919 if (vms->starting) { 08920 if (vms->lastmsg > -1) { 08921 if (skipadvanced) 08922 res = ast_play_and_wait(chan, "vm-onefor-full"); 08923 else 08924 res = ast_play_and_wait(chan, "vm-onefor"); 08925 if (!res) 08926 res = vm_play_folder_name(chan, vms->vmbox); 08927 } 08928 if (!res) { 08929 if (skipadvanced) 08930 res = ast_play_and_wait(chan, "vm-opts-full"); 08931 else 08932 res = ast_play_and_wait(chan, "vm-opts"); 08933 } 08934 } else { 08935 /* Added for additional help */ 08936 if (skipadvanced) { 08937 res = ast_play_and_wait(chan, "vm-onefor-full"); 08938 if (!res) 08939 res = vm_play_folder_name(chan, vms->vmbox); 08940 res = ast_play_and_wait(chan, "vm-opts-full"); 08941 } 08942 /* Logic: 08943 * If the current message is not the first OR 08944 * if we're listening to the first new message and there are 08945 * also urgent messages, then prompt for navigation to the 08946 * previous message 08947 */ 08948 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 08949 res = ast_play_and_wait(chan, "vm-prev"); 08950 } 08951 if (!res && !skipadvanced) 08952 res = ast_play_and_wait(chan, "vm-advopts"); 08953 if (!res) 08954 res = ast_play_and_wait(chan, "vm-repeat"); 08955 /* Logic: 08956 * If we're not listening to the last message OR 08957 * we're listening to the last urgent message and there are 08958 * also new non-urgent messages, then prompt for navigation 08959 * to the next message 08960 */ 08961 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 08962 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 08963 res = ast_play_and_wait(chan, "vm-next"); 08964 } 08965 if (!res) { 08966 if (!vms->deleted[vms->curmsg]) 08967 res = ast_play_and_wait(chan, "vm-delete"); 08968 else 08969 res = ast_play_and_wait(chan, "vm-undelete"); 08970 if (!res) 08971 res = ast_play_and_wait(chan, "vm-toforward"); 08972 if (!res) 08973 res = ast_play_and_wait(chan, "vm-savemessage"); 08974 } 08975 } 08976 if (!res) { 08977 res = ast_play_and_wait(chan, "vm-helpexit"); 08978 } 08979 if (!res) 08980 res = ast_waitfordigit(chan, 6000); 08981 if (!res) { 08982 vms->repeats++; 08983 if (vms->repeats > 2) { 08984 res = 't'; 08985 } 08986 } 08987 } 08988 return res; 08989 }
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 8991 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().
08992 { 08993 int res = 0; 08994 /* Play instructions and wait for new command */ 08995 while (!res) { 08996 if (vms->lastmsg > -1) { 08997 res = ast_play_and_wait(chan, "vm-listen"); 08998 if (!res) 08999 res = vm_play_folder_name(chan, vms->vmbox); 09000 if (!res) 09001 res = ast_play_and_wait(chan, "press"); 09002 if (!res) 09003 res = ast_play_and_wait(chan, "digits/1"); 09004 } 09005 if (!res) 09006 res = ast_play_and_wait(chan, "vm-opts"); 09007 if (!res) { 09008 vms->starting = 0; 09009 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09010 } 09011 } 09012 return res; 09013 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 8852 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().
08853 { 08854 char prefile[256]; 08855 08856 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08857 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08858 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08859 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08860 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08861 ast_play_and_wait(chan, "vm-tempgreetactive"); 08862 } 08863 DISPOSE(prefile, -1); 08864 } 08865 08866 /* Play voicemail intro - syntax is different for different languages */ 08867 if (0) { 08868 return 0; 08869 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 08870 return vm_intro_cs(chan, vms); 08871 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 08872 static int deprecation_warning = 0; 08873 if (deprecation_warning++ % 10 == 0) { 08874 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 08875 } 08876 return vm_intro_cs(chan, vms); 08877 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 08878 return vm_intro_de(chan, vms); 08879 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 08880 return vm_intro_es(chan, vms); 08881 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 08882 return vm_intro_fr(chan, vms); 08883 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 08884 return vm_intro_gr(chan, vms); 08885 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 08886 return vm_intro_he(chan, vms); 08887 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 08888 return vm_intro_it(chan, vms); 08889 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 08890 return vm_intro_nl(chan, vms); 08891 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 08892 return vm_intro_no(chan, vms); 08893 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 08894 return vm_intro_pl(chan, vms); 08895 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 08896 return vm_intro_pt_BR(chan, vms); 08897 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 08898 return vm_intro_pt(chan, vms); 08899 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 08900 return vm_intro_multilang(chan, vms, "n"); 08901 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 08902 return vm_intro_se(chan, vms); 08903 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 08904 return vm_intro_multilang(chan, vms, "n"); 08905 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 08906 return vm_intro_vi(chan, vms); 08907 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08908 return vm_intro_zh(chan, vms); 08909 } else { /* Default to ENGLISH */ 08910 return vm_intro_en(chan, vms); 08911 } 08912 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8722 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().
08723 { 08724 int res; 08725 res = ast_play_and_wait(chan, "vm-youhave"); 08726 if (!res) { 08727 if (vms->newmessages) { 08728 if (vms->newmessages == 1) { 08729 res = ast_play_and_wait(chan, "digits/jednu"); 08730 } else { 08731 res = say_and_wait(chan, vms->newmessages, chan->language); 08732 } 08733 if (!res) { 08734 if ((vms->newmessages == 1)) 08735 res = ast_play_and_wait(chan, "vm-novou"); 08736 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08737 res = ast_play_and_wait(chan, "vm-nove"); 08738 if (vms->newmessages > 4) 08739 res = ast_play_and_wait(chan, "vm-novych"); 08740 } 08741 if (vms->oldmessages && !res) 08742 res = ast_play_and_wait(chan, "vm-and"); 08743 else if (!res) { 08744 if ((vms->newmessages == 1)) 08745 res = ast_play_and_wait(chan, "vm-zpravu"); 08746 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08747 res = ast_play_and_wait(chan, "vm-zpravy"); 08748 if (vms->newmessages > 4) 08749 res = ast_play_and_wait(chan, "vm-zprav"); 08750 } 08751 } 08752 if (!res && vms->oldmessages) { 08753 res = say_and_wait(chan, vms->oldmessages, chan->language); 08754 if (!res) { 08755 if ((vms->oldmessages == 1)) 08756 res = ast_play_and_wait(chan, "vm-starou"); 08757 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08758 res = ast_play_and_wait(chan, "vm-stare"); 08759 if (vms->oldmessages > 4) 08760 res = ast_play_and_wait(chan, "vm-starych"); 08761 } 08762 if (!res) { 08763 if ((vms->oldmessages == 1)) 08764 res = ast_play_and_wait(chan, "vm-zpravu"); 08765 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08766 res = ast_play_and_wait(chan, "vm-zpravy"); 08767 if (vms->oldmessages > 4) 08768 res = ast_play_and_wait(chan, "vm-zprav"); 08769 } 08770 } 08771 if (!res) { 08772 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08773 res = ast_play_and_wait(chan, "vm-no"); 08774 if (!res) 08775 res = ast_play_and_wait(chan, "vm-zpravy"); 08776 } 08777 } 08778 } 08779 return res; 08780 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8418 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().
08419 { 08420 /* Introduce messages they have */ 08421 int res; 08422 res = ast_play_and_wait(chan, "vm-youhave"); 08423 if (!res) { 08424 if (vms->newmessages) { 08425 if ((vms->newmessages == 1)) 08426 res = ast_play_and_wait(chan, "digits/1F"); 08427 else 08428 res = say_and_wait(chan, vms->newmessages, chan->language); 08429 if (!res) 08430 res = ast_play_and_wait(chan, "vm-INBOX"); 08431 if (vms->oldmessages && !res) 08432 res = ast_play_and_wait(chan, "vm-and"); 08433 else if (!res) { 08434 if ((vms->newmessages == 1)) 08435 res = ast_play_and_wait(chan, "vm-message"); 08436 else 08437 res = ast_play_and_wait(chan, "vm-messages"); 08438 } 08439 08440 } 08441 if (!res && vms->oldmessages) { 08442 if (vms->oldmessages == 1) 08443 res = ast_play_and_wait(chan, "digits/1F"); 08444 else 08445 res = say_and_wait(chan, vms->oldmessages, chan->language); 08446 if (!res) 08447 res = ast_play_and_wait(chan, "vm-Old"); 08448 if (!res) { 08449 if (vms->oldmessages == 1) 08450 res = ast_play_and_wait(chan, "vm-message"); 08451 else 08452 res = ast_play_and_wait(chan, "vm-messages"); 08453 } 08454 } 08455 if (!res) { 08456 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08457 res = ast_play_and_wait(chan, "vm-no"); 08458 if (!res) 08459 res = ast_play_and_wait(chan, "vm-messages"); 08460 } 08461 } 08462 } 08463 return res; 08464 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8167 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().
08168 { 08169 int res; 08170 08171 /* Introduce messages they have */ 08172 res = ast_play_and_wait(chan, "vm-youhave"); 08173 if (!res) { 08174 if (vms->urgentmessages) { 08175 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08176 if (!res) 08177 res = ast_play_and_wait(chan, "vm-Urgent"); 08178 if ((vms->oldmessages || vms->newmessages) && !res) { 08179 res = ast_play_and_wait(chan, "vm-and"); 08180 } else if (!res) { 08181 if ((vms->urgentmessages == 1)) 08182 res = ast_play_and_wait(chan, "vm-message"); 08183 else 08184 res = ast_play_and_wait(chan, "vm-messages"); 08185 } 08186 } 08187 if (vms->newmessages) { 08188 res = say_and_wait(chan, vms->newmessages, chan->language); 08189 if (!res) 08190 res = ast_play_and_wait(chan, "vm-INBOX"); 08191 if (vms->oldmessages && !res) 08192 res = ast_play_and_wait(chan, "vm-and"); 08193 else if (!res) { 08194 if ((vms->newmessages == 1)) 08195 res = ast_play_and_wait(chan, "vm-message"); 08196 else 08197 res = ast_play_and_wait(chan, "vm-messages"); 08198 } 08199 08200 } 08201 if (!res && vms->oldmessages) { 08202 res = say_and_wait(chan, vms->oldmessages, chan->language); 08203 if (!res) 08204 res = ast_play_and_wait(chan, "vm-Old"); 08205 if (!res) { 08206 if (vms->oldmessages == 1) 08207 res = ast_play_and_wait(chan, "vm-message"); 08208 else 08209 res = ast_play_and_wait(chan, "vm-messages"); 08210 } 08211 } 08212 if (!res) { 08213 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08214 res = ast_play_and_wait(chan, "vm-no"); 08215 if (!res) 08216 res = ast_play_and_wait(chan, "vm-messages"); 08217 } 08218 } 08219 } 08220 return res; 08221 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8467 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().
08468 { 08469 /* Introduce messages they have */ 08470 int res; 08471 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08472 res = ast_play_and_wait(chan, "vm-youhaveno"); 08473 if (!res) 08474 res = ast_play_and_wait(chan, "vm-messages"); 08475 } else { 08476 res = ast_play_and_wait(chan, "vm-youhave"); 08477 } 08478 if (!res) { 08479 if (vms->newmessages) { 08480 if (!res) { 08481 if ((vms->newmessages == 1)) { 08482 res = ast_play_and_wait(chan, "digits/1M"); 08483 if (!res) 08484 res = ast_play_and_wait(chan, "vm-message"); 08485 if (!res) 08486 res = ast_play_and_wait(chan, "vm-INBOXs"); 08487 } else { 08488 res = say_and_wait(chan, vms->newmessages, chan->language); 08489 if (!res) 08490 res = ast_play_and_wait(chan, "vm-messages"); 08491 if (!res) 08492 res = ast_play_and_wait(chan, "vm-INBOX"); 08493 } 08494 } 08495 if (vms->oldmessages && !res) 08496 res = ast_play_and_wait(chan, "vm-and"); 08497 } 08498 if (vms->oldmessages) { 08499 if (!res) { 08500 if (vms->oldmessages == 1) { 08501 res = ast_play_and_wait(chan, "digits/1M"); 08502 if (!res) 08503 res = ast_play_and_wait(chan, "vm-message"); 08504 if (!res) 08505 res = ast_play_and_wait(chan, "vm-Olds"); 08506 } else { 08507 res = say_and_wait(chan, vms->oldmessages, chan->language); 08508 if (!res) 08509 res = ast_play_and_wait(chan, "vm-messages"); 08510 if (!res) 08511 res = ast_play_and_wait(chan, "vm-Old"); 08512 } 08513 } 08514 } 08515 } 08516 return res; 08517 }
static int vm_intro_fr | ( | 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 res = ast_play_and_wait(chan, "vm-INBOX"); 08575 if (vms->oldmessages && !res) 08576 res = ast_play_and_wait(chan, "vm-and"); 08577 else if (!res) { 08578 if ((vms->newmessages == 1)) 08579 res = ast_play_and_wait(chan, "vm-message"); 08580 else 08581 res = ast_play_and_wait(chan, "vm-messages"); 08582 } 08583 08584 } 08585 if (!res && vms->oldmessages) { 08586 res = say_and_wait(chan, vms->oldmessages, chan->language); 08587 if (!res) 08588 res = ast_play_and_wait(chan, "vm-Old"); 08589 if (!res) { 08590 if (vms->oldmessages == 1) 08591 res = ast_play_and_wait(chan, "vm-message"); 08592 else 08593 res = ast_play_and_wait(chan, "vm-messages"); 08594 } 08595 } 08596 if (!res) { 08597 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08598 res = ast_play_and_wait(chan, "vm-no"); 08599 if (!res) 08600 res = ast_play_and_wait(chan, "vm-messages"); 08601 } 08602 } 08603 } 08604 return res; 08605 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7966 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().
07967 { 07968 int res = 0; 07969 07970 if (vms->newmessages) { 07971 res = ast_play_and_wait(chan, "vm-youhave"); 07972 if (!res) 07973 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 07974 if (!res) { 07975 if ((vms->newmessages == 1)) { 07976 res = ast_play_and_wait(chan, "vm-INBOX"); 07977 if (!res) 07978 res = ast_play_and_wait(chan, "vm-message"); 07979 } else { 07980 res = ast_play_and_wait(chan, "vm-INBOXs"); 07981 if (!res) 07982 res = ast_play_and_wait(chan, "vm-messages"); 07983 } 07984 } 07985 } else if (vms->oldmessages){ 07986 res = ast_play_and_wait(chan, "vm-youhave"); 07987 if (!res) 07988 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 07989 if ((vms->oldmessages == 1)){ 07990 res = ast_play_and_wait(chan, "vm-Old"); 07991 if (!res) 07992 res = ast_play_and_wait(chan, "vm-message"); 07993 } else { 07994 res = ast_play_and_wait(chan, "vm-Olds"); 07995 if (!res) 07996 res = ast_play_and_wait(chan, "vm-messages"); 07997 } 07998 } else if (!vms->oldmessages && !vms->newmessages) 07999 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08000 return res; 08001 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8100 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().
08101 { 08102 int res = 0; 08103 08104 /* Introduce messages they have */ 08105 if (!res) { 08106 if ((vms->newmessages) || (vms->oldmessages)) { 08107 res = ast_play_and_wait(chan, "vm-youhave"); 08108 } 08109 /* 08110 * The word "shtei" refers to the number 2 in hebrew when performing a count 08111 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08112 * an element, this is one of them. 08113 */ 08114 if (vms->newmessages) { 08115 if (!res) { 08116 if (vms->newmessages == 1) { 08117 res = ast_play_and_wait(chan, "vm-INBOX1"); 08118 } else { 08119 if (vms->newmessages == 2) { 08120 res = ast_play_and_wait(chan, "vm-shtei"); 08121 } else { 08122 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08123 } 08124 res = ast_play_and_wait(chan, "vm-INBOX"); 08125 } 08126 } 08127 if (vms->oldmessages && !res) { 08128 res = ast_play_and_wait(chan, "vm-and"); 08129 if (vms->oldmessages == 1) { 08130 res = ast_play_and_wait(chan, "vm-Old1"); 08131 } else { 08132 if (vms->oldmessages == 2) { 08133 res = ast_play_and_wait(chan, "vm-shtei"); 08134 } else { 08135 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08136 } 08137 res = ast_play_and_wait(chan, "vm-Old"); 08138 } 08139 } 08140 } 08141 if (!res && vms->oldmessages && !vms->newmessages) { 08142 if (!res) { 08143 if (vms->oldmessages == 1) { 08144 res = ast_play_and_wait(chan, "vm-Old1"); 08145 } else { 08146 if (vms->oldmessages == 2) { 08147 res = ast_play_and_wait(chan, "vm-shtei"); 08148 } else { 08149 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08150 } 08151 res = ast_play_and_wait(chan, "vm-Old"); 08152 } 08153 } 08154 } 08155 if (!res) { 08156 if (!vms->oldmessages && !vms->newmessages) { 08157 if (!res) { 08158 res = ast_play_and_wait(chan, "vm-nomessages"); 08159 } 08160 } 08161 } 08162 } 08163 return res; 08164 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8224 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().
08225 { 08226 /* Introduce messages they have */ 08227 int res; 08228 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08229 res = ast_play_and_wait(chan, "vm-no") || 08230 ast_play_and_wait(chan, "vm-message"); 08231 else 08232 res = ast_play_and_wait(chan, "vm-youhave"); 08233 if (!res && vms->newmessages) { 08234 res = (vms->newmessages == 1) ? 08235 ast_play_and_wait(chan, "digits/un") || 08236 ast_play_and_wait(chan, "vm-nuovo") || 08237 ast_play_and_wait(chan, "vm-message") : 08238 /* 2 or more new messages */ 08239 say_and_wait(chan, vms->newmessages, chan->language) || 08240 ast_play_and_wait(chan, "vm-nuovi") || 08241 ast_play_and_wait(chan, "vm-messages"); 08242 if (!res && vms->oldmessages) 08243 res = ast_play_and_wait(chan, "vm-and"); 08244 } 08245 if (!res && vms->oldmessages) { 08246 res = (vms->oldmessages == 1) ? 08247 ast_play_and_wait(chan, "digits/un") || 08248 ast_play_and_wait(chan, "vm-vecchio") || 08249 ast_play_and_wait(chan, "vm-message") : 08250 /* 2 or more old messages */ 08251 say_and_wait(chan, vms->oldmessages, chan->language) || 08252 ast_play_and_wait(chan, "vm-vecchi") || 08253 ast_play_and_wait(chan, "vm-messages"); 08254 } 08255 return res; 08256 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8060 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().
08061 { 08062 int res; 08063 int lastnum = 0; 08064 08065 res = ast_play_and_wait(chan, "vm-youhave"); 08066 08067 if (!res && vms->newmessages) { 08068 lastnum = vms->newmessages; 08069 08070 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08071 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08072 } 08073 08074 if (!res && vms->oldmessages) { 08075 res = ast_play_and_wait(chan, "vm-and"); 08076 } 08077 } 08078 08079 if (!res && vms->oldmessages) { 08080 lastnum = vms->oldmessages; 08081 08082 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08083 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08084 } 08085 } 08086 08087 if (!res) { 08088 if (lastnum == 0) { 08089 res = ast_play_and_wait(chan, "vm-no"); 08090 } 08091 if (!res) { 08092 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08093 } 08094 } 08095 08096 return res; 08097 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8608 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().
08609 { 08610 /* Introduce messages they have */ 08611 int res; 08612 res = ast_play_and_wait(chan, "vm-youhave"); 08613 if (!res) { 08614 if (vms->newmessages) { 08615 res = say_and_wait(chan, vms->newmessages, chan->language); 08616 if (!res) { 08617 if (vms->newmessages == 1) 08618 res = ast_play_and_wait(chan, "vm-INBOXs"); 08619 else 08620 res = ast_play_and_wait(chan, "vm-INBOX"); 08621 } 08622 if (vms->oldmessages && !res) 08623 res = ast_play_and_wait(chan, "vm-and"); 08624 else if (!res) { 08625 if ((vms->newmessages == 1)) 08626 res = ast_play_and_wait(chan, "vm-message"); 08627 else 08628 res = ast_play_and_wait(chan, "vm-messages"); 08629 } 08630 08631 } 08632 if (!res && vms->oldmessages) { 08633 res = say_and_wait(chan, vms->oldmessages, chan->language); 08634 if (!res) { 08635 if (vms->oldmessages == 1) 08636 res = ast_play_and_wait(chan, "vm-Olds"); 08637 else 08638 res = ast_play_and_wait(chan, "vm-Old"); 08639 } 08640 if (!res) { 08641 if (vms->oldmessages == 1) 08642 res = ast_play_and_wait(chan, "vm-message"); 08643 else 08644 res = ast_play_and_wait(chan, "vm-messages"); 08645 } 08646 } 08647 if (!res) { 08648 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08649 res = ast_play_and_wait(chan, "vm-no"); 08650 if (!res) 08651 res = ast_play_and_wait(chan, "vm-messages"); 08652 } 08653 } 08654 } 08655 return res; 08656 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8374 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().
08375 { 08376 /* Introduce messages they have */ 08377 int res; 08378 08379 res = ast_play_and_wait(chan, "vm-youhave"); 08380 if (res) 08381 return res; 08382 08383 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08384 res = ast_play_and_wait(chan, "vm-no"); 08385 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08386 return res; 08387 } 08388 08389 if (vms->newmessages) { 08390 if ((vms->newmessages == 1)) { 08391 res = ast_play_and_wait(chan, "digits/1"); 08392 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08393 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08394 } else { 08395 res = say_and_wait(chan, vms->newmessages, chan->language); 08396 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08397 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08398 } 08399 if (!res && vms->oldmessages) 08400 res = ast_play_and_wait(chan, "vm-and"); 08401 } 08402 if (!res && vms->oldmessages) { 08403 if (vms->oldmessages == 1) { 08404 res = ast_play_and_wait(chan, "digits/1"); 08405 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08406 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08407 } else { 08408 res = say_and_wait(chan, vms->oldmessages, chan->language); 08409 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08410 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08411 } 08412 } 08413 08414 return res; 08415 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8259 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().
08260 { 08261 /* Introduce messages they have */ 08262 int res; 08263 div_t num; 08264 08265 if (!vms->oldmessages && !vms->newmessages) { 08266 res = ast_play_and_wait(chan, "vm-no"); 08267 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08268 return res; 08269 } else { 08270 res = ast_play_and_wait(chan, "vm-youhave"); 08271 } 08272 08273 if (vms->newmessages) { 08274 num = div(vms->newmessages, 10); 08275 if (vms->newmessages == 1) { 08276 res = ast_play_and_wait(chan, "digits/1-a"); 08277 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08278 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08279 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08280 if (num.rem == 2) { 08281 if (!num.quot) { 08282 res = ast_play_and_wait(chan, "digits/2-ie"); 08283 } else { 08284 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08285 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08286 } 08287 } else { 08288 res = say_and_wait(chan, vms->newmessages, chan->language); 08289 } 08290 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08291 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08292 } else { 08293 res = say_and_wait(chan, vms->newmessages, chan->language); 08294 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08295 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08296 } 08297 if (!res && vms->oldmessages) 08298 res = ast_play_and_wait(chan, "vm-and"); 08299 } 08300 if (!res && vms->oldmessages) { 08301 num = div(vms->oldmessages, 10); 08302 if (vms->oldmessages == 1) { 08303 res = ast_play_and_wait(chan, "digits/1-a"); 08304 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08305 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08306 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08307 if (num.rem == 2) { 08308 if (!num.quot) { 08309 res = ast_play_and_wait(chan, "digits/2-ie"); 08310 } else { 08311 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08312 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08313 } 08314 } else { 08315 res = say_and_wait(chan, vms->oldmessages, chan->language); 08316 } 08317 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08318 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08319 } else { 08320 res = say_and_wait(chan, vms->oldmessages, chan->language); 08321 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08322 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08323 } 08324 } 08325 08326 return res; 08327 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8659 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().
08660 { 08661 /* Introduce messages they have */ 08662 int res; 08663 res = ast_play_and_wait(chan, "vm-youhave"); 08664 if (!res) { 08665 if (vms->newmessages) { 08666 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08667 if (!res) { 08668 if ((vms->newmessages == 1)) { 08669 res = ast_play_and_wait(chan, "vm-message"); 08670 if (!res) 08671 res = ast_play_and_wait(chan, "vm-INBOXs"); 08672 } else { 08673 res = ast_play_and_wait(chan, "vm-messages"); 08674 if (!res) 08675 res = ast_play_and_wait(chan, "vm-INBOX"); 08676 } 08677 } 08678 if (vms->oldmessages && !res) 08679 res = ast_play_and_wait(chan, "vm-and"); 08680 } 08681 if (!res && vms->oldmessages) { 08682 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08683 if (!res) { 08684 if (vms->oldmessages == 1) { 08685 res = ast_play_and_wait(chan, "vm-message"); 08686 if (!res) 08687 res = ast_play_and_wait(chan, "vm-Olds"); 08688 } else { 08689 res = ast_play_and_wait(chan, "vm-messages"); 08690 if (!res) 08691 res = ast_play_and_wait(chan, "vm-Old"); 08692 } 08693 } 08694 } 08695 if (!res) { 08696 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08697 res = ast_play_and_wait(chan, "vm-no"); 08698 if (!res) 08699 res = ast_play_and_wait(chan, "vm-messages"); 08700 } 08701 } 08702 } 08703 return res; 08704 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8520 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().
08520 { 08521 /* Introduce messages they have */ 08522 int res; 08523 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08524 res = ast_play_and_wait(chan, "vm-nomessages"); 08525 return res; 08526 } else { 08527 res = ast_play_and_wait(chan, "vm-youhave"); 08528 } 08529 if (vms->newmessages) { 08530 if (!res) 08531 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08532 if ((vms->newmessages == 1)) { 08533 if (!res) 08534 res = ast_play_and_wait(chan, "vm-message"); 08535 if (!res) 08536 res = ast_play_and_wait(chan, "vm-INBOXs"); 08537 } else { 08538 if (!res) 08539 res = ast_play_and_wait(chan, "vm-messages"); 08540 if (!res) 08541 res = ast_play_and_wait(chan, "vm-INBOX"); 08542 } 08543 if (vms->oldmessages && !res) 08544 res = ast_play_and_wait(chan, "vm-and"); 08545 } 08546 if (vms->oldmessages) { 08547 if (!res) 08548 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08549 if (vms->oldmessages == 1) { 08550 if (!res) 08551 res = ast_play_and_wait(chan, "vm-message"); 08552 if (!res) 08553 res = ast_play_and_wait(chan, "vm-Olds"); 08554 } else { 08555 if (!res) 08556 res = ast_play_and_wait(chan, "vm-messages"); 08557 if (!res) 08558 res = ast_play_and_wait(chan, "vm-Old"); 08559 } 08560 } 08561 return res; 08562 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8330 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().
08331 { 08332 /* Introduce messages they have */ 08333 int res; 08334 08335 res = ast_play_and_wait(chan, "vm-youhave"); 08336 if (res) 08337 return res; 08338 08339 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08340 res = ast_play_and_wait(chan, "vm-no"); 08341 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08342 return res; 08343 } 08344 08345 if (vms->newmessages) { 08346 if ((vms->newmessages == 1)) { 08347 res = ast_play_and_wait(chan, "digits/ett"); 08348 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08349 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08350 } else { 08351 res = say_and_wait(chan, vms->newmessages, chan->language); 08352 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08353 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08354 } 08355 if (!res && vms->oldmessages) 08356 res = ast_play_and_wait(chan, "vm-and"); 08357 } 08358 if (!res && vms->oldmessages) { 08359 if (vms->oldmessages == 1) { 08360 res = ast_play_and_wait(chan, "digits/ett"); 08361 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08362 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08363 } else { 08364 res = say_and_wait(chan, vms->oldmessages, chan->language); 08365 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08366 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08367 } 08368 } 08369 08370 return res; 08371 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8822 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().
08823 { 08824 int res; 08825 08826 /* Introduce messages they have */ 08827 res = ast_play_and_wait(chan, "vm-youhave"); 08828 if (!res) { 08829 if (vms->newmessages) { 08830 res = say_and_wait(chan, vms->newmessages, chan->language); 08831 if (!res) 08832 res = ast_play_and_wait(chan, "vm-INBOX"); 08833 if (vms->oldmessages && !res) 08834 res = ast_play_and_wait(chan, "vm-and"); 08835 } 08836 if (!res && vms->oldmessages) { 08837 res = say_and_wait(chan, vms->oldmessages, chan->language); 08838 if (!res) 08839 res = ast_play_and_wait(chan, "vm-Old"); 08840 } 08841 if (!res) { 08842 if (!vms->oldmessages && !vms->newmessages) { 08843 res = ast_play_and_wait(chan, "vm-no"); 08844 if (!res) 08845 res = ast_play_and_wait(chan, "vm-message"); 08846 } 08847 } 08848 } 08849 return res; 08850 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8783 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().
08784 { 08785 int res; 08786 /* Introduce messages they have */ 08787 res = ast_play_and_wait(chan, "vm-you"); 08788 08789 if (!res && vms->newmessages) { 08790 res = ast_play_and_wait(chan, "vm-have"); 08791 if (!res) 08792 res = say_and_wait(chan, vms->newmessages, chan->language); 08793 if (!res) 08794 res = ast_play_and_wait(chan, "vm-tong"); 08795 if (!res) 08796 res = ast_play_and_wait(chan, "vm-INBOX"); 08797 if (vms->oldmessages && !res) 08798 res = ast_play_and_wait(chan, "vm-and"); 08799 else if (!res) 08800 res = ast_play_and_wait(chan, "vm-messages"); 08801 } 08802 if (!res && vms->oldmessages) { 08803 res = ast_play_and_wait(chan, "vm-have"); 08804 if (!res) 08805 res = say_and_wait(chan, vms->oldmessages, chan->language); 08806 if (!res) 08807 res = ast_play_and_wait(chan, "vm-tong"); 08808 if (!res) 08809 res = ast_play_and_wait(chan, "vm-Old"); 08810 if (!res) 08811 res = ast_play_and_wait(chan, "vm-messages"); 08812 } 08813 if (!res && !vms->oldmessages && !vms->newmessages) { 08814 res = ast_play_and_wait(chan, "vm-haveno"); 08815 if (!res) 08816 res = ast_play_and_wait(chan, "vm-messages"); 08817 } 08818 return res; 08819 }
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 9025 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().
09026 { 09027 int cmd = 0; 09028 int duration = 0; 09029 int tries = 0; 09030 char newpassword[80] = ""; 09031 char newpassword2[80] = ""; 09032 char prefile[PATH_MAX] = ""; 09033 unsigned char buf[256]; 09034 int bytes = 0; 09035 09036 if (ast_adsi_available(chan)) { 09037 bytes += adsi_logo(buf + bytes); 09038 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09039 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09040 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09041 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09042 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09043 } 09044 09045 /* First, have the user change their password 09046 so they won't get here again */ 09047 for (;;) { 09048 newpassword[1] = '\0'; 09049 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09050 if (cmd == '#') 09051 newpassword[0] = '\0'; 09052 if (cmd < 0 || cmd == 't' || cmd == '#') 09053 return cmd; 09054 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09055 if (cmd < 0 || cmd == 't' || cmd == '#') 09056 return cmd; 09057 cmd = check_password(vmu, newpassword); /* perform password validation */ 09058 if (cmd != 0) { 09059 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09060 cmd = ast_play_and_wait(chan, vm_invalid_password); 09061 } else { 09062 newpassword2[1] = '\0'; 09063 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09064 if (cmd == '#') 09065 newpassword2[0] = '\0'; 09066 if (cmd < 0 || cmd == 't' || cmd == '#') 09067 return cmd; 09068 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09069 if (cmd < 0 || cmd == 't' || cmd == '#') 09070 return cmd; 09071 if (!strcmp(newpassword, newpassword2)) 09072 break; 09073 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09074 cmd = ast_play_and_wait(chan, vm_mismatch); 09075 } 09076 if (++tries == 3) 09077 return -1; 09078 if (cmd != 0) { 09079 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09080 } 09081 } 09082 if (pwdchange & PWDCHANGE_INTERNAL) 09083 vm_change_password(vmu, newpassword); 09084 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09085 vm_change_password_shell(vmu, newpassword); 09086 09087 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09088 cmd = ast_play_and_wait(chan, vm_passchanged); 09089 09090 /* If forcename is set, have the user record their name */ 09091 if (ast_test_flag(vmu, VM_FORCENAME)) { 09092 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09093 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09094 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09095 if (cmd < 0 || cmd == 't' || cmd == '#') 09096 return cmd; 09097 } 09098 } 09099 09100 /* If forcegreetings is set, have the user record their greetings */ 09101 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09102 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09103 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09104 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09105 if (cmd < 0 || cmd == 't' || cmd == '#') 09106 return cmd; 09107 } 09108 09109 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09110 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09111 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09112 if (cmd < 0 || cmd == 't' || cmd == '#') 09113 return cmd; 09114 } 09115 } 09116 09117 return cmd; 09118 }
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 9120 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().
09121 { 09122 int cmd = 0; 09123 int retries = 0; 09124 int duration = 0; 09125 char newpassword[80] = ""; 09126 char newpassword2[80] = ""; 09127 char prefile[PATH_MAX] = ""; 09128 unsigned char buf[256]; 09129 int bytes = 0; 09130 09131 if (ast_adsi_available(chan)) { 09132 bytes += adsi_logo(buf + bytes); 09133 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09134 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09135 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09136 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09137 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09138 } 09139 while ((cmd >= 0) && (cmd != 't')) { 09140 if (cmd) 09141 retries = 0; 09142 switch (cmd) { 09143 case '1': /* Record your unavailable message */ 09144 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09145 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09146 break; 09147 case '2': /* Record your busy message */ 09148 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09149 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09150 break; 09151 case '3': /* Record greeting */ 09152 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09153 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09154 break; 09155 case '4': /* manage the temporary greeting */ 09156 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09157 break; 09158 case '5': /* change password */ 09159 if (vmu->password[0] == '-') { 09160 cmd = ast_play_and_wait(chan, "vm-no"); 09161 break; 09162 } 09163 newpassword[1] = '\0'; 09164 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09165 if (cmd == '#') 09166 newpassword[0] = '\0'; 09167 else { 09168 if (cmd < 0) 09169 break; 09170 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09171 break; 09172 } 09173 } 09174 cmd = check_password(vmu, newpassword); /* perform password validation */ 09175 if (cmd != 0) { 09176 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09177 cmd = ast_play_and_wait(chan, vm_invalid_password); 09178 if (!cmd) { 09179 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09180 } 09181 break; 09182 } 09183 newpassword2[1] = '\0'; 09184 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09185 if (cmd == '#') 09186 newpassword2[0] = '\0'; 09187 else { 09188 if (cmd < 0) 09189 break; 09190 09191 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09192 break; 09193 } 09194 } 09195 if (strcmp(newpassword, newpassword2)) { 09196 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09197 cmd = ast_play_and_wait(chan, vm_mismatch); 09198 if (!cmd) { 09199 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09200 } 09201 break; 09202 } 09203 if (pwdchange & PWDCHANGE_INTERNAL) 09204 vm_change_password(vmu, newpassword); 09205 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09206 vm_change_password_shell(vmu, newpassword); 09207 09208 ast_debug(1, "User %s set password to %s of length %d\n", 09209 vms->username, newpassword, (int) strlen(newpassword)); 09210 cmd = ast_play_and_wait(chan, vm_passchanged); 09211 break; 09212 case '*': 09213 cmd = 't'; 09214 break; 09215 default: 09216 cmd = 0; 09217 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09218 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09219 if (ast_fileexists(prefile, NULL, NULL)) { 09220 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09221 } 09222 DISPOSE(prefile, -1); 09223 if (!cmd) { 09224 cmd = ast_play_and_wait(chan, "vm-options"); 09225 } 09226 if (!cmd) { 09227 cmd = ast_waitfordigit(chan, 6000); 09228 } 09229 if (!cmd) { 09230 retries++; 09231 } 09232 if (retries > 3) { 09233 cmd = 't'; 09234 } 09235 } 09236 } 09237 if (cmd == 't') 09238 cmd = 0; 09239 return cmd; 09240 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 7929 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().
07930 { 07931 int cmd; 07932 07933 if ( !strncasecmp(chan->language, "it", 2) || 07934 !strncasecmp(chan->language, "es", 2) || 07935 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 07936 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07937 return cmd ? cmd : ast_play_and_wait(chan, box); 07938 } else if (!strncasecmp(chan->language, "gr", 2)) { 07939 return vm_play_folder_name_gr(chan, box); 07940 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 07941 return ast_play_and_wait(chan, box); 07942 } else if (!strncasecmp(chan->language, "pl", 2)) { 07943 return vm_play_folder_name_pl(chan, box); 07944 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 07945 return vm_play_folder_name_ua(chan, box); 07946 } else if (!strncasecmp(chan->language, "vi", 2)) { 07947 return ast_play_and_wait(chan, box); 07948 } else { /* Default English */ 07949 cmd = ast_play_and_wait(chan, box); 07950 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07951 } 07952 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7882 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
07883 { 07884 int cmd; 07885 char *buf; 07886 07887 buf = alloca(strlen(box) + 2); 07888 strcpy(buf, box); 07889 strcat(buf, "s"); 07890 07891 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 07892 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 07893 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07894 } else { 07895 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07896 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 07897 } 07898 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7900 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
07901 { 07902 int cmd; 07903 07904 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 07905 if (!strcasecmp(box, "vm-INBOX")) 07906 cmd = ast_play_and_wait(chan, "vm-new-e"); 07907 else 07908 cmd = ast_play_and_wait(chan, "vm-old-e"); 07909 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07910 } else { 07911 cmd = ast_play_and_wait(chan, "vm-messages"); 07912 return cmd ? cmd : ast_play_and_wait(chan, box); 07913 } 07914 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7916 of file app_voicemail.c.
References ast_play_and_wait().
Referenced by vm_play_folder_name().
07917 { 07918 int cmd; 07919 07920 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 07921 cmd = ast_play_and_wait(chan, "vm-messages"); 07922 return cmd ? cmd : ast_play_and_wait(chan, box); 07923 } else { 07924 cmd = ast_play_and_wait(chan, box); 07925 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07926 } 07927 }
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 9258 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().
09259 { 09260 int cmd = 0; 09261 int retries = 0; 09262 int duration = 0; 09263 char prefile[PATH_MAX] = ""; 09264 unsigned char buf[256]; 09265 int bytes = 0; 09266 09267 if (ast_adsi_available(chan)) { 09268 bytes += adsi_logo(buf + bytes); 09269 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09270 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09271 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09272 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09273 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09274 } 09275 09276 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09277 while ((cmd >= 0) && (cmd != 't')) { 09278 if (cmd) 09279 retries = 0; 09280 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09281 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09282 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09283 cmd = 't'; 09284 } else { 09285 switch (cmd) { 09286 case '1': 09287 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09288 break; 09289 case '2': 09290 DELETE(prefile, -1, prefile, vmu); 09291 ast_play_and_wait(chan, "vm-tempremoved"); 09292 cmd = 't'; 09293 break; 09294 case '*': 09295 cmd = 't'; 09296 break; 09297 default: 09298 cmd = ast_play_and_wait(chan, 09299 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09300 "vm-tempgreeting2" : "vm-tempgreeting"); 09301 if (!cmd) 09302 cmd = ast_waitfordigit(chan, 6000); 09303 if (!cmd) 09304 retries++; 09305 if (retries > 3) 09306 cmd = 't'; 09307 } 09308 } 09309 DISPOSE(prefile, -1); 09310 } 09311 if (cmd == 't') 09312 cmd = 0; 09313 return cmd; 09314 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11146 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().
11148 { 11149 struct ast_vm_user *user; 11150 11151 AST_LIST_LOCK(&users); 11152 AST_LIST_TRAVERSE(&users, user, list) { 11153 vm_users_data_provider_get_helper(search, data_root, user); 11154 } 11155 AST_LIST_UNLOCK(&users); 11156 11157 return 0; 11158 }
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 11099 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().
11101 { 11102 struct ast_data *data_user, *data_zone; 11103 struct ast_data *data_state; 11104 struct vm_zone *zone = NULL; 11105 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11106 char ext_context[256] = ""; 11107 11108 data_user = ast_data_add_node(data_root, "user"); 11109 if (!data_user) { 11110 return -1; 11111 } 11112 11113 ast_data_add_structure(ast_vm_user, data_user, user); 11114 11115 AST_LIST_LOCK(&zones); 11116 AST_LIST_TRAVERSE(&zones, zone, list) { 11117 if (!strcmp(zone->name, user->zonetag)) { 11118 break; 11119 } 11120 } 11121 AST_LIST_UNLOCK(&zones); 11122 11123 /* state */ 11124 data_state = ast_data_add_node(data_user, "state"); 11125 if (!data_state) { 11126 return -1; 11127 } 11128 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11129 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11130 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11131 ast_data_add_int(data_state, "newmsg", newmsg); 11132 ast_data_add_int(data_state, "oldmsg", oldmsg); 11133 11134 if (zone) { 11135 data_zone = ast_data_add_node(data_user, "zone"); 11136 ast_data_add_structure(vm_zone, data_zone, zone); 11137 } 11138 11139 if (!ast_data_search_match(search, data_user)) { 11140 ast_data_remove_node(data_root, data_user); 11141 } 11142 11143 return 0; 11144 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10785 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().
10786 { 10787 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 10788 struct ast_vm_user vmus; 10789 char *options = NULL; 10790 int silent = 0, skipuser = 0; 10791 int res = -1; 10792 10793 if (data) { 10794 s = ast_strdupa(data); 10795 user = strsep(&s, ","); 10796 options = strsep(&s, ","); 10797 if (user) { 10798 s = user; 10799 user = strsep(&s, "@"); 10800 context = strsep(&s, ""); 10801 if (!ast_strlen_zero(user)) 10802 skipuser++; 10803 ast_copy_string(mailbox, user, sizeof(mailbox)); 10804 } 10805 } 10806 10807 if (options) { 10808 silent = (strchr(options, 's')) != NULL; 10809 } 10810 10811 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 10812 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 10813 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 10814 ast_play_and_wait(chan, "auth-thankyou"); 10815 res = 0; 10816 } else if (mailbox[0] == '*') { 10817 /* user entered '*' */ 10818 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10819 res = 0; /* prevent hangup */ 10820 } 10821 } 10822 10823 return res; 10824 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12272 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().
12273 { 12274 char *context; 12275 char *args_copy; 12276 int res; 12277 12278 if (ast_strlen_zero(data)) { 12279 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12280 return -1; 12281 } 12282 12283 args_copy = ast_strdupa(data); 12284 if ((context = strchr(args_copy, '@'))) { 12285 *context++ = '\0'; 12286 } else { 12287 context = "default"; 12288 } 12289 12290 if ((res = sayname(chan, args_copy, context) < 0)) { 12291 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12292 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12293 if (!res) { 12294 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12295 } 12296 } 12297 12298 return res; 12299 }
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 4305 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().
04306 { 04307 const struct vm_zone *z = NULL; 04308 struct timeval t = ast_tvnow(); 04309 04310 /* Does this user have a timezone specified? */ 04311 if (!ast_strlen_zero(vmu->zonetag)) { 04312 /* Find the zone in the list */ 04313 AST_LIST_LOCK(&zones); 04314 AST_LIST_TRAVERSE(&zones, z, list) { 04315 if (!strcmp(z->name, vmu->zonetag)) 04316 break; 04317 } 04318 AST_LIST_UNLOCK(&zones); 04319 } 04320 ast_localtime(&t, tm, z ? z->timezone : NULL); 04321 return tm; 04322 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7305 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().
07306 { 07307 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); 07308 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7297 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().
07298 { 07299 int res; 07300 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07301 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07302 return res; 07303 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12246 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().
12246 { 12247 struct ast_config *conf; 12248 struct ast_category *cat; 12249 struct ast_variable *var; 12250 12251 if (!(conf=ast_config_new())) { 12252 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12253 return -1; 12254 } 12255 if (!(cat=ast_category_new("general","",1))) { 12256 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12257 return -1; 12258 } 12259 if (!(var=ast_variable_new("password",password,""))) { 12260 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12261 return -1; 12262 } 12263 ast_category_append(conf,cat); 12264 ast_variable_append(cat,var); 12265 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12266 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12267 return -1; 12268 } 12269 return 0; 12270 }
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 13260 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 13260 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 11022 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 10780 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [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 11160 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] |