#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"
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 | 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 | { NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER } |
enum | { 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 | { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
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. | |
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 char * | encode_mime_str (const char *start, char *end, size_t endsize, 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 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 | 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 (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, char *passdata, size_t passdatasize, const char *category, const char *flag) |
static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
static char * | quote (const char *from, char *to, size_t len) |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
static int | reload (void) |
static void | rename_file (char *sfn, char *dfn) |
Renames a message in a mailbox folder. | |
static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
Resets a user password to a specified password. | |
static void | run_externnotify (char *context, char *extension, const char *flag) |
static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box) |
static int | say_and_wait (struct ast_channel *chan, int num, const char *language) |
static int | sayname (struct ast_channel *chan, const char *mailbox, const char *context) |
static int | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag) |
static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
static char * | show_users_realtime (int fd, const char *context) |
static void | start_poll_thread (void) |
static void | stop_poll_thread (void) |
static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
Strips control and non 7-bit clean characters from input string. | |
static char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
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, void *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_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, void *data) |
static int | vm_execmain (struct ast_channel *chan, void *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_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 | vmauthenticate (struct ast_channel *chan, void *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. Return tm so it can be used as a function argument. | |
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) |
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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
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 * | descrip_vm |
static char * | descrip_vm_box_exists |
static char * | descrip_vmain |
static char * | descrip_vmauthenticate |
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 struct ast_custom_function | mailbox_exists_acf |
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 | pagerfromstring [100] |
static char * | pagersubject = NULL |
static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
static unsigned int | poll_freq |
static ast_mutex_t | poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static unsigned int | poll_mailboxes |
static pthread_t | poll_thread = AST_PTHREADT_NULL |
static unsigned char | poll_thread_run |
static int | pwdchange = PWDCHANGE_INTERNAL |
static int | saydurationminfo |
static char | serveremail [80] |
static int | silencethreshold = 128 |
static int | skipms |
static struct ast_smdi_interface * | smdi_iface = NULL |
static char * | synopsis_vm = "Leave a Voicemail message" |
static char * | synopsis_vm_box_exists |
static char * | synopsis_vmain = "Check Voicemail messages" |
static char * | synopsis_vmauthenticate = "Authenticate with Voicemail passwords" |
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 }} |
enum { ... } | vm_box |
static char | vm_invalid_password [80] = "vm-invalid-password" |
static char | vm_mismatch [80] = "vm-mismatch" |
static char | vm_newpassword [80] = "vm-newpassword" |
enum { ... } | vm_option_args |
enum { ... } | vm_option_flags |
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 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 192 of file app_voicemail.c.
#define BASELINELEN 72 |
#define BASEMAXINLINE 256 |
#define CHUNKSIZE 65536 |
Definition at line 189 of file app_voicemail.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 185 of file app_voicemail.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
#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 633 of file app_voicemail.c.
Referenced by load_config().
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 486 of file app_voicemail.c.
Referenced by notify_new_message(), play_record_review(), and vm_tempgreeting().
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 481 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 220 of file app_voicemail.c.
Referenced by add_email_attachment(), base_encode(), make_email_file(), and ochar().
#define ERROR_LOCK_PATH -100 |
Definition at line 245 of file app_voicemail.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 483 of file app_voicemail.c.
Referenced by close_mailbox(), copy_message(), and save_to_folder().
#define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
Referenced by handle_voicemail_show_users().
#define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_voicemail_show_zones().
#define INTRO "vm-intro" |
Definition at line 208 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
#define MAX_DATETIME_FORMAT 512 |
Definition at line 223 of file app_voicemail.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 224 of file app_voicemail.c.
#define MAXMSG 100 |
#define MAXMSGLIMIT 9999 |
Definition at line 211 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 213 of file app_voicemail.c.
Referenced by load_config().
#define OPERATOR_EXIT 300 |
Definition at line 246 of file app_voicemail.c.
Referenced by leave_voicemail(), vm_exec(), and vm_execmain().
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 498 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 497 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 484 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), and save_to_folder().
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 480 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 206 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 482 of file app_voicemail.c.
Referenced by copy_message(), forward_message(), leave_voicemail(), and play_record_review().
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 507 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 239 of file app_voicemail.c.
Referenced by find_user(), find_user_realtime(), free_user(), and free_vm_users().
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 237 of file app_voicemail.c.
Referenced by apply_option(), 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 238 of file app_voicemail.c.
Referenced by apply_option(), 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 236 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 230 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_message().
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 234 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 233 of file app_voicemail.c.
Referenced by apply_option(), 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 244 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 243 of file app_voicemail.c.
Referenced by apply_option(), 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 242 of file app_voicemail.c.
Referenced by apply_option(), close_mailbox(), and load_config().
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 227 of file app_voicemail.c.
Referenced by apply_option(), 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 235 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 226 of file app_voicemail.c.
Referenced by apply_option(), 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 228 of file app_voicemail.c.
Referenced by apply_option(), 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 231 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and play_message().
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 240 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 232 of file app_voicemail.c.
Referenced by load_config(), and vm_execmain().
#define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 229 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_execmain().
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 241 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_intro().
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 424 of file app_voicemail.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 191 of file app_voicemail.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 187 of file app_voicemail.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 188 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
anonymous enum |
Definition at line 249 of file app_voicemail.c.
00249 { 00250 NEW_FOLDER, 00251 OLD_FOLDER, 00252 WORK_FOLDER, 00253 FAMILY_FOLDER, 00254 FRIENDS_FOLDER, 00255 GREETINGS_FOLDER 00256 } vm_box;
anonymous enum |
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 258 of file app_voicemail.c.
00258 { 00259 OPT_SILENT = (1 << 0), 00260 OPT_BUSY_GREETING = (1 << 1), 00261 OPT_UNAVAIL_GREETING = (1 << 2), 00262 OPT_RECORDGAIN = (1 << 3), 00263 OPT_PREPEND_MAILBOX = (1 << 4), 00264 OPT_AUTOPLAY = (1 << 6), 00265 OPT_DTMFEXIT = (1 << 7), 00266 OPT_MESSAGE_Urgent = (1 << 8), 00267 OPT_MESSAGE_PRIORITY = (1 << 9) 00268 } vm_option_flags;
anonymous enum |
Definition at line 270 of file app_voicemail.c.
00270 { 00271 OPT_ARG_RECORDGAIN = 0, 00272 OPT_ARG_PLAYFOLDER = 1, 00273 OPT_ARG_DTMFEXIT = 2, 00274 /* This *must* be the last value in this enum! */ 00275 OPT_ARG_ARRAY_SIZE = 3, 00276 } vm_option_args;
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 4860 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
04861 { 04862 DIR *dir; 04863 struct dirent *de; 04864 char fn[256]; 04865 int ret = 0; 04866 04867 /* If no mailbox, return immediately */ 04868 if (ast_strlen_zero(mailbox)) 04869 return 0; 04870 04871 if (ast_strlen_zero(folder)) 04872 folder = "INBOX"; 04873 if (ast_strlen_zero(context)) 04874 context = "default"; 04875 04876 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 04877 04878 if (!(dir = opendir(fn))) 04879 return 0; 04880 04881 while ((de = readdir(dir))) { 04882 if (!strncasecmp(de->d_name, "msg", 3)) { 04883 if (shortcircuit) { 04884 ret = 1; 04885 break; 04886 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 04887 ret++; 04888 } 04889 } 04890 } 04891 04892 closedir(dir); 04893 04894 return ret; 04895 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 11759 of file app_voicemail.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 11759 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 9909 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().
09910 { 09911 struct ast_vm_user svm; 09912 AST_DECLARE_APP_ARGS(arg, 09913 AST_APP_ARG(mbox); 09914 AST_APP_ARG(context); 09915 ); 09916 09917 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 09918 09919 if (ast_strlen_zero(arg.mbox)) { 09920 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 09921 return -1; 09922 } 09923 09924 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 09925 return 0; 09926 }
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 4350 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().
04351 { 04352 char tmpdir[256], newtmp[256]; 04353 char fname[256]; 04354 char tmpcmd[256]; 04355 int tmpfd = -1; 04356 04357 /* Eww. We want formats to tell us their own MIME type */ 04358 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04359 04360 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04361 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04362 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04363 tmpfd = mkstemp(newtmp); 04364 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04365 ast_debug(3, "newtmp: %s\n", newtmp); 04366 if (tmpfd > -1) { 04367 int soxstatus; 04368 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04369 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04370 attach = newtmp; 04371 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04372 } else { 04373 ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04374 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04375 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04376 } 04377 } 04378 } 04379 fprintf(p, "--%s" ENDL, bound); 04380 if (msgnum > -1) 04381 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04382 else 04383 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04384 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04385 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04386 if (msgnum > -1) 04387 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04388 else 04389 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04390 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04391 base_encode(fname, p); 04392 if (last) 04393 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04394 if (tmpfd > -1) { 04395 unlink(fname); 04396 close(tmpfd); 04397 unlink(newtmp); 04398 } 04399 return 0; 04400 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 5793 of file app_voicemail.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available, ast_adsi_load_session, ast_log(), and chan.
Referenced by vm_authenticate(), and vm_execmain().
05794 { 05795 int x; 05796 if (!ast_adsi_available(chan)) 05797 return; 05798 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 05799 if (x < 0) 05800 return; 05801 if (!x) { 05802 if (adsi_load_vmail(chan, useadsi)) { 05803 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 05804 return; 05805 } 05806 } else 05807 *useadsi = 1; 05808 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 5982 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available, chan, and vm_state::curmsg.
Referenced by vm_execmain().
05983 { 05984 int bytes=0; 05985 unsigned char buf[256]; 05986 unsigned char keys[8]; 05987 05988 int x; 05989 05990 if (!ast_adsi_available(chan)) 05991 return; 05992 05993 /* New meaning for keys */ 05994 for (x=0;x<5;x++) 05995 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05996 05997 keys[6] = 0x0; 05998 keys[7] = 0x0; 05999 06000 if (!vms->curmsg) { 06001 /* No prev key, provide "Folder" instead */ 06002 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06003 } 06004 if (vms->curmsg >= vms->lastmsg) { 06005 /* If last message ... */ 06006 if (vms->curmsg) { 06007 /* but not only message, provide "Folder" instead */ 06008 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06009 } else { 06010 /* Otherwise if only message, leave blank */ 06011 keys[3] = 1; 06012 } 06013 } 06014 06015 /* If deleted, show "undeleted" */ 06016 if (vms->deleted[vms->curmsg]) 06017 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06018 06019 /* Except "Exit" */ 06020 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06021 bytes += ast_adsi_set_keys(buf + bytes, keys); 06022 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06023 06024 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06025 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 5858 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, ast_adsi_voice_mode, and chan.
Referenced by vm_execmain().
05859 { 05860 unsigned char buf[256]; 05861 int bytes=0; 05862 unsigned char keys[8]; 05863 int x,y; 05864 05865 if (!ast_adsi_available(chan)) 05866 return; 05867 05868 for (x=0;x<5;x++) { 05869 y = ADSI_KEY_APPS + 12 + start + x; 05870 if (y > ADSI_KEY_APPS + 12 + 4) 05871 y = 0; 05872 keys[x] = ADSI_KEY_SKT | y; 05873 } 05874 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 05875 keys[6] = 0; 05876 keys[7] = 0; 05877 05878 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 05879 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 05880 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05881 bytes += ast_adsi_set_keys(buf + bytes, keys); 05882 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05883 05884 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05885 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6130 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, ast_adsi_voice_mode, and chan.
Referenced by vm_execmain().
06131 { 06132 unsigned char buf[256]; 06133 int bytes=0; 06134 06135 if (!ast_adsi_available(chan)) 06136 return; 06137 bytes += adsi_logo(buf + bytes); 06138 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06139 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06140 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06141 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06142 06143 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06144 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 5664 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, chan, mbox(), and num.
Referenced by adsi_begin().
05665 { 05666 unsigned char buf[256]; 05667 int bytes=0; 05668 int x; 05669 char num[5]; 05670 05671 *useadsi = 0; 05672 bytes += ast_adsi_data_mode(buf + bytes); 05673 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05674 05675 bytes = 0; 05676 bytes += adsi_logo(buf); 05677 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05678 #ifdef DISPLAY 05679 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 05680 #endif 05681 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05682 bytes += ast_adsi_data_mode(buf + bytes); 05683 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05684 05685 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 05686 bytes = 0; 05687 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 05688 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05689 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05690 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05691 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05692 return 0; 05693 } 05694 05695 #ifdef DISPLAY 05696 /* Add a dot */ 05697 bytes = 0; 05698 bytes += ast_adsi_logo(buf); 05699 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05700 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 05701 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05702 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05703 #endif 05704 bytes = 0; 05705 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 05706 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 05707 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 05708 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 05709 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 05710 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 05711 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05712 05713 #ifdef DISPLAY 05714 /* Add another dot */ 05715 bytes = 0; 05716 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 05717 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05718 05719 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05720 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05721 #endif 05722 05723 bytes = 0; 05724 /* These buttons we load but don't use yet */ 05725 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 05726 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 05727 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 05728 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 05729 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 05730 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 05731 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05732 05733 #ifdef DISPLAY 05734 /* Add another dot */ 05735 bytes = 0; 05736 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 05737 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05738 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05739 #endif 05740 05741 bytes = 0; 05742 for (x=0;x<5;x++) { 05743 snprintf(num, sizeof(num), "%d", x); 05744 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1); 05745 } 05746 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 05747 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05748 05749 #ifdef DISPLAY 05750 /* Add another dot */ 05751 bytes = 0; 05752 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 05753 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05754 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05755 #endif 05756 05757 if (ast_adsi_end_download(chan)) { 05758 bytes = 0; 05759 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 05760 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05761 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05762 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05763 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05764 return 0; 05765 } 05766 bytes = 0; 05767 bytes += ast_adsi_download_disconnect(buf + bytes); 05768 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05769 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05770 05771 ast_debug(1, "Done downloading scripts...\n"); 05772 05773 #ifdef DISPLAY 05774 /* Add last dot */ 05775 bytes = 0; 05776 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 05777 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05778 #endif 05779 ast_debug(1, "Restarting session...\n"); 05780 05781 bytes = 0; 05782 /* Load the session now */ 05783 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 05784 *useadsi = 1; 05785 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 05786 } else 05787 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 05788 05789 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05790 return 0; 05791 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5810 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, ast_adsi_voice_mode, and chan.
Referenced by vm_authenticate().
05811 { 05812 unsigned char buf[256]; 05813 int bytes=0; 05814 unsigned char keys[8]; 05815 int x; 05816 if (!ast_adsi_available(chan)) 05817 return; 05818 05819 for (x=0;x<8;x++) 05820 keys[x] = 0; 05821 /* Set one key for next */ 05822 keys[3] = ADSI_KEY_APPS + 3; 05823 05824 bytes += adsi_logo(buf + bytes); 05825 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 05826 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 05827 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05828 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 05829 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 05830 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 05831 bytes += ast_adsi_set_keys(buf + bytes, keys); 05832 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05833 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05834 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 5656 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().
05657 { 05658 int bytes = 0; 05659 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 05660 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 05661 return bytes; 05662 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 5887 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available, ast_copy_string(), ast_strlen_zero(), chan, vm_state::curmsg, vm_state::fn, num, and strsep().
Referenced by play_message(), and vm_execmain().
05888 { 05889 int bytes=0; 05890 unsigned char buf[256]; 05891 char buf1[256], buf2[256]; 05892 char fn2[PATH_MAX]; 05893 05894 char cid[256]=""; 05895 char *val; 05896 char *name, *num; 05897 char datetime[21]=""; 05898 FILE *f; 05899 05900 unsigned char keys[8]; 05901 05902 int x; 05903 05904 if (!ast_adsi_available(chan)) 05905 return; 05906 05907 /* Retrieve important info */ 05908 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 05909 f = fopen(fn2, "r"); 05910 if (f) { 05911 while (!feof(f)) { 05912 if (!fgets((char *)buf, sizeof(buf), f)) { 05913 continue; 05914 } 05915 if (!feof(f)) { 05916 char *stringp=NULL; 05917 stringp = (char *)buf; 05918 strsep(&stringp, "="); 05919 val = strsep(&stringp, "="); 05920 if (!ast_strlen_zero(val)) { 05921 if (!strcmp((char *)buf, "callerid")) 05922 ast_copy_string(cid, val, sizeof(cid)); 05923 if (!strcmp((char *)buf, "origdate")) 05924 ast_copy_string(datetime, val, sizeof(datetime)); 05925 } 05926 } 05927 } 05928 fclose(f); 05929 } 05930 /* New meaning for keys */ 05931 for (x=0;x<5;x++) 05932 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05933 keys[6] = 0x0; 05934 keys[7] = 0x0; 05935 05936 if (!vms->curmsg) { 05937 /* No prev key, provide "Folder" instead */ 05938 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05939 } 05940 if (vms->curmsg >= vms->lastmsg) { 05941 /* If last message ... */ 05942 if (vms->curmsg) { 05943 /* but not only message, provide "Folder" instead */ 05944 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05945 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05946 05947 } else { 05948 /* Otherwise if only message, leave blank */ 05949 keys[3] = 1; 05950 } 05951 } 05952 05953 if (!ast_strlen_zero(cid)) { 05954 ast_callerid_parse(cid, &name, &num); 05955 if (!name) 05956 name = num; 05957 } else 05958 name = "Unknown Caller"; 05959 05960 /* If deleted, show "undeleted" */ 05961 05962 if (vms->deleted[vms->curmsg]) 05963 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05964 05965 /* Except "Exit" */ 05966 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05967 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 05968 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 05969 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 05970 05971 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05972 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05973 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 05974 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 05975 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05976 bytes += ast_adsi_set_keys(buf + bytes, keys); 05977 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05978 05979 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05980 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5836 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, ast_adsi_voice_mode, and chan.
Referenced by vm_authenticate().
05837 { 05838 unsigned char buf[256]; 05839 int bytes=0; 05840 unsigned char keys[8]; 05841 int x; 05842 if (!ast_adsi_available(chan)) 05843 return; 05844 05845 for (x=0;x<8;x++) 05846 keys[x] = 0; 05847 /* Set one key for next */ 05848 keys[3] = ADSI_KEY_APPS + 3; 05849 05850 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05851 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 05852 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 05853 bytes += ast_adsi_set_keys(buf + bytes, keys); 05854 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05855 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05856 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6027 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, chan, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
06028 { 06029 unsigned char buf[256] = ""; 06030 char buf1[256] = "", buf2[256] = ""; 06031 int bytes=0; 06032 unsigned char keys[8]; 06033 int x; 06034 06035 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06036 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06037 if (!ast_adsi_available(chan)) 06038 return; 06039 if (vms->newmessages) { 06040 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06041 if (vms->oldmessages) { 06042 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06043 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06044 } else { 06045 snprintf(buf2, sizeof(buf2), "%s.", newm); 06046 } 06047 } else if (vms->oldmessages) { 06048 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06049 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06050 } else { 06051 strcpy(buf1, "You have no messages."); 06052 buf2[0] = ' '; 06053 buf2[1] = '\0'; 06054 } 06055 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06056 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06057 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06058 06059 for (x=0;x<6;x++) 06060 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06061 keys[6] = 0; 06062 keys[7] = 0; 06063 06064 /* Don't let them listen if there are none */ 06065 if (vms->lastmsg < 0) 06066 keys[0] = 1; 06067 bytes += ast_adsi_set_keys(buf + bytes, keys); 06068 06069 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06070 06071 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06072 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6074 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, chan, vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
06075 { 06076 unsigned char buf[256] = ""; 06077 char buf1[256] = "", buf2[256] = ""; 06078 int bytes=0; 06079 unsigned char keys[8]; 06080 int x; 06081 06082 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06083 06084 if (!ast_adsi_available(chan)) 06085 return; 06086 06087 /* Original command keys */ 06088 for (x=0;x<6;x++) 06089 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06090 06091 keys[6] = 0; 06092 keys[7] = 0; 06093 06094 if ((vms->lastmsg + 1) < 1) 06095 keys[0] = 0; 06096 06097 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06098 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06099 06100 if (vms->lastmsg + 1) 06101 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06102 else 06103 strcpy(buf2, "no messages."); 06104 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06105 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06106 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06107 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06108 bytes += ast_adsi_set_keys(buf + bytes, keys); 06109 06110 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06111 06112 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06113 06114 }
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 11335 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, chan, CONFIG_FLAG_NOCACHE, config_flags, 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(), num, play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
11336 { 11337 int res = 0; 11338 char filename[PATH_MAX]; 11339 struct ast_config *msg_cfg = NULL; 11340 const char *origtime, *context; 11341 char *name, *num; 11342 int retries = 0; 11343 char *cid; 11344 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 11345 11346 vms->starting = 0; 11347 11348 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11349 11350 /* Retrieve info from VM attribute file */ 11351 snprintf(filename,sizeof(filename), "%s.txt", vms->fn); 11352 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 11353 msg_cfg = ast_config_load(filename, config_flags); 11354 DISPOSE(vms->curdir, vms->curmsg); 11355 if (!msg_cfg) { 11356 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 11357 return 0; 11358 } 11359 11360 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 11361 ast_config_destroy(msg_cfg); 11362 return 0; 11363 } 11364 11365 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 11366 11367 context = ast_variable_retrieve(msg_cfg, "message", "context"); 11368 if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ 11369 context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); 11370 switch (option) { 11371 case 3: /* Play message envelope */ 11372 if (!res) 11373 res = play_message_datetime(chan, vmu, origtime, filename); 11374 if (!res) 11375 res = play_message_callerid(chan, vms, cid, context, 0); 11376 11377 res = 't'; 11378 break; 11379 11380 case 2: /* Call back */ 11381 11382 if (ast_strlen_zero(cid)) 11383 break; 11384 11385 ast_callerid_parse(cid, &name, &num); 11386 while ((res > -1) && (res != 't')) { 11387 switch (res) { 11388 case '1': 11389 if (num) { 11390 /* Dial the CID number */ 11391 res = dialout(chan, vmu, num, vmu->callback); 11392 if (res) { 11393 ast_config_destroy(msg_cfg); 11394 return 9; 11395 } 11396 } else { 11397 res = '2'; 11398 } 11399 break; 11400 11401 case '2': 11402 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 11403 if (!ast_strlen_zero(vmu->dialout)) { 11404 res = dialout(chan, vmu, NULL, vmu->dialout); 11405 if (res) { 11406 ast_config_destroy(msg_cfg); 11407 return 9; 11408 } 11409 } else { 11410 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 11411 res = ast_play_and_wait(chan, "vm-sorry"); 11412 } 11413 ast_config_destroy(msg_cfg); 11414 return res; 11415 case '*': 11416 res = 't'; 11417 break; 11418 case '3': 11419 case '4': 11420 case '5': 11421 case '6': 11422 case '7': 11423 case '8': 11424 case '9': 11425 case '0': 11426 11427 res = ast_play_and_wait(chan, "vm-sorry"); 11428 retries++; 11429 break; 11430 default: 11431 if (num) { 11432 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 11433 res = ast_play_and_wait(chan, "vm-num-i-have"); 11434 if (!res) 11435 res = play_message_callerid(chan, vms, num, vmu->context, 1); 11436 if (!res) 11437 res = ast_play_and_wait(chan, "vm-tocallnum"); 11438 /* Only prompt for a caller-specified number if there is a dialout context specified */ 11439 if (!ast_strlen_zero(vmu->dialout)) { 11440 if (!res) 11441 res = ast_play_and_wait(chan, "vm-calldiffnum"); 11442 } 11443 } else { 11444 res = ast_play_and_wait(chan, "vm-nonumber"); 11445 if (!ast_strlen_zero(vmu->dialout)) { 11446 if (!res) 11447 res = ast_play_and_wait(chan, "vm-toenternumber"); 11448 } 11449 } 11450 if (!res) 11451 res = ast_play_and_wait(chan, "vm-star-cancel"); 11452 if (!res) 11453 res = ast_waitfordigit(chan, 6000); 11454 if (!res) { 11455 retries++; 11456 if (retries > 3) 11457 res = 't'; 11458 } 11459 break; 11460 11461 } 11462 if (res == 't') 11463 res = 0; 11464 else if (res == '*') 11465 res = -1; 11466 } 11467 break; 11468 11469 case 1: /* Reply */ 11470 /* Send reply directly to sender */ 11471 if (ast_strlen_zero(cid)) 11472 break; 11473 11474 ast_callerid_parse(cid, &name, &num); 11475 if (!num) { 11476 ast_verb(3, "No CID number available, no reply sent\n"); 11477 if (!res) 11478 res = ast_play_and_wait(chan, "vm-nonumber"); 11479 ast_config_destroy(msg_cfg); 11480 return res; 11481 } else { 11482 struct ast_vm_user vmu2; 11483 if (find_user(&vmu2, vmu->context, num)) { 11484 struct leave_vm_options leave_options; 11485 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 11486 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 11487 11488 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 11489 11490 memset(&leave_options, 0, sizeof(leave_options)); 11491 leave_options.record_gain = record_gain; 11492 res = leave_voicemail(chan, mailbox, &leave_options); 11493 if (!res) 11494 res = 't'; 11495 ast_config_destroy(msg_cfg); 11496 return res; 11497 } else { 11498 /* Sender has no mailbox, can't reply */ 11499 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 11500 ast_play_and_wait(chan, "vm-nobox"); 11501 res = 't'; 11502 ast_config_destroy(msg_cfg); 11503 return res; 11504 } 11505 } 11506 res = 0; 11507 11508 break; 11509 } 11510 11511 #ifndef IMAP_STORAGE 11512 ast_config_destroy(msg_cfg); 11513 11514 if (!res) { 11515 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11516 vms->heard[msg] = 1; 11517 res = wait_file(chan, vms, vms->fn); 11518 } 11519 #endif 11520 return res; 11521 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 9829 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_strdupa, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), ast_vm_user::pager, ast_vm_user::password, populate_defaults(), queue_mwi_event(), s, and strsep().
Referenced by load_config().
09830 { 09831 /* Assumes lock is already held */ 09832 char *tmp; 09833 char *stringp; 09834 char *s; 09835 struct ast_vm_user *vmu; 09836 char *mailbox_full; 09837 int new = 0, old = 0, urgent = 0; 09838 09839 tmp = ast_strdupa(data); 09840 09841 if (!(vmu = find_or_create(context, box))) 09842 return -1; 09843 09844 populate_defaults(vmu); 09845 09846 stringp = tmp; 09847 if ((s = strsep(&stringp, ","))) 09848 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 09849 if (stringp && (s = strsep(&stringp, ","))) 09850 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 09851 if (stringp && (s = strsep(&stringp, ","))) 09852 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 09853 if (stringp && (s = strsep(&stringp, ","))) 09854 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 09855 if (stringp && (s = strsep(&stringp, ","))) 09856 apply_options(vmu, s); 09857 09858 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 09859 strcpy(mailbox_full, box); 09860 strcat(mailbox_full, "@"); 09861 strcat(mailbox_full, context); 09862 09863 inboxcount2(mailbox_full, &urgent, &new, &old); 09864 queue_mwi_event(mailbox_full, urgent, new, old); 09865 09866 return 0; 09867 }
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 841 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::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, 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_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
00842 { 00843 int x; 00844 if (!strcasecmp(var, "attach")) { 00845 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 00846 } else if (!strcasecmp(var, "attachfmt")) { 00847 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 00848 } else if (!strcasecmp(var, "serveremail")) { 00849 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 00850 } else if (!strcasecmp(var, "language")) { 00851 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 00852 } else if (!strcasecmp(var, "tz")) { 00853 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 00854 #ifdef IMAP_STORAGE 00855 } else if (!strcasecmp(var, "imapuser")) { 00856 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 00857 vmu->imapversion = imapversion; 00858 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 00859 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 00860 vmu->imapversion = imapversion; 00861 } else if (!strcasecmp(var, "imapvmshareid")) { 00862 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 00863 vmu->imapversion = imapversion; 00864 #endif 00865 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 00866 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 00867 } else if (!strcasecmp(var, "saycid")){ 00868 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 00869 } else if (!strcasecmp(var,"sendvoicemail")){ 00870 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 00871 } else if (!strcasecmp(var, "review")){ 00872 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 00873 } else if (!strcasecmp(var, "tempgreetwarn")){ 00874 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 00875 } else if (!strcasecmp(var, "messagewrap")){ 00876 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 00877 } else if (!strcasecmp(var, "operator")) { 00878 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 00879 } else if (!strcasecmp(var, "envelope")){ 00880 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 00881 } else if (!strcasecmp(var, "moveheard")){ 00882 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 00883 } else if (!strcasecmp(var, "sayduration")){ 00884 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 00885 } else if (!strcasecmp(var, "saydurationm")){ 00886 if (sscanf(value, "%30d", &x) == 1) { 00887 vmu->saydurationm = x; 00888 } else { 00889 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 00890 } 00891 } else if (!strcasecmp(var, "forcename")){ 00892 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 00893 } else if (!strcasecmp(var, "forcegreetings")){ 00894 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 00895 } else if (!strcasecmp(var, "callback")) { 00896 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 00897 } else if (!strcasecmp(var, "dialout")) { 00898 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 00899 } else if (!strcasecmp(var, "exitcontext")) { 00900 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 00901 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 00902 vmu->maxsecs = atoi(value); 00903 if (vmu->maxsecs <= 0) { 00904 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 00905 vmu->maxsecs = vmmaxsecs; 00906 } else { 00907 vmu->maxsecs = atoi(value); 00908 } 00909 if (!strcasecmp(var, "maxmessage")) 00910 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 00911 } else if (!strcasecmp(var, "maxmsg")) { 00912 vmu->maxmsg = atoi(value); 00913 if (vmu->maxmsg <= 0) { 00914 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 00915 vmu->maxmsg = MAXMSG; 00916 } else if (vmu->maxmsg > MAXMSGLIMIT) { 00917 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 00918 vmu->maxmsg = MAXMSGLIMIT; 00919 } 00920 } else if (!strcasecmp(var, "backupdeleted")) { 00921 if (sscanf(value, "%30d", &x) == 1) 00922 vmu->maxdeletedmsg = x; 00923 else if (ast_true(value)) 00924 vmu->maxdeletedmsg = MAXMSG; 00925 else 00926 vmu->maxdeletedmsg = 0; 00927 00928 if (vmu->maxdeletedmsg < 0) { 00929 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 00930 vmu->maxdeletedmsg = MAXMSG; 00931 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 00932 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 00933 vmu->maxdeletedmsg = MAXMSGLIMIT; 00934 } 00935 } else if (!strcasecmp(var, "volgain")) { 00936 sscanf(value, "%30lf", &vmu->volgain); 00937 } else if (!strcasecmp(var, "options")) { 00938 apply_options(vmu, value); 00939 } 00940 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1054 of file app_voicemail.c.
References apply_option(), ast_strdupa, s, strsep(), and var.
Referenced by append_mailbox(), and apply_option().
01055 { 01056 char *stringp; 01057 char *s; 01058 char *var, *value; 01059 stringp = ast_strdupa(options); 01060 while ((s = strsep(&stringp, "|"))) { 01061 value = s; 01062 if ((var = strsep(&value, "=")) && value) { 01063 apply_option(vmu, var, value); 01064 } 01065 } 01066 }
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 1073 of file app_voicemail.c.
References apply_option(), ast_copy_string(), ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::fullname, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::uniqueid, ast_variable::value, and var.
Referenced by find_user_realtime(), and load_config().
01074 { 01075 struct ast_variable *tmp; 01076 tmp = var; 01077 while (tmp) { 01078 if (!strcasecmp(tmp->name, "vmsecret")) { 01079 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 01080 } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */ 01081 if (ast_strlen_zero(retval->password)) 01082 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 01083 } else if (!strcasecmp(tmp->name, "uniqueid")) { 01084 ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid)); 01085 } else if (!strcasecmp(tmp->name, "pager")) { 01086 ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager)); 01087 } else if (!strcasecmp(tmp->name, "email")) { 01088 ast_copy_string(retval->email, tmp->value, sizeof(retval->email)); 01089 } else if (!strcasecmp(tmp->name, "fullname")) { 01090 ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname)); 01091 } else if (!strcasecmp(tmp->name, "context")) { 01092 ast_copy_string(retval->context, tmp->value, sizeof(retval->context)); 01093 #ifdef IMAP_STORAGE 01094 } else if (!strcasecmp(tmp->name, "imapuser")) { 01095 ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser)); 01096 retval->imapversion = imapversion; 01097 } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) { 01098 ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword)); 01099 retval->imapversion = imapversion; 01100 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01101 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01102 retval->imapversion = imapversion; 01103 #endif 01104 } else 01105 apply_option(retval, tmp->name, tmp->value); 01106 tmp = tmp->next; 01107 } 01108 }
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 3827 of file app_voicemail.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
03828 { 03829 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 03830 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 03831 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 03832 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 03833 int i,hiteof= 0; 03834 FILE *fi; 03835 struct baseio bio; 03836 03837 memset(&bio, 0, sizeof(bio)); 03838 bio.iocp = BASEMAXINLINE; 03839 03840 if (!(fi = fopen(filename, "rb"))) { 03841 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 03842 return -1; 03843 } 03844 03845 while (!hiteof){ 03846 unsigned char igroup[3], ogroup[4]; 03847 int c,n; 03848 03849 igroup[0]= igroup[1]= igroup[2]= 0; 03850 03851 for (n= 0;n<3;n++) { 03852 if ((c = inchar(&bio, fi)) == EOF) { 03853 hiteof= 1; 03854 break; 03855 } 03856 03857 igroup[n]= (unsigned char)c; 03858 } 03859 03860 if (n> 0) { 03861 ogroup[0]= dtable[igroup[0]>>2]; 03862 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 03863 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 03864 ogroup[3]= dtable[igroup[2]&0x3F]; 03865 03866 if (n<3) { 03867 ogroup[3]= '='; 03868 03869 if (n<2) 03870 ogroup[2]= '='; 03871 } 03872 03873 for (i= 0;i<4;i++) 03874 ochar(&bio, ogroup[i], so); 03875 } 03876 } 03877 03878 fclose(fi); 03879 03880 if (fputs(ENDL, so) == EOF) { 03881 return 0; 03882 } 03883 03884 return 1; 03885 }
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 1033 of file app_voicemail.c.
References ast_copy_string(), ast_realtime_require_field(), ast_strlen_zero(), ast_update_realtime(), ast_vm_user::password, RQ_CHAR, SENTINEL, and ast_vm_user::uniqueid.
Referenced by vm_change_password().
01034 { 01035 int res = -1; 01036 if (!strcmp(vmu->password, password)) { 01037 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01038 res = 0; 01039 } else if (!ast_strlen_zero(vmu->uniqueid)) { 01040 if (strlen(password) > 10) { 01041 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01042 } 01043 if (ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, SENTINEL) > 0) { 01044 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01045 res = 0; 01046 } 01047 } 01048 return res; 01049 }
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 3993 of file app_voicemail.c.
Referenced by make_email_file().
03994 { 03995 for (; *str; str++) { 03996 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 03997 return 1; 03998 } 03999 } 04000 return 0; 04001 }
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 995 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), buf, 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().
00996 { 00997 /* check minimum length */ 00998 if (strlen(password) < minpassword) 00999 return 1; 01000 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01001 char cmd[255], buf[255]; 01002 01003 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01004 01005 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01006 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01007 ast_debug(5, "Result: %s\n", buf); 01008 if (!strncasecmp(buf, "VALID", 5)) { 01009 ast_debug(3, "Passed password check: '%s'\n", buf); 01010 return 0; 01011 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01012 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01013 return 0; 01014 } else { 01015 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01016 return 1; 01017 } 01018 } 01019 } 01020 return 0; 01021 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7219 of file app_voicemail.c.
References ast_log(), ast_test_flag, ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, 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::maxmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
07220 { 07221 int x = 0; 07222 #ifndef IMAP_STORAGE 07223 int res = 0, nummsg; 07224 char fn2[PATH_MAX]; 07225 #endif 07226 07227 if (vms->lastmsg <= -1) 07228 goto done; 07229 07230 vms->curmsg = -1; 07231 #ifndef IMAP_STORAGE 07232 /* Get the deleted messages fixed */ 07233 if (vm_lock_path(vms->curdir)) 07234 return ERROR_LOCK_PATH; 07235 07236 for (x = 0; x < vmu->maxmsg; x++) { 07237 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07238 /* Save this message. It's not in INBOX or hasn't been heard */ 07239 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07240 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 07241 break; 07242 vms->curmsg++; 07243 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07244 if (strcmp(vms->fn, fn2)) { 07245 RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07246 } 07247 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07248 /* Move to old folder before deleting */ 07249 res = save_to_folder(vmu, vms, x, 1); 07250 if (res == ERROR_LOCK_PATH) { 07251 /* If save failed do not delete the message */ 07252 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07253 vms->deleted[x] = 0; 07254 vms->heard[x] = 0; 07255 --x; 07256 } 07257 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07258 /* Move to deleted folder */ 07259 res = save_to_folder(vmu, vms, x, 10); 07260 if (res == ERROR_LOCK_PATH) { 07261 /* If save failed do not delete the message */ 07262 vms->deleted[x] = 0; 07263 vms->heard[x] = 0; 07264 --x; 07265 } 07266 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07267 /* If realtime storage enabled - we should explicitly delete this message, 07268 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07269 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07270 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07271 DELETE(vms->curdir, x, vms->fn, vmu); 07272 } 07273 } 07274 07275 /* Delete ALL remaining messages */ 07276 nummsg = x - 1; 07277 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07278 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07279 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07280 DELETE(vms->curdir, x, vms->fn, vmu); 07281 } 07282 ast_unlock_path(vms->curdir); 07283 #else 07284 if (vms->deleted) { 07285 for (x=0;x < vmu->maxmsg;x++) { 07286 if (vms->deleted[x]) { 07287 ast_debug(3,"IMAP delete of %d\n",x); 07288 DELETE(vms->curdir, x, vms->fn, vmu); 07289 } 07290 } 07291 } 07292 #endif 07293 07294 done: 07295 if (vms->deleted) 07296 memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 07297 if (vms->heard) 07298 memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 07299 07300 return 0; 07301 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10013 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().
10014 { 10015 int which = 0; 10016 int wordlen; 10017 struct ast_vm_user *vmu; 10018 const char *context = ""; 10019 10020 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 10021 if (pos > 4) 10022 return NULL; 10023 if (pos == 3) 10024 return (state == 0) ? ast_strdup("for") : NULL; 10025 wordlen = strlen(word); 10026 AST_LIST_TRAVERSE(&users, vmu, list) { 10027 if (!strncasecmp(word, vmu->context, wordlen)) { 10028 if (context && strcmp(context, vmu->context) && ++which > state) 10029 return ast_strdup(vmu->context); 10030 /* ignore repeated contexts ? */ 10031 context = vmu->context; 10032 } 10033 } 10034 return NULL; 10035 }
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 3631 of file app_voicemail.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
03632 { 03633 int ifd; 03634 int ofd; 03635 int res; 03636 int len; 03637 char buf[4096]; 03638 03639 #ifdef HARDLINK_WHEN_POSSIBLE 03640 /* Hard link if possible; saves disk space & is faster */ 03641 if (link(infile, outfile)) { 03642 #endif 03643 if ((ifd = open(infile, O_RDONLY)) < 0) { 03644 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03645 return -1; 03646 } 03647 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03648 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03649 close(ifd); 03650 return -1; 03651 } 03652 do { 03653 len = read(ifd, buf, sizeof(buf)); 03654 if (len < 0) { 03655 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03656 close(ifd); 03657 close(ofd); 03658 unlink(outfile); 03659 } 03660 if (len) { 03661 res = write(ofd, buf, len); 03662 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03663 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03664 close(ifd); 03665 close(ofd); 03666 unlink(outfile); 03667 } 03668 } 03669 } while (len); 03670 close(ifd); 03671 close(ofd); 03672 return 0; 03673 #ifdef HARDLINK_WHEN_POSSIBLE 03674 } else { 03675 /* Hard link succeeded */ 03676 return 0; 03677 } 03678 #endif 03679 }
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 | This is only used by file storage based mailboxes. |
Definition at line 4802 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, inprocess_count(), ast_channel::language, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), mbox(), notify_new_message(), S_OR, STORE, vm_delete(), and vm_lock_path().
Referenced by forward_message(), and leave_voicemail().
04803 { 04804 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 04805 const char *frombox = mbox(imbox); 04806 int recipmsgnum; 04807 int res = 0; 04808 04809 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 04810 04811 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 04812 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 04813 } else { 04814 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04815 } 04816 04817 if (!dir) 04818 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 04819 else 04820 ast_copy_string(fromdir, dir, sizeof(fromdir)); 04821 04822 make_file(frompath, sizeof(frompath), fromdir, msgnum); 04823 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04824 04825 if (vm_lock_path(todir)) 04826 return ERROR_LOCK_PATH; 04827 04828 recipmsgnum = last_message_index(recip, todir) + 1; 04829 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 04830 make_file(topath, sizeof(topath), todir, recipmsgnum); 04831 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 04832 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 04833 } else { 04834 /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL 04835 * copy will fail. Instead, we need to create a local copy, store it, and delete the local 04836 * copy. We don't have to #ifdef this because if file storage reaches this point, there's a 04837 * much worse problem happening and IMAP storage doesn't call this function 04838 */ 04839 copy_plain_file(frompath, topath); 04840 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 04841 vm_delete(topath); 04842 } 04843 } else { 04844 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 04845 res = -1; 04846 } 04847 ast_unlock_path(todir); 04848 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 04849 04850 return res; 04851 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 3690 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().
03691 { 03692 char frompath2[PATH_MAX], topath2[PATH_MAX]; 03693 struct ast_variable *tmp,*var = NULL; 03694 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 03695 ast_filecopy(frompath, topath, NULL); 03696 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 03697 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 03698 if (ast_check_realtime("voicemail_data")) { 03699 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 03700 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 03701 for (tmp = var; tmp; tmp = tmp->next) { 03702 if (!strcasecmp(tmp->name, "origmailbox")) { 03703 origmailbox = tmp->value; 03704 } else if (!strcasecmp(tmp->name, "context")) { 03705 context = tmp->value; 03706 } else if (!strcasecmp(tmp->name, "macrocontext")) { 03707 macrocontext = tmp->value; 03708 } else if (!strcasecmp(tmp->name, "exten")) { 03709 exten = tmp->value; 03710 } else if (!strcasecmp(tmp->name, "priority")) { 03711 priority = tmp->value; 03712 } else if (!strcasecmp(tmp->name, "callerchan")) { 03713 callerchan = tmp->value; 03714 } else if (!strcasecmp(tmp->name, "callerid")) { 03715 callerid = tmp->value; 03716 } else if (!strcasecmp(tmp->name, "origdate")) { 03717 origdate = tmp->value; 03718 } else if (!strcasecmp(tmp->name, "origtime")) { 03719 origtime = tmp->value; 03720 } else if (!strcasecmp(tmp->name, "category")) { 03721 category = tmp->value; 03722 } else if (!strcasecmp(tmp->name, "duration")) { 03723 duration = tmp->value; 03724 } 03725 } 03726 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); 03727 } 03728 copy(frompath2, topath2); 03729 ast_variables_destroy(var); 03730 }
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 3534 of file app_voicemail.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().
03535 { 03536 03537 int vmcount = 0; 03538 DIR *vmdir = NULL; 03539 struct dirent *vment = NULL; 03540 03541 if (vm_lock_path(dir)) 03542 return ERROR_LOCK_PATH; 03543 03544 if ((vmdir = opendir(dir))) { 03545 while ((vment = readdir(vmdir))) { 03546 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03547 vmcount++; 03548 } 03549 } 03550 closedir(vmdir); 03551 } 03552 ast_unlock_path(dir); 03553 03554 return vmcount; 03555 }
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 1383 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01384 { 01385 mode_t mode = VOICEMAIL_DIR_MODE; 01386 int res; 01387 01388 make_dir(dest, len, context, ext, folder); 01389 if ((res = ast_mkdir(dest, mode))) { 01390 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01391 return -1; 01392 } 01393 return 0; 01394 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 11263 of file app_voicemail.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verb, ast_verbose, ast_waitfordigit(), chan, ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.
Referenced by advanced_options(), and vm_execmain().
11264 { 11265 int cmd = 0; 11266 char destination[80] = ""; 11267 int retries = 0; 11268 11269 if (!num) { 11270 ast_verb(3, "Destination number will be entered manually\n"); 11271 while (retries < 3 && cmd != 't') { 11272 destination[1] = '\0'; 11273 destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call"); 11274 if (!cmd) 11275 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 11276 if (!cmd) 11277 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 11278 if (!cmd) { 11279 cmd = ast_waitfordigit(chan, 6000); 11280 if (cmd) 11281 destination[0] = cmd; 11282 } 11283 if (!cmd) { 11284 retries++; 11285 } else { 11286 11287 if (cmd < 0) 11288 return 0; 11289 if (cmd == '*') { 11290 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 11291 return 0; 11292 } 11293 if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 11294 retries++; 11295 else 11296 cmd = 't'; 11297 } 11298 } 11299 if (retries >= 3) { 11300 return 0; 11301 } 11302 11303 } else { 11304 if (option_verbose > 2) 11305 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 11306 ast_copy_string(destination, num, sizeof(destination)); 11307 } 11308 11309 if (!ast_strlen_zero(destination)) { 11310 if (destination[strlen(destination) -1 ] == '*') 11311 return 0; 11312 if (option_verbose > 2) 11313 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 11314 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 11315 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 11316 chan->priority = 0; 11317 return 9; 11318 } 11319 return 0; 11320 }
static char* encode_mime_str | ( | const char * | start, | |
char * | end, | |||
size_t | endsize, | |||
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.
start | A string to be encoded | |
end | An expandable buffer for holding the result | |
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 4019 of file app_voicemail.c.
References charset.
Referenced by make_email_file().
04020 { 04021 char tmp[80]; 04022 int first_section = 1; 04023 size_t endlen = 0, tmplen = 0; 04024 *end = '\0'; 04025 04026 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 04027 for (; *start; start++) { 04028 int need_encoding = 0; 04029 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04030 need_encoding = 1; 04031 } 04032 if ((first_section && need_encoding && preamble + tmplen > 70) || 04033 (first_section && !need_encoding && preamble + tmplen > 72) || 04034 (!first_section && need_encoding && tmplen > 70) || 04035 (!first_section && !need_encoding && tmplen > 72)) { 04036 /* Start new line */ 04037 endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp); 04038 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 04039 first_section = 0; 04040 } 04041 if (need_encoding && *start == ' ') { 04042 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_"); 04043 } else if (need_encoding) { 04044 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start); 04045 } else { 04046 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start); 04047 } 04048 } 04049 snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : ""); 04050 return end; 04051 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 9797 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().
09798 { 09799 struct ast_vm_user *vmu; 09800 09801 AST_LIST_TRAVERSE(&users, vmu, list) { 09802 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 09803 if (strcasecmp(vmu->context, context)) { 09804 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 09805 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 09806 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 09807 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 09808 } 09809 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 09810 return NULL; 09811 } 09812 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 09813 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 09814 return NULL; 09815 } 09816 } 09817 09818 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 09819 return NULL; 09820 09821 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 09822 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 09823 09824 AST_LIST_INSERT_TAIL(&users, vmu, list); 09825 09826 return vmu; 09827 }
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 1179 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.
01180 { 01181 /* This function could be made to generate one from a database, too */ 01182 struct ast_vm_user *vmu=NULL, *cur; 01183 AST_LIST_LOCK(&users); 01184 01185 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01186 context = "default"; 01187 01188 AST_LIST_TRAVERSE(&users, cur, list) { 01189 #ifdef IMAP_STORAGE 01190 if (cur->imapversion != imapversion) { 01191 continue; 01192 } 01193 #endif 01194 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01195 break; 01196 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01197 break; 01198 } 01199 if (cur) { 01200 /* Make a copy, so that on a reload, we have no race */ 01201 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01202 memcpy(vmu, cur, sizeof(*vmu)); 01203 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01204 AST_LIST_NEXT(vmu, list) = NULL; 01205 } 01206 } else 01207 vmu = find_user_realtime(ivm, context, mailbox); 01208 AST_LIST_UNLOCK(&users); 01209 return vmu; 01210 }
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 1142 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.
01143 { 01144 struct ast_variable *var; 01145 struct ast_vm_user *retval; 01146 01147 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01148 if (!ivm) 01149 ast_set_flag(retval, VM_ALLOCED); 01150 else 01151 memset(retval, 0, sizeof(*retval)); 01152 if (mailbox) 01153 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01154 populate_defaults(retval); 01155 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01156 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01157 else 01158 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01159 if (var) { 01160 apply_options_full(retval, var); 01161 ast_variables_destroy(var); 01162 } else { 01163 if (!ivm) 01164 ast_free(retval); 01165 retval = NULL; 01166 } 01167 } 01168 return retval; 01169 }
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.
ast_channel | ||
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 |
When in the leave message mode (is_new_message == 1):
When in the forward message mode (is_new_message == 0):
Definition at line 6498 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(), chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, 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_channel::language, leave_voicemail(), ast_app::list, LOG_NOTICE, ast_vm_user::mailbox, make_file(), pbx_exec(), pbx_findapp(), ast_channel::priority, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, strsep(), vm_state::username, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
Referenced by vm_execmain().
06499 { 06500 #ifdef IMAP_STORAGE 06501 int todircount=0; 06502 struct vm_state *dstvms; 06503 #endif 06504 char username[70]=""; 06505 char fn[PATH_MAX]; /* for playback of name greeting */ 06506 char ecodes[16] = "#"; 06507 int res = 0, cmd = 0; 06508 struct ast_vm_user *receiver = NULL, *vmtmp; 06509 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 06510 char *stringp; 06511 const char *s; 06512 int saved_messages = 0, found = 0; 06513 int valid_extensions = 0; 06514 char *dir; 06515 int curmsg; 06516 char urgent_str[7] = ""; 06517 char tmptxtfile[PATH_MAX]; 06518 int prompt_played = 0; 06519 #ifndef IMAP_STORAGE 06520 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06521 #endif 06522 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 06523 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 06524 } 06525 06526 if (vms == NULL) return -1; 06527 dir = vms->curdir; 06528 curmsg = vms->curmsg; 06529 06530 tmptxtfile[0] = '\0'; 06531 while (!res && !valid_extensions) { 06532 int use_directory = 0; 06533 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 06534 int done = 0; 06535 int retries = 0; 06536 cmd=0; 06537 while ((cmd >= 0) && !done ){ 06538 if (cmd) 06539 retries = 0; 06540 switch (cmd) { 06541 case '1': 06542 use_directory = 0; 06543 done = 1; 06544 break; 06545 case '2': 06546 use_directory = 1; 06547 done=1; 06548 break; 06549 case '*': 06550 cmd = 't'; 06551 done = 1; 06552 break; 06553 default: 06554 /* Press 1 to enter an extension press 2 to use the directory */ 06555 cmd = ast_play_and_wait(chan,"vm-forward"); 06556 if (!cmd) 06557 cmd = ast_waitfordigit(chan,3000); 06558 if (!cmd) 06559 retries++; 06560 if (retries > 3) { 06561 cmd = 't'; 06562 done = 1; 06563 } 06564 06565 } 06566 } 06567 if (cmd < 0 || cmd == 't') 06568 break; 06569 } 06570 06571 if (use_directory) { 06572 /* use app_directory */ 06573 06574 char old_context[sizeof(chan->context)]; 06575 char old_exten[sizeof(chan->exten)]; 06576 int old_priority; 06577 struct ast_app* directory_app; 06578 06579 directory_app = pbx_findapp("Directory"); 06580 if (directory_app) { 06581 char vmcontext[256]; 06582 /* make backup copies */ 06583 memcpy(old_context, chan->context, sizeof(chan->context)); 06584 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 06585 old_priority = chan->priority; 06586 06587 /* call the the Directory, changes the channel */ 06588 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 06589 res = pbx_exec(chan, directory_app, vmcontext); 06590 06591 ast_copy_string(username, chan->exten, sizeof(username)); 06592 06593 /* restore the old context, exten, and priority */ 06594 memcpy(chan->context, old_context, sizeof(chan->context)); 06595 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 06596 chan->priority = old_priority; 06597 } else { 06598 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 06599 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 06600 } 06601 } else { 06602 /* Ask for an extension */ 06603 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 06604 prompt_played++; 06605 if (res || prompt_played > 4) 06606 break; 06607 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 06608 break; 06609 } 06610 06611 /* start all over if no username */ 06612 if (ast_strlen_zero(username)) 06613 continue; 06614 stringp = username; 06615 s = strsep(&stringp, "*"); 06616 /* start optimistic */ 06617 valid_extensions = 1; 06618 while (s) { 06619 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 06620 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 06621 found++; 06622 } else { 06623 /* XXX Optimization for the future. When we encounter a single bad extension, 06624 * bailing out on all of the extensions may not be the way to go. We should 06625 * probably just bail on that single extension, then allow the user to enter 06626 * several more. XXX 06627 */ 06628 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 06629 free_user(receiver); 06630 } 06631 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 06632 valid_extensions = 0; 06633 break; 06634 } 06635 06636 /* play name if available, else play extension number */ 06637 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 06638 RETRIEVE(fn, -1, s, receiver->context); 06639 if (ast_fileexists(fn, NULL, NULL) > 0) { 06640 res = ast_stream_and_wait(chan, fn, ecodes); 06641 if (res) { 06642 DISPOSE(fn, -1); 06643 return res; 06644 } 06645 } else { 06646 res = ast_say_digit_str(chan, s, ecodes, chan->language); 06647 } 06648 DISPOSE(fn, -1); 06649 06650 s = strsep(&stringp, "*"); 06651 } 06652 /* break from the loop of reading the extensions */ 06653 if (valid_extensions) 06654 break; 06655 /* "I am sorry, that's not a valid extension. Please try again." */ 06656 res = ast_play_and_wait(chan, "pbx-invalid"); 06657 } 06658 /* check if we're clear to proceed */ 06659 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 06660 return res; 06661 if (is_new_message == 1) { 06662 struct leave_vm_options leave_options; 06663 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 06664 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 06665 06666 /* Send VoiceMail */ 06667 memset(&leave_options, 0, sizeof(leave_options)); 06668 leave_options.record_gain = record_gain; 06669 cmd = leave_voicemail(chan, mailbox, &leave_options); 06670 } else { 06671 /* Forward VoiceMail */ 06672 long duration = 0; 06673 struct vm_state vmstmp; 06674 int copy_msg_result = 0; 06675 memcpy(&vmstmp, vms, sizeof(vmstmp)); 06676 06677 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 06678 06679 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 06680 if (!cmd) { 06681 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 06682 #ifdef IMAP_STORAGE 06683 int attach_user_voicemail; 06684 char *myserveremail = serveremail; 06685 06686 /* get destination mailbox */ 06687 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 06688 if (!dstvms) { 06689 dstvms = create_vm_state_from_user(vmtmp); 06690 } 06691 if (dstvms) { 06692 init_mailstream(dstvms, 0); 06693 if (!dstvms->mailstream) { 06694 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 06695 } else { 06696 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 06697 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 06698 } 06699 } else { 06700 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 06701 } 06702 if (!ast_strlen_zero(vmtmp->serveremail)) 06703 myserveremail = vmtmp->serveremail; 06704 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 06705 /* NULL category for IMAP storage */ 06706 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, NULL, urgent_str); 06707 #else 06708 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 06709 #endif 06710 saved_messages++; 06711 AST_LIST_REMOVE_CURRENT(list); 06712 free_user(vmtmp); 06713 if (res) 06714 break; 06715 } 06716 AST_LIST_TRAVERSE_SAFE_END; 06717 if (saved_messages > 0 && !copy_msg_result) { 06718 /* give confirmation that the message was saved */ 06719 /* commented out since we can't forward batches yet 06720 if (saved_messages == 1) 06721 res = ast_play_and_wait(chan, "vm-message"); 06722 else 06723 res = ast_play_and_wait(chan, "vm-messages"); 06724 if (!res) 06725 res = ast_play_and_wait(chan, "vm-saved"); */ 06726 #ifdef IMAP_STORAGE 06727 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 06728 if (ast_strlen_zero(vmstmp.introfn)) 06729 #endif 06730 res = ast_play_and_wait(chan, "vm-msgsaved"); 06731 } 06732 #ifndef IMAP_STORAGE 06733 else { 06734 /* with IMAP, mailbox full warning played by imap_check_limits */ 06735 res = ast_play_and_wait(chan, "vm-mailboxfull"); 06736 } 06737 /* Restore original message without prepended message if backup exists */ 06738 make_file(msgfile, sizeof(msgfile), dir, curmsg); 06739 strcpy(textfile, msgfile); 06740 strcpy(backup, msgfile); 06741 strcpy(backup_textfile, msgfile); 06742 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06743 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06744 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06745 if (ast_fileexists(backup, NULL, NULL) > 0) { 06746 ast_filerename(backup, msgfile, NULL); 06747 rename(backup_textfile, textfile); 06748 } 06749 #endif 06750 } 06751 DISPOSE(dir, curmsg); 06752 } 06753 06754 /* If anything failed above, we still have this list to free */ 06755 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) 06756 free_user(vmtmp); 06757 return res ? res : cmd; 06758 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1419 of file app_voicemail.c.
References ast_free, ast_test_flag, and VM_ALLOCED.
01420 { 01421 if (ast_test_flag(vmu, VM_ALLOCED)) 01422 ast_free(vmu); 01423 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 10470 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().
10471 { 10472 struct ast_vm_user *current; 10473 AST_LIST_LOCK(&users); 10474 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 10475 ast_set_flag(current, VM_ALLOCED); 10476 free_user(current); 10477 } 10478 AST_LIST_UNLOCK(&users); 10479 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 10482 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().
10483 { 10484 struct vm_zone *zcur; 10485 AST_LIST_LOCK(&zones); 10486 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 10487 free_zone(zcur); 10488 AST_LIST_UNLOCK(&zones); 10489 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4570 of file app_voicemail.c.
References ast_free.
04571 { 04572 ast_free(z); 04573 }
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 4526 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
04527 { 04528 struct ast_tm tm; 04529 struct timeval t = ast_tvnow(); 04530 04531 ast_localtime(&t, &tm, "UTC"); 04532 04533 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04534 }
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 6150 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), chan, ast_channel::language, mbox(), and vm_play_folder_name().
Referenced by get_folder2().
06151 { 06152 int x; 06153 int d; 06154 char fn[PATH_MAX]; 06155 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06156 if (d) 06157 return d; 06158 for (x = start; x< 5; x++) { /* For all folders */ 06159 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06160 return d; 06161 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06162 if (d) 06163 return d; 06164 snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */ 06165 d = vm_play_folder_name(chan, fn); 06166 if (d) 06167 return d; 06168 d = ast_waitfordigit(chan, 500); 06169 if (d) 06170 return d; 06171 } 06172 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06173 if (d) 06174 return d; 06175 d = ast_waitfordigit(chan, 4000); 06176 return d; 06177 }
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 6191 of file app_voicemail.c.
References ast_play_and_wait(), chan, and get_folder().
Referenced by vm_execmain().
06192 { 06193 int res = 0; 06194 int loops = 0; 06195 res = ast_play_and_wait(chan, fn); /* Folder name */ 06196 while (((res < '0') || (res > '9')) && 06197 (res != '#') && (res >= 0) && 06198 loops < 4) { 06199 res = get_folder(chan, 0); 06200 loops++; 06201 } 06202 if (loops == 4) { /* give up */ 06203 return '#'; 06204 } 06205 return res; 06206 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 10253 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::mailbox, mwi_sub_task::mailbox, poll_subscribed_mailbox(), mwi_sub_task::uniqueid, and mwi_sub::uniqueid.
Referenced by mwi_sub_event_cb().
10254 { 10255 unsigned int len; 10256 struct mwi_sub *mwi_sub; 10257 struct mwi_sub_task *p = datap; 10258 10259 len = sizeof(*mwi_sub); 10260 if (!ast_strlen_zero(p->mailbox)) 10261 len += strlen(p->mailbox); 10262 10263 if (!ast_strlen_zero(p->context)) 10264 len += strlen(p->context) + 1; /* Allow for seperator */ 10265 10266 if (!(mwi_sub = ast_calloc(1, len))) 10267 return -1; 10268 10269 mwi_sub->uniqueid = p->uniqueid; 10270 if (!ast_strlen_zero(p->mailbox)) 10271 strcpy(mwi_sub->mailbox, p->mailbox); 10272 10273 if (!ast_strlen_zero(p->context)) { 10274 strcat(mwi_sub->mailbox, "@"); 10275 strcat(mwi_sub->mailbox, p->context); 10276 } 10277 10278 AST_RWLIST_WRLOCK(&mwi_subs); 10279 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 10280 AST_RWLIST_UNLOCK(&mwi_subs); 10281 ast_free((void *) p->mailbox); 10282 ast_free((void *) p->context); 10283 ast_free(p); 10284 poll_subscribed_mailbox(mwi_sub); 10285 return 0; 10286 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 10231 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_destroy(), and mwi_sub::uniqueid.
Referenced by mwi_unsub_event_cb().
10232 { 10233 struct mwi_sub *mwi_sub; 10234 uint32_t *uniqueid = datap; 10235 10236 AST_RWLIST_WRLOCK(&mwi_subs); 10237 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 10238 if (mwi_sub->uniqueid == *uniqueid) { 10239 AST_LIST_REMOVE_CURRENT(entry); 10240 break; 10241 } 10242 } 10243 AST_RWLIST_TRAVERSE_SAFE_END 10244 AST_RWLIST_UNLOCK(&mwi_subs); 10245 10246 if (mwi_sub) 10247 mwi_sub_destroy(mwi_sub); 10248 10249 ast_free(uniqueid); 10250 return 0; 10251 }
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 10148 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.
10149 { 10150 switch (cmd) { 10151 case CLI_INIT: 10152 e->command = "voicemail reload"; 10153 e->usage = 10154 "Usage: voicemail reload\n" 10155 " Reload voicemail configuration\n"; 10156 return NULL; 10157 case CLI_GENERATE: 10158 return NULL; 10159 } 10160 10161 if (a->argc != 2) 10162 return CLI_SHOWUSAGE; 10163 10164 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 10165 load_config(1); 10166 10167 return CLI_SUCCESS; 10168 }
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 10038 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.
10039 { 10040 struct ast_vm_user *vmu; 10041 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 10042 const char *context = NULL; 10043 int users_counter = 0; 10044 10045 switch (cmd) { 10046 case CLI_INIT: 10047 e->command = "voicemail show users"; 10048 e->usage = 10049 "Usage: voicemail show users [for <context>]\n" 10050 " Lists all mailboxes currently set up\n"; 10051 return NULL; 10052 case CLI_GENERATE: 10053 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 10054 } 10055 10056 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 10057 return CLI_SHOWUSAGE; 10058 if (a->argc == 5) { 10059 if (strcmp(a->argv[3],"for")) 10060 return CLI_SHOWUSAGE; 10061 context = a->argv[4]; 10062 } 10063 10064 if (ast_check_realtime("voicemail")) { 10065 if (!context) { 10066 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 10067 return CLI_SHOWUSAGE; 10068 } 10069 return show_users_realtime(a->fd, context); 10070 } 10071 10072 AST_LIST_LOCK(&users); 10073 if (AST_LIST_EMPTY(&users)) { 10074 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 10075 AST_LIST_UNLOCK(&users); 10076 return CLI_FAILURE; 10077 } 10078 if (a->argc == 3) 10079 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10080 else { 10081 int count = 0; 10082 AST_LIST_TRAVERSE(&users, vmu, list) { 10083 if (!strcmp(context, vmu->context)) 10084 count++; 10085 } 10086 if (count) { 10087 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10088 } else { 10089 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 10090 AST_LIST_UNLOCK(&users); 10091 return CLI_FAILURE; 10092 } 10093 } 10094 AST_LIST_TRAVERSE(&users, vmu, list) { 10095 int newmsgs = 0, oldmsgs = 0; 10096 char count[12], tmp[256] = ""; 10097 10098 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 10099 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 10100 inboxcount(tmp, &newmsgs, &oldmsgs); 10101 snprintf(count, sizeof(count), "%d", newmsgs); 10102 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 10103 users_counter++; 10104 } 10105 } 10106 AST_LIST_UNLOCK(&users); 10107 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 10108 return CLI_SUCCESS; 10109 }
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 10112 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.
10113 { 10114 struct vm_zone *zone; 10115 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 10116 char *res = CLI_SUCCESS; 10117 10118 switch (cmd) { 10119 case CLI_INIT: 10120 e->command = "voicemail show zones"; 10121 e->usage = 10122 "Usage: voicemail show zones\n" 10123 " Lists zone message formats\n"; 10124 return NULL; 10125 case CLI_GENERATE: 10126 return NULL; 10127 } 10128 10129 if (a->argc != 3) 10130 return CLI_SHOWUSAGE; 10131 10132 AST_LIST_LOCK(&zones); 10133 if (!AST_LIST_EMPTY(&zones)) { 10134 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 10135 AST_LIST_TRAVERSE(&zones, zone, list) { 10136 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 10137 } 10138 } else { 10139 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 10140 res = CLI_FAILURE; 10141 } 10142 AST_LIST_UNLOCK(&zones); 10143 10144 return res; 10145 }
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 4906 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
04907 { 04908 char tmp[256], *tmp2 = tmp, *box, *context; 04909 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04910 if (ast_strlen_zero(folder)) { 04911 folder = "INBOX"; 04912 } 04913 while ((box = strsep(&tmp2, ",&"))) { 04914 if ((context = strchr(box, '@'))) 04915 *context++ = '\0'; 04916 else 04917 context = "default"; 04918 if (__has_voicemail(context, box, folder, 1)) 04919 return 1; 04920 /* If we are checking INBOX, we should check Urgent as well */ 04921 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 04922 return 1; 04923 } 04924 } 04925 return 0; 04926 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 4988 of file app_voicemail.c.
References inboxcount2().
Referenced by handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
04989 { 04990 int urgentmsgs = 0; 04991 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 04992 if (newmsgs) { 04993 *newmsgs += urgentmsgs; 04994 } 04995 return res; 04996 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 4929 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by append_mailbox(), inboxcount(), load_module(), poll_subscribed_mailbox(), and run_externnotify().
04930 { 04931 char tmp[256]; 04932 char *context; 04933 04934 /* If no mailbox, return immediately */ 04935 if (ast_strlen_zero(mailbox)) 04936 return 0; 04937 04938 if (newmsgs) 04939 *newmsgs = 0; 04940 if (oldmsgs) 04941 *oldmsgs = 0; 04942 if (urgentmsgs) 04943 *urgentmsgs = 0; 04944 04945 if (strchr(mailbox, ',')) { 04946 int tmpnew, tmpold, tmpurgent; 04947 char *mb, *cur; 04948 04949 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04950 mb = tmp; 04951 while ((cur = strsep(&mb, ", "))) { 04952 if (!ast_strlen_zero(cur)) { 04953 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 04954 return -1; 04955 else { 04956 if (newmsgs) 04957 *newmsgs += tmpnew; 04958 if (oldmsgs) 04959 *oldmsgs += tmpold; 04960 if (urgentmsgs) 04961 *urgentmsgs += tmpurgent; 04962 } 04963 } 04964 } 04965 return 0; 04966 } 04967 04968 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04969 04970 if ((context = strchr(tmp, '@'))) 04971 *context++ = '\0'; 04972 else 04973 context = "default"; 04974 04975 if (newmsgs) 04976 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 04977 if (oldmsgs) 04978 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 04979 if (urgentmsgs) 04980 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 04981 04982 return 0; 04983 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 3762 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(), and sip_addheader().
03763 { 03764 int l; 03765 03766 if (bio->ateof) 03767 return 0; 03768 03769 if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) { 03770 if (ferror(fi)) 03771 return -1; 03772 03773 bio->ateof = 1; 03774 return 0; 03775 } 03776 03777 bio->iolen= l; 03778 bio->iocp= 0; 03779 03780 return 1; 03781 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 3786 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
03787 { 03788 if (bio->iocp>=bio->iolen) { 03789 if (!inbuf(bio, fi)) 03790 return EOF; 03791 } 03792 03793 return bio->iobuf[bio->iocp++]; 03794 }
static int inprocess_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 740 of file app_voicemail.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
Referenced by load_module().
00741 { 00742 struct inprocess *i = obj, *j = arg; 00743 if (!strcmp(i->mailbox, j->mailbox)) { 00744 return 0; 00745 } 00746 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 00747 }
static int inprocess_count | ( | const char * | context, | |
const char * | mailbox, | |||
int | delta | |||
) | [static] |
Definition at line 749 of file app_voicemail.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_atomic_fetchadd_int(), inprocess::count, and inprocess_container.
Referenced by copy_message(), and leave_voicemail().
00750 { 00751 struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00752 arg->context = arg->mailbox + strlen(mailbox) + 1; 00753 strcpy(arg->mailbox, mailbox); /* SAFE */ 00754 strcpy(arg->context, context); /* SAFE */ 00755 ao2_lock(inprocess_container); 00756 if ((i = ao2_find(inprocess_container, arg, 0))) { 00757 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00758 ao2_unlock(inprocess_container); 00759 ao2_ref(i, -1); 00760 return ret; 00761 } 00762 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00763 ao2_unlock(inprocess_container); 00764 return 0; 00765 } 00766 i->context = i->mailbox + strlen(mailbox) + 1; 00767 strcpy(i->mailbox, mailbox); /* SAFE */ 00768 strcpy(i->context, context); /* SAFE */ 00769 i->count = delta; 00770 ao2_link(inprocess_container, i); 00771 ao2_unlock(inprocess_container); 00772 ao2_ref(i, -1); 00773 return 0; 00774 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 734 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 4536 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), chan, create_dirpath(), DISPOSE, ast_channel::language, and RETRIEVE.
04537 { 04538 int res; 04539 char fn[PATH_MAX]; 04540 char dest[PATH_MAX]; 04541 04542 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04543 04544 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04545 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04546 return -1; 04547 } 04548 04549 RETRIEVE(fn, -1, ext, context); 04550 if (ast_fileexists(fn, NULL, NULL) > 0) { 04551 res = ast_stream_and_wait(chan, fn, ecodes); 04552 if (res) { 04553 DISPOSE(fn, -1); 04554 return res; 04555 } 04556 } else { 04557 /* Dispose just in case */ 04558 DISPOSE(fn, -1); 04559 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04560 if (res) 04561 return res; 04562 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04563 if (res) 04564 return res; 04565 } 04566 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04567 return res; 04568 }
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 1117 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by load_config().
01118 { 01119 int i; 01120 char *local_key = ast_strdupa(key); 01121 01122 for (i = 0; i < strlen(key); ++i) { 01123 if (!strchr(VALID_DTMF, *local_key)) { 01124 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01125 return 0; 01126 } 01127 local_key++; 01128 } 01129 return 1; 01130 }
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 3588 of file app_voicemail.c.
References map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by copy_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
03589 { 03590 int x; 03591 unsigned char map[MAXMSGLIMIT] = ""; 03592 DIR *msgdir; 03593 struct dirent *msgdirent; 03594 int msgdirint; 03595 03596 /* Reading the entire directory into a file map scales better than 03597 * doing a stat repeatedly on a predicted sequence. I suspect this 03598 * is partially due to stat(2) internally doing a readdir(2) itself to 03599 * find each file. */ 03600 if (!(msgdir = opendir(dir))) { 03601 return -1; 03602 } 03603 03604 while ((msgdirent = readdir(msgdir))) { 03605 if (sscanf(msgdirent->d_name, "msg%30d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) 03606 map[msgdirint] = 1; 03607 } 03608 closedir(msgdir); 03609 03610 for (x = 0; x < vmu->maxmsg; x++) { 03611 if (map[x] == 0) 03612 break; 03613 } 03614 03615 return x - 1; 03616 }
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 5061 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer, ast_str_create(), ast_str_set(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verbose, ast_waitstream(), chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_vm_user::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, ast_vm_user::exit, leave_vm_options::exitcontext, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), inprocess_count(), INTRO, invent_message(), ast_channel::language, last_message_index(), ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_channel::name, vm_state::newmessages, notify_new_message(), OPERATOR_EXIT, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RENAME, RETRIEVE, S_OR, SENTINEL, STORE, strsep(), transfer, VERBOSE_PREFIX_3, vm_lock_path(), VM_OPERATOR, and VOICEMAIL_FILE_MODE.
05062 { 05063 #ifdef IMAP_STORAGE 05064 int newmsgs, oldmsgs; 05065 #else 05066 char urgdir[PATH_MAX]; 05067 #endif 05068 char txtfile[PATH_MAX]; 05069 char tmptxtfile[PATH_MAX]; 05070 struct vm_state *vms = NULL; 05071 char callerid[256]; 05072 FILE *txt; 05073 char date[256]; 05074 int txtdes; 05075 int res = 0; 05076 int msgnum; 05077 int duration = 0; 05078 int ausemacro = 0; 05079 int ousemacro = 0; 05080 int ouseexten = 0; 05081 int rtmsgid = 0; 05082 char tmpid[16]; 05083 char tmpdur[16]; 05084 char priority[16]; 05085 char origtime[16]; 05086 char dir[PATH_MAX]; 05087 char tmpdir[PATH_MAX]; 05088 char fn[PATH_MAX]; 05089 char prefile[PATH_MAX] = ""; 05090 char tempfile[PATH_MAX] = ""; 05091 char ext_context[256] = ""; 05092 char fmt[80]; 05093 char *context; 05094 char ecodes[17] = "#"; 05095 struct ast_str *tmp = ast_str_create(16); 05096 char *tmpptr; 05097 struct ast_vm_user *vmu; 05098 struct ast_vm_user svm; 05099 const char *category = NULL; 05100 const char *code; 05101 const char *alldtmf = "0123456789ABCD*#"; 05102 char flag[80]; 05103 05104 ast_str_set(&tmp, 0, "%s", ext); 05105 ext = ast_str_buffer(tmp); 05106 if ((context = strchr(ext, '@'))) { 05107 *context++ = '\0'; 05108 tmpptr = strchr(context, '&'); 05109 } else { 05110 tmpptr = strchr(ext, '&'); 05111 } 05112 05113 if (tmpptr) 05114 *tmpptr++ = '\0'; 05115 05116 ast_channel_lock(chan); 05117 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05118 category = ast_strdupa(category); 05119 } 05120 ast_channel_unlock(chan); 05121 05122 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05123 ast_copy_string(flag, "Urgent", sizeof(flag)); 05124 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05125 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05126 } else { 05127 flag[0] = '\0'; 05128 } 05129 05130 ast_debug(3, "Before find_user\n"); 05131 if (!(vmu = find_user(&svm, context, ext))) { 05132 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05133 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05134 ast_free(tmp); 05135 return res; 05136 } 05137 /* Setup pre-file if appropriate */ 05138 if (strcmp(vmu->context, "default")) 05139 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05140 else 05141 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05142 05143 /* Set the path to the prefile. Will be one of 05144 VM_SPOOL_DIRcontext/ext/busy 05145 VM_SPOOL_DIRcontext/ext/unavail 05146 Depending on the flag set in options. 05147 */ 05148 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05149 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05150 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05151 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05152 } 05153 /* Set the path to the tmpfile as 05154 VM_SPOOL_DIR/context/ext/temp 05155 and attempt to create the folder structure. 05156 */ 05157 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05158 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05159 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05160 ast_free(tmp); 05161 return -1; 05162 } 05163 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05164 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05165 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05166 05167 DISPOSE(tempfile, -1); 05168 /* It's easier just to try to make it than to check for its existence */ 05169 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05170 05171 /* Check current or macro-calling context for special extensions */ 05172 if (ast_test_flag(vmu, VM_OPERATOR)) { 05173 if (!ast_strlen_zero(vmu->exit)) { 05174 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 05175 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05176 ouseexten = 1; 05177 } 05178 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 05179 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05180 ouseexten = 1; 05181 } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 05182 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05183 ousemacro = 1; 05184 } 05185 } 05186 05187 if (!ast_strlen_zero(vmu->exit)) { 05188 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 05189 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05190 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 05191 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05192 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 05193 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05194 ausemacro = 1; 05195 } 05196 05197 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05198 for (code = alldtmf; *code; code++) { 05199 char e[2] = ""; 05200 e[0] = *code; 05201 if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) 05202 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05203 } 05204 } 05205 05206 /* Play the beginning intro if desired */ 05207 if (!ast_strlen_zero(prefile)) { 05208 #ifdef ODBC_STORAGE 05209 int success = 05210 #endif 05211 RETRIEVE(prefile, -1, ext, context); 05212 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05213 if (ast_streamfile(chan, prefile, chan->language) > -1) 05214 res = ast_waitstream(chan, ecodes); 05215 #ifdef ODBC_STORAGE 05216 if (success == -1) { 05217 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05218 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05219 store_file(prefile, vmu->mailbox, vmu->context, -1); 05220 } 05221 #endif 05222 } else { 05223 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05224 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05225 } 05226 DISPOSE(prefile, -1); 05227 if (res < 0) { 05228 ast_debug(1, "Hang up during prefile playback\n"); 05229 free_user(vmu); 05230 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05231 ast_free(tmp); 05232 return -1; 05233 } 05234 } 05235 if (res == '#') { 05236 /* On a '#' we skip the instructions */ 05237 ast_set_flag(options, OPT_SILENT); 05238 res = 0; 05239 } 05240 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05241 res = ast_stream_and_wait(chan, INTRO, ecodes); 05242 if (res == '#') { 05243 ast_set_flag(options, OPT_SILENT); 05244 res = 0; 05245 } 05246 } 05247 if (res > 0) 05248 ast_stopstream(chan); 05249 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05250 other than the operator -- an automated attendant or mailbox login for example */ 05251 if (res == '*') { 05252 chan->exten[0] = 'a'; 05253 chan->exten[1] = '\0'; 05254 if (!ast_strlen_zero(vmu->exit)) { 05255 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05256 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05257 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05258 } 05259 chan->priority = 0; 05260 free_user(vmu); 05261 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05262 ast_free(tmp); 05263 return 0; 05264 } 05265 05266 /* Check for a '0' here */ 05267 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05268 transfer: 05269 if (ouseexten || ousemacro) { 05270 chan->exten[0] = 'o'; 05271 chan->exten[1] = '\0'; 05272 if (!ast_strlen_zero(vmu->exit)) { 05273 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05274 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05275 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05276 } 05277 ast_play_and_wait(chan, "transfer"); 05278 chan->priority = 0; 05279 free_user(vmu); 05280 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05281 } 05282 ast_free(tmp); 05283 return OPERATOR_EXIT; 05284 } 05285 05286 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05287 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05288 if (!ast_strlen_zero(options->exitcontext)) 05289 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05290 free_user(vmu); 05291 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05292 ast_free(tmp); 05293 return res; 05294 } 05295 05296 if (res < 0) { 05297 free_user(vmu); 05298 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05299 ast_free(tmp); 05300 return -1; 05301 } 05302 /* The meat of recording the message... All the announcements and beeps have been played*/ 05303 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05304 if (!ast_strlen_zero(fmt)) { 05305 msgnum = 0; 05306 05307 #ifdef IMAP_STORAGE 05308 /* Is ext a mailbox? */ 05309 /* must open stream for this user to get info! */ 05310 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05311 if (res < 0) { 05312 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05313 ast_free(tmp); 05314 return -1; 05315 } 05316 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05317 /* It is possible under certain circumstances that inboxcount did not 05318 * create a vm_state when it was needed. This is a catchall which will 05319 * rarely be used. 05320 */ 05321 if (!(vms = create_vm_state_from_user(vmu))) { 05322 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05323 ast_free(tmp); 05324 return -1; 05325 } 05326 } 05327 vms->newmessages++; 05328 05329 /* here is a big difference! We add one to it later */ 05330 msgnum = newmsgs + oldmsgs; 05331 ast_debug(3, "Messagecount set to %d\n",msgnum); 05332 snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05333 /* set variable for compatibility */ 05334 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05335 05336 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05337 goto leave_vm_out; 05338 } 05339 #else 05340 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05341 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05342 if (!res) 05343 res = ast_waitstream(chan, ""); 05344 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05345 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05346 inprocess_count(vmu->mailbox, vmu->context, -1); 05347 goto leave_vm_out; 05348 } 05349 05350 #endif 05351 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05352 txtdes = mkstemp(tmptxtfile); 05353 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05354 if (txtdes < 0) { 05355 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05356 if (!res) 05357 res = ast_waitstream(chan, ""); 05358 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05359 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05360 inprocess_count(vmu->mailbox, vmu->context, -1); 05361 goto leave_vm_out; 05362 } 05363 05364 /* Now play the beep once we have the message number for our next message. */ 05365 if (res >= 0) { 05366 /* Unless we're *really* silent, try to send the beep */ 05367 res = ast_stream_and_wait(chan, "beep", ""); 05368 } 05369 05370 /* Store information in real-time storage */ 05371 if (ast_check_realtime("voicemail_data")) { 05372 snprintf(priority, sizeof(priority), "%d", chan->priority); 05373 snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL)); 05374 get_date(date, sizeof(date)); 05375 rtmsgid = ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", S_OR(category,""), SENTINEL); 05376 } 05377 05378 /* Store information */ 05379 txt = fdopen(txtdes, "w+"); 05380 if (txt) { 05381 get_date(date, sizeof(date)); 05382 fprintf(txt, 05383 ";\n" 05384 "; Message Information file\n" 05385 ";\n" 05386 "[message]\n" 05387 "origmailbox=%s\n" 05388 "context=%s\n" 05389 "macrocontext=%s\n" 05390 "exten=%s\n" 05391 "priority=%d\n" 05392 "callerchan=%s\n" 05393 "callerid=%s\n" 05394 "origdate=%s\n" 05395 "origtime=%ld\n" 05396 "category=%s\n", 05397 ext, 05398 chan->context, 05399 chan->macrocontext, 05400 chan->exten, 05401 chan->priority, 05402 chan->name, 05403 ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"), 05404 date, (long)time(NULL), 05405 category ? category : ""); 05406 } else { 05407 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05408 inprocess_count(vmu->mailbox, vmu->context, -1); 05409 if (ast_check_realtime("voicemail_data")) { 05410 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05411 } 05412 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05413 goto leave_vm_out; 05414 } 05415 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05416 05417 if (txt) { 05418 fprintf(txt, "flag=%s\n", flag); 05419 if (duration < vmminsecs) { 05420 fclose(txt); 05421 if (option_verbose > 2) 05422 ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs); 05423 ast_filedelete(tmptxtfile, NULL); 05424 unlink(tmptxtfile); 05425 if (ast_check_realtime("voicemail_data")) { 05426 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05427 ast_destroy_realtime("voicemail_data", "id", tmpid, SENTINEL); 05428 } 05429 inprocess_count(vmu->mailbox, vmu->context, -1); 05430 } else { 05431 fprintf(txt, "duration=%d\n", duration); 05432 fclose(txt); 05433 if (vm_lock_path(dir)) { 05434 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05435 /* Delete files */ 05436 ast_filedelete(tmptxtfile, NULL); 05437 unlink(tmptxtfile); 05438 inprocess_count(vmu->mailbox, vmu->context, -1); 05439 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05440 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05441 unlink(tmptxtfile); 05442 ast_unlock_path(dir); 05443 inprocess_count(vmu->mailbox, vmu->context, -1); 05444 if (ast_check_realtime("voicemail_data")) { 05445 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05446 ast_destroy_realtime("voicemail_data", "id", tmpid, SENTINEL); 05447 } 05448 } else { 05449 #ifndef IMAP_STORAGE 05450 msgnum = last_message_index(vmu, dir) + 1; 05451 #endif 05452 make_file(fn, sizeof(fn), dir, msgnum); 05453 05454 /* assign a variable with the name of the voicemail file */ 05455 #ifndef IMAP_STORAGE 05456 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05457 #else 05458 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05459 #endif 05460 05461 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05462 ast_filerename(tmptxtfile, fn, NULL); 05463 rename(tmptxtfile, txtfile); 05464 inprocess_count(vmu->mailbox, vmu->context, -1); 05465 05466 /* Properly set permissions on voicemail text descriptor file. 05467 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05468 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05469 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05470 05471 ast_unlock_path(dir); 05472 if (ast_check_realtime("voicemail_data")) { 05473 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05474 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05475 ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, SENTINEL); 05476 } 05477 /* We must store the file first, before copying the message, because 05478 * ODBC storage does the entire copy with SQL. 05479 */ 05480 if (ast_fileexists(fn, NULL, NULL) > 0) { 05481 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05482 } 05483 05484 /* Are there to be more recipients of this message? */ 05485 while (tmpptr) { 05486 struct ast_vm_user recipu, *recip; 05487 char *exten, *cntx; 05488 05489 exten = strsep(&tmpptr, "&"); 05490 cntx = strchr(exten, '@'); 05491 if (cntx) { 05492 *cntx = '\0'; 05493 cntx++; 05494 } 05495 if ((recip = find_user(&recipu, cntx, exten))) { 05496 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05497 free_user(recip); 05498 } 05499 } 05500 #ifndef IMAP_STORAGE 05501 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05502 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05503 char sfn[PATH_MAX]; 05504 char dfn[PATH_MAX]; 05505 int x; 05506 /* It's easier just to try to make it than to check for its existence */ 05507 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05508 x = last_message_index(vmu, urgdir) + 1; 05509 make_file(sfn, sizeof(sfn), dir, msgnum); 05510 make_file(dfn, sizeof(dfn), urgdir, x); 05511 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 05512 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05513 /* Notification must happen for this new message in Urgent folder, not INBOX */ 05514 ast_copy_string(fn, dfn, sizeof(fn)); 05515 msgnum = x; 05516 } 05517 #endif 05518 /* Notification needs to happen after the copy, though. */ 05519 if (ast_fileexists(fn, NULL, NULL)) { 05520 #ifdef IMAP_STORAGE 05521 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05522 #else 05523 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05524 #endif 05525 } 05526 05527 /* Disposal needs to happen after the optional move and copy */ 05528 if (ast_fileexists(fn, NULL, NULL)) { 05529 DISPOSE(dir, msgnum); 05530 } 05531 } 05532 } 05533 } else { 05534 inprocess_count(vmu->mailbox, vmu->context, -1); 05535 } 05536 if (res == '0') { 05537 goto transfer; 05538 } else if (res > 0) 05539 res = 0; 05540 05541 if (duration < vmminsecs) 05542 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05543 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05544 else 05545 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05546 } else 05547 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 05548 leave_vm_out: 05549 free_user(vmu); 05550 05551 #ifdef IMAP_STORAGE 05552 /* expunge message - use UID Expunge if supported on IMAP server*/ 05553 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n",expungeonhangup); 05554 if (expungeonhangup == 1) { 05555 ast_mutex_lock(&vms->lock); 05556 #ifdef HAVE_IMAP_TK2006 05557 if (LEVELUIDPLUS (vms->mailstream)) { 05558 mail_expunge_full(vms->mailstream,NIL,EX_UID); 05559 } else 05560 #endif 05561 mail_expunge(vms->mailstream); 05562 ast_mutex_unlock(&vms->lock); 05563 } 05564 #endif 05565 05566 ast_free(tmp); 05567 return res; 05568 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 10536 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_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, pagerbody, pagerfromstring, pagersubject, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, 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.
10537 { 10538 struct ast_vm_user *current; 10539 struct ast_config *cfg, *ucfg; 10540 char *cat; 10541 struct ast_variable *var; 10542 const char *val; 10543 char *q, *stringp, *tmp; 10544 int x; 10545 int tmpadsi[4]; 10546 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 10547 10548 ast_unload_realtime("voicemail"); 10549 ast_unload_realtime("voicemail_data"); 10550 10551 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 10552 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) 10553 return 0; 10554 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10555 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 10556 } else { 10557 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10558 ucfg = ast_config_load("users.conf", config_flags); 10559 } 10560 #ifdef IMAP_STORAGE 10561 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 10562 #endif 10563 /* set audio control prompts */ 10564 strcpy(listen_control_forward_key,DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 10565 strcpy(listen_control_reverse_key,DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 10566 strcpy(listen_control_pause_key,DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 10567 strcpy(listen_control_restart_key,DEFAULT_LISTEN_CONTROL_RESTART_KEY); 10568 strcpy(listen_control_stop_key,DEFAULT_LISTEN_CONTROL_STOP_KEY); 10569 10570 /* Free all the users structure */ 10571 free_vm_users(); 10572 10573 /* Free all the zones structure */ 10574 free_vm_zones(); 10575 10576 AST_LIST_LOCK(&users); 10577 10578 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 10579 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 10580 10581 if (cfg) { 10582 /* General settings */ 10583 10584 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 10585 val = "default"; 10586 ast_copy_string(userscontext, val, sizeof(userscontext)); 10587 /* Attach voice message to mail message ? */ 10588 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 10589 val = "yes"; 10590 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 10591 10592 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 10593 val = "no"; 10594 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 10595 10596 volgain = 0.0; 10597 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 10598 sscanf(val, "%30lf", &volgain); 10599 10600 #ifdef ODBC_STORAGE 10601 strcpy(odbc_database, "asterisk"); 10602 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 10603 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 10604 } 10605 strcpy(odbc_table, "voicemessages"); 10606 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 10607 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 10608 } 10609 #endif 10610 /* Mail command */ 10611 strcpy(mailcmd, SENDMAIL); 10612 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 10613 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 10614 10615 maxsilence = 0; 10616 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 10617 maxsilence = atoi(val); 10618 if (maxsilence > 0) 10619 maxsilence *= 1000; 10620 } 10621 10622 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 10623 maxmsg = MAXMSG; 10624 } else { 10625 maxmsg = atoi(val); 10626 if (maxmsg <= 0) { 10627 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 10628 maxmsg = MAXMSG; 10629 } else if (maxmsg > MAXMSGLIMIT) { 10630 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10631 maxmsg = MAXMSGLIMIT; 10632 } 10633 } 10634 10635 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 10636 maxdeletedmsg = 0; 10637 } else { 10638 if (sscanf(val, "%30d", &x) == 1) 10639 maxdeletedmsg = x; 10640 else if (ast_true(val)) 10641 maxdeletedmsg = MAXMSG; 10642 else 10643 maxdeletedmsg = 0; 10644 10645 if (maxdeletedmsg < 0) { 10646 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 10647 maxdeletedmsg = MAXMSG; 10648 } else if (maxdeletedmsg > MAXMSGLIMIT) { 10649 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10650 maxdeletedmsg = MAXMSGLIMIT; 10651 } 10652 } 10653 10654 /* Load date format config for voicemail mail */ 10655 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 10656 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 10657 } 10658 10659 /* External password changing command */ 10660 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 10661 ast_copy_string(ext_pass_cmd,val,sizeof(ext_pass_cmd)); 10662 pwdchange = PWDCHANGE_EXTERNAL; 10663 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 10664 ast_copy_string(ext_pass_cmd,val,sizeof(ext_pass_cmd)); 10665 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 10666 } 10667 10668 /* External password validation command */ 10669 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 10670 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 10671 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 10672 } 10673 10674 #ifdef IMAP_STORAGE 10675 /* IMAP server address */ 10676 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 10677 ast_copy_string(imapserver, val, sizeof(imapserver)); 10678 } else { 10679 ast_copy_string(imapserver,"localhost", sizeof(imapserver)); 10680 } 10681 /* IMAP server port */ 10682 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 10683 ast_copy_string(imapport, val, sizeof(imapport)); 10684 } else { 10685 ast_copy_string(imapport,"143", sizeof(imapport)); 10686 } 10687 /* IMAP server flags */ 10688 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 10689 ast_copy_string(imapflags, val, sizeof(imapflags)); 10690 } 10691 /* IMAP server master username */ 10692 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 10693 ast_copy_string(authuser, val, sizeof(authuser)); 10694 } 10695 /* IMAP server master password */ 10696 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 10697 ast_copy_string(authpassword, val, sizeof(authpassword)); 10698 } 10699 /* Expunge on exit */ 10700 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 10701 if (ast_false(val)) 10702 expungeonhangup = 0; 10703 else 10704 expungeonhangup = 1; 10705 } else { 10706 expungeonhangup = 1; 10707 } 10708 /* IMAP voicemail folder */ 10709 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 10710 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 10711 } else { 10712 ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder)); 10713 } 10714 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 10715 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 10716 } 10717 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 10718 imapgreetings = ast_true(val); 10719 } else { 10720 imapgreetings = 0; 10721 } 10722 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 10723 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 10724 } else { 10725 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 10726 } 10727 10728 /* There is some very unorthodox casting done here. This is due 10729 * to the way c-client handles the argument passed in. It expects a 10730 * void pointer and casts the pointer directly to a long without 10731 * first dereferencing it. */ 10732 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 10733 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 10734 } else { 10735 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 10736 } 10737 10738 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 10739 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 10740 } else { 10741 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 10742 } 10743 10744 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 10745 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 10746 } else { 10747 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 10748 } 10749 10750 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 10751 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 10752 } else { 10753 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 10754 } 10755 10756 /* Increment configuration version */ 10757 imapversion++; 10758 #endif 10759 /* External voicemail notify application */ 10760 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 10761 ast_copy_string(externnotify, val, sizeof(externnotify)); 10762 ast_debug(1, "found externnotify: %s\n", externnotify); 10763 } else { 10764 externnotify[0] = '\0'; 10765 } 10766 10767 /* SMDI voicemail notification */ 10768 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 10769 ast_debug(1, "Enabled SMDI voicemail notification\n"); 10770 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 10771 smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find(val) : NULL; 10772 } else { 10773 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 10774 smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find("/dev/ttyS0") : NULL; 10775 } 10776 if (!smdi_iface) { 10777 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 10778 } 10779 } 10780 10781 /* Silence treshold */ 10782 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 10783 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 10784 silencethreshold = atoi(val); 10785 10786 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 10787 val = ASTERISK_USERNAME; 10788 ast_copy_string(serveremail, val, sizeof(serveremail)); 10789 10790 vmmaxsecs = 0; 10791 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 10792 if (sscanf(val, "%30d", &x) == 1) { 10793 vmmaxsecs = x; 10794 } else { 10795 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10796 } 10797 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 10798 static int maxmessage_deprecate = 0; 10799 if (maxmessage_deprecate == 0) { 10800 maxmessage_deprecate = 1; 10801 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 10802 } 10803 if (sscanf(val, "%30d", &x) == 1) { 10804 vmmaxsecs = x; 10805 } else { 10806 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10807 } 10808 } 10809 10810 vmminsecs = 0; 10811 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 10812 if (sscanf(val, "%30d", &x) == 1) { 10813 vmminsecs = x; 10814 if (maxsilence / 1000 >= vmminsecs) { 10815 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 10816 } 10817 } else { 10818 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10819 } 10820 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 10821 static int maxmessage_deprecate = 0; 10822 if (maxmessage_deprecate == 0) { 10823 maxmessage_deprecate = 1; 10824 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 10825 } 10826 if (sscanf(val, "%30d", &x) == 1) { 10827 vmminsecs = x; 10828 if (maxsilence / 1000 >= vmminsecs) { 10829 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 10830 } 10831 } else { 10832 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10833 } 10834 } 10835 10836 val = ast_variable_retrieve(cfg, "general", "format"); 10837 if (!val) { 10838 val = "wav"; 10839 } else { 10840 tmp = ast_strdupa(val); 10841 val = ast_format_str_reduce(tmp); 10842 if (!val) { 10843 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 10844 val = "wav"; 10845 } 10846 } 10847 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 10848 10849 skipms = 3000; 10850 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 10851 if (sscanf(val, "%30d", &x) == 1) { 10852 maxgreet = x; 10853 } else { 10854 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 10855 } 10856 } 10857 10858 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 10859 if (sscanf(val, "%30d", &x) == 1) { 10860 skipms = x; 10861 } else { 10862 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 10863 } 10864 } 10865 10866 maxlogins = 3; 10867 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 10868 if (sscanf(val, "%30d", &x) == 1) { 10869 maxlogins = x; 10870 } else { 10871 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 10872 } 10873 } 10874 10875 minpassword = MINPASSWORD; 10876 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 10877 if (sscanf(val, "%30d", &x) == 1) { 10878 minpassword = x; 10879 } else { 10880 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 10881 } 10882 } 10883 10884 /* Force new user to record name ? */ 10885 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 10886 val = "no"; 10887 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 10888 10889 /* Force new user to record greetings ? */ 10890 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 10891 val = "no"; 10892 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 10893 10894 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 10895 ast_debug(1, "VM_CID Internal context string: %s\n", val); 10896 stringp = ast_strdupa(val); 10897 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 10898 if (!ast_strlen_zero(stringp)) { 10899 q = strsep(&stringp, ","); 10900 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 10901 q++; 10902 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 10903 ast_debug(1,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 10904 } else { 10905 cidinternalcontexts[x][0] = '\0'; 10906 } 10907 } 10908 } 10909 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 10910 ast_debug(1,"VM Review Option disabled globally\n"); 10911 val = "no"; 10912 } 10913 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 10914 10915 /* Temporary greeting reminder */ 10916 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 10917 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 10918 val = "no"; 10919 } else { 10920 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 10921 } 10922 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 10923 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 10924 ast_debug(1, "VM next message wrap disabled globally\n"); 10925 val = "no"; 10926 } 10927 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 10928 10929 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 10930 ast_debug(1,"VM Operator break disabled globally\n"); 10931 val = "no"; 10932 } 10933 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 10934 10935 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 10936 ast_debug(1,"VM CID Info before msg disabled globally\n"); 10937 val = "no"; 10938 } 10939 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 10940 10941 if (!(val = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){ 10942 ast_debug(1,"Send Voicemail msg disabled globally\n"); 10943 val = "no"; 10944 } 10945 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 10946 10947 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 10948 ast_debug(1,"ENVELOPE before msg enabled globally\n"); 10949 val = "yes"; 10950 } 10951 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 10952 10953 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 10954 ast_debug(1,"Move Heard enabled globally\n"); 10955 val = "yes"; 10956 } 10957 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 10958 10959 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 10960 ast_debug(1,"Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 10961 val = "no"; 10962 } 10963 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 10964 10965 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 10966 ast_debug(1,"Duration info before msg enabled globally\n"); 10967 val = "yes"; 10968 } 10969 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 10970 10971 saydurationminfo = 2; 10972 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 10973 if (sscanf(val, "%30d", &x) == 1) { 10974 saydurationminfo = x; 10975 } else { 10976 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 10977 } 10978 } 10979 10980 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 10981 ast_debug(1,"We are not going to skip to the next msg after save/delete\n"); 10982 val = "no"; 10983 } 10984 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 10985 10986 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 10987 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 10988 ast_debug(1, "found dialout context: %s\n", dialcontext); 10989 } else { 10990 dialcontext[0] = '\0'; 10991 } 10992 10993 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 10994 ast_copy_string(callcontext, val, sizeof(callcontext)); 10995 ast_debug(1, "found callback context: %s\n", callcontext); 10996 } else { 10997 callcontext[0] = '\0'; 10998 } 10999 11000 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 11001 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 11002 ast_debug(1, "found operator context: %s\n", exitcontext); 11003 } else { 11004 exitcontext[0] = '\0'; 11005 } 11006 11007 /* load password sounds configuration */ 11008 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 11009 ast_copy_string(vm_password, val, sizeof(vm_password)); 11010 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 11011 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 11012 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 11013 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 11014 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 11015 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 11016 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 11017 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 11018 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 11019 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 11020 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 11021 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 11022 } 11023 /* load configurable audio prompts */ 11024 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 11025 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 11026 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 11027 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 11028 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 11029 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 11030 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 11031 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 11032 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 11033 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 11034 11035 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 11036 val = "no"; 11037 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 11038 11039 poll_freq = DEFAULT_POLL_FREQ; 11040 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 11041 if (sscanf(val, "%30u", &poll_freq) != 1) { 11042 poll_freq = DEFAULT_POLL_FREQ; 11043 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 11044 } 11045 } 11046 11047 poll_mailboxes = 0; 11048 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 11049 poll_mailboxes = ast_true(val); 11050 11051 if (ucfg) { 11052 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 11053 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 11054 continue; 11055 if ((current = find_or_create(userscontext, cat))) { 11056 populate_defaults(current); 11057 apply_options_full(current, ast_variable_browse(ucfg, cat)); 11058 ast_copy_string(current->context, userscontext, sizeof(current->context)); 11059 } 11060 } 11061 ast_config_destroy(ucfg); 11062 } 11063 cat = ast_category_browse(cfg, NULL); 11064 while (cat) { 11065 if (strcasecmp(cat, "general")) { 11066 var = ast_variable_browse(cfg, cat); 11067 if (strcasecmp(cat, "zonemessages")) { 11068 /* Process mailboxes in this context */ 11069 while (var) { 11070 append_mailbox(cat, var->name, var->value); 11071 var = var->next; 11072 } 11073 } else { 11074 /* Timezones in this context */ 11075 while (var) { 11076 struct vm_zone *z; 11077 if ((z = ast_malloc(sizeof(*z)))) { 11078 char *msg_format, *tzone; 11079 msg_format = ast_strdupa(var->value); 11080 tzone = strsep(&msg_format, "|"); 11081 if (msg_format) { 11082 ast_copy_string(z->name, var->name, sizeof(z->name)); 11083 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 11084 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 11085 AST_LIST_LOCK(&zones); 11086 AST_LIST_INSERT_HEAD(&zones, z, list); 11087 AST_LIST_UNLOCK(&zones); 11088 } else { 11089 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 11090 ast_free(z); 11091 } 11092 } else { 11093 AST_LIST_UNLOCK(&users); 11094 ast_config_destroy(cfg); 11095 return -1; 11096 } 11097 var = var->next; 11098 } 11099 } 11100 } 11101 cat = ast_category_browse(cfg, cat); 11102 } 11103 memset(fromstring, 0, sizeof(fromstring)); 11104 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 11105 strcpy(charset, "ISO-8859-1"); 11106 if (emailbody) { 11107 ast_free(emailbody); 11108 emailbody = NULL; 11109 } 11110 if (emailsubject) { 11111 ast_free(emailsubject); 11112 emailsubject = NULL; 11113 } 11114 if (pagerbody) { 11115 ast_free(pagerbody); 11116 pagerbody = NULL; 11117 } 11118 if (pagersubject) { 11119 ast_free(pagersubject); 11120 pagersubject = NULL; 11121 } 11122 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 11123 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 11124 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 11125 ast_copy_string(fromstring, val, sizeof(fromstring)); 11126 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 11127 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 11128 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 11129 ast_copy_string(charset, val, sizeof(charset)); 11130 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 11131 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 11132 for (x = 0; x < 4; x++) { 11133 memcpy(&adsifdn[x], &tmpadsi[x], 1); 11134 } 11135 } 11136 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 11137 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 11138 for (x = 0; x < 4; x++) { 11139 memcpy(&adsisec[x], &tmpadsi[x], 1); 11140 } 11141 } 11142 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 11143 if (atoi(val)) { 11144 adsiver = atoi(val); 11145 } 11146 } 11147 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 11148 ast_copy_string(zonetag, val, sizeof(zonetag)); 11149 } 11150 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 11151 emailsubject = ast_strdup(val); 11152 } 11153 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 11154 emailbody = substitute_escapes(val); 11155 } 11156 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 11157 pagersubject = ast_strdup(val); 11158 } 11159 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 11160 pagerbody = substitute_escapes(val); 11161 } 11162 AST_LIST_UNLOCK(&users); 11163 ast_config_destroy(cfg); 11164 11165 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 11166 start_poll_thread(); 11167 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 11168 stop_poll_thread();; 11169 11170 return 0; 11171 } else { 11172 AST_LIST_UNLOCK(&users); 11173 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 11174 if (ucfg) 11175 ast_config_destroy(ucfg); 11176 return 0; 11177 } 11178 }
static int load_module | ( | void | ) | [static] |
Definition at line 11225 of file app_voicemail.c.
References ao2_container_alloc, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_install_vm_functions(), ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application, ast_taskprocessor_get(), 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_exec(), vm_execmain(), and vmauthenticate().
11226 { 11227 int res; 11228 my_umask = umask(0); 11229 umask(my_umask); 11230 11231 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 11232 return AST_MODULE_LOAD_DECLINE; 11233 } 11234 11235 /* compute the location of the voicemail spool directory */ 11236 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 11237 11238 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 11239 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 11240 } 11241 11242 if ((res = load_config(0))) 11243 return res; 11244 11245 res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm); 11246 res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain); 11247 res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists); 11248 res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate); 11249 res |= ast_custom_function_register(&mailbox_exists_acf); 11250 res |= ast_manager_register("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users, "List All Voicemail User Information"); 11251 if (res) 11252 return res; 11253 11254 ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 11255 11256 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 11257 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 11258 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 11259 11260 return res; 11261 }
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. |
Definition at line 1339 of file app_voicemail.c.
01340 { 01341 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01342 }
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. | |
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. | |
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. |
Definition at line 4073 of file app_voicemail.c.
References add_email_attachment(), ast_channel_alloc, ast_channel_free(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_localtime(), ast_log(), ast_random(), AST_STATE_DOWN, ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), chan, charset, check_mime(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, ast_vm_user::email, emailbody, emaildateformat, emailsubject, encode_mime_str(), ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, ast_channel::next, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04074 { 04075 char date[256]; 04076 char host[MAXHOSTNAMELEN] = ""; 04077 char who[256]; 04078 char bound[256]; 04079 char dur[256]; 04080 struct ast_tm tm; 04081 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04082 char *passdata = NULL, *passdata2; 04083 size_t len_passdata = 0, len_passdata2, tmplen; 04084 char *greeting_attachment; 04085 char filename[256]; 04086 04087 04088 /* One alloca for multiple fields */ 04089 len_passdata2 = strlen(vmu->fullname); 04090 if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) { 04091 len_passdata2 = tmplen; 04092 } 04093 if ((tmplen = strlen(fromstring)) > len_passdata2) { 04094 len_passdata2 = tmplen; 04095 } 04096 len_passdata2 = len_passdata2 * 3 + 200; 04097 passdata2 = alloca(len_passdata2); 04098 04099 if (cidnum) { 04100 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04101 } 04102 if (cidname) { 04103 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04104 } 04105 gethostname(host, sizeof(host) - 1); 04106 04107 if (strchr(srcemail, '@')) 04108 ast_copy_string(who, srcemail, sizeof(who)); 04109 else 04110 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04111 04112 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04113 if (greeting_attachment) 04114 *greeting_attachment++ = '\0'; 04115 04116 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04117 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04118 fprintf(p, "Date: %s" ENDL, date); 04119 04120 /* Set date format for voicemail mail */ 04121 ast_strftime(date, sizeof(date), emaildateformat, &tm); 04122 04123 if (!ast_strlen_zero(fromstring)) { 04124 struct ast_channel *ast; 04125 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04126 char *ptr; 04127 memset(passdata2, 0, len_passdata2); 04128 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category, flag); 04129 pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2); 04130 len_passdata = strlen(passdata2) * 3 + 300; 04131 passdata = alloca(len_passdata); 04132 if (check_mime(passdata2)) { 04133 int first_line = 1; 04134 encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3); 04135 while ((ptr = strchr(passdata, ' '))) { 04136 *ptr = '\0'; 04137 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata); 04138 first_line = 0; 04139 passdata = ptr + 1; 04140 } 04141 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who); 04142 } else { 04143 fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who); 04144 } 04145 ast_channel_free(ast); 04146 } else { 04147 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04148 } 04149 } else { 04150 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04151 } 04152 04153 if (check_mime(vmu->fullname)) { 04154 int first_line = 1; 04155 char *ptr; 04156 encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3); 04157 while ((ptr = strchr(passdata2, ' '))) { 04158 *ptr = '\0'; 04159 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2); 04160 first_line = 0; 04161 passdata2 = ptr + 1; 04162 } 04163 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email); 04164 } else { 04165 fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email); 04166 } 04167 if (!ast_strlen_zero(emailsubject)) { 04168 struct ast_channel *ast; 04169 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04170 int vmlen = strlen(emailsubject) * 3 + 200; 04171 /* Only allocate more space if the previous was not large enough */ 04172 if (vmlen > len_passdata) { 04173 passdata = alloca(vmlen); 04174 len_passdata = vmlen; 04175 } 04176 04177 memset(passdata, 0, len_passdata); 04178 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category, flag); 04179 pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata); 04180 if (check_mime(passdata)) { 04181 int first_line = 1; 04182 char *ptr; 04183 encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0); 04184 while ((ptr = strchr(passdata2, ' '))) { 04185 *ptr = '\0'; 04186 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 04187 first_line = 0; 04188 passdata2 = ptr + 1; 04189 } 04190 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 04191 } else { 04192 fprintf(p, "Subject: %s" ENDL, passdata); 04193 } 04194 ast_channel_free(ast); 04195 } else { 04196 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04197 } 04198 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04199 if (ast_strlen_zero(flag)) { 04200 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04201 } else { 04202 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04203 } 04204 } else { 04205 if (ast_strlen_zero(flag)) { 04206 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04207 } else { 04208 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04209 } 04210 } 04211 04212 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host); 04213 if (imap) { 04214 /* additional information needed for IMAP searching */ 04215 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04216 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04217 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04218 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04219 #ifdef IMAP_STORAGE 04220 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04221 #else 04222 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04223 #endif 04224 /* flag added for Urgent */ 04225 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04226 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04227 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04228 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04229 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04230 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04231 if (!ast_strlen_zero(category)) { 04232 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04233 } else { 04234 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04235 } 04236 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04237 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04238 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL)); 04239 } 04240 if (!ast_strlen_zero(cidnum)) { 04241 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04242 } 04243 if (!ast_strlen_zero(cidname)) { 04244 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04245 } 04246 fprintf(p, "MIME-Version: 1.0" ENDL); 04247 if (attach_user_voicemail) { 04248 /* Something unique. */ 04249 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random()); 04250 04251 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04252 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04253 fprintf(p, "--%s" ENDL, bound); 04254 } 04255 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04256 if (emailbody) { 04257 struct ast_channel *ast; 04258 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04259 char *passdata; 04260 int vmlen = strlen(emailbody)*3 + 200; 04261 passdata = alloca(vmlen); 04262 memset(passdata, 0, vmlen); 04263 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04264 pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen); 04265 #ifdef IMAP_STORAGE 04266 { 04267 /* Convert body to native line terminators for IMAP backend */ 04268 char *line = passdata, *next; 04269 do { 04270 /* Terminate line before outputting it to the file */ 04271 if ((next = strchr(line, '\n'))) { 04272 *next++ = '\0'; 04273 } 04274 fprintf(p, "%s" ENDL, line); 04275 line = next; 04276 } while (!ast_strlen_zero(line)); 04277 } 04278 #else 04279 fprintf(p, "%s" ENDL, passdata); 04280 #endif 04281 ast_channel_free(ast); 04282 } else 04283 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04284 } else if (msgnum > -1) { 04285 if (strcmp(vmu->mailbox, mailbox)) { 04286 /* Forwarded type */ 04287 struct ast_config *msg_cfg; 04288 const char *v; 04289 int inttime; 04290 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04291 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04292 /* Retrieve info from VM attribute file */ 04293 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04294 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04295 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04296 strcat(fromfile, ".txt"); 04297 } 04298 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04299 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04300 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04301 } 04302 04303 /* You might be tempted to do origdate, except that a) it's in the wrong 04304 * format, and b) it's missing for IMAP recordings. */ 04305 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04306 struct timeval tv = { inttime, }; 04307 struct ast_tm tm; 04308 ast_localtime(&tv, &tm, NULL); 04309 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 04310 } 04311 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04312 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04313 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04314 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04315 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04316 date, origcallerid, origdate); 04317 ast_config_destroy(msg_cfg); 04318 } else { 04319 goto plain_message; 04320 } 04321 } else { 04322 plain_message: 04323 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04324 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04325 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04326 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04327 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04328 } 04329 } else { 04330 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04331 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04332 } 04333 04334 if (imap || attach_user_voicemail) { 04335 if (!ast_strlen_zero(attach2)) { 04336 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04337 ast_debug(5, "creating second attachment filename %s\n", filename); 04338 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04339 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04340 ast_debug(5, "creating attachment filename %s\n", filename); 04341 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04342 } else { 04343 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04344 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04345 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04346 } 04347 } 04348 }
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. |
Definition at line 1354 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), save_to_folder(), vm_execmain(), and vm_forwardoptions().
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 10369 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, s, 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().
10370 { 10371 struct ast_vm_user *vmu = NULL; 10372 const char *id = astman_get_header(m, "ActionID"); 10373 char actionid[128] = ""; 10374 10375 if (!ast_strlen_zero(id)) 10376 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 10377 10378 AST_LIST_LOCK(&users); 10379 10380 if (AST_LIST_EMPTY(&users)) { 10381 astman_send_ack(s, m, "There are no voicemail users currently defined."); 10382 AST_LIST_UNLOCK(&users); 10383 return RESULT_SUCCESS; 10384 } 10385 10386 astman_send_ack(s, m, "Voicemail user list will follow"); 10387 10388 AST_LIST_TRAVERSE(&users, vmu, list) { 10389 char dirname[256]; 10390 10391 #ifdef IMAP_STORAGE 10392 int new, old; 10393 inboxcount(vmu->mailbox, &new, &old); 10394 #endif 10395 10396 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 10397 astman_append(s, 10398 "%s" 10399 "Event: VoicemailUserEntry\r\n" 10400 "VMContext: %s\r\n" 10401 "VoiceMailbox: %s\r\n" 10402 "Fullname: %s\r\n" 10403 "Email: %s\r\n" 10404 "Pager: %s\r\n" 10405 "ServerEmail: %s\r\n" 10406 "MailCommand: %s\r\n" 10407 "Language: %s\r\n" 10408 "TimeZone: %s\r\n" 10409 "Callback: %s\r\n" 10410 "Dialout: %s\r\n" 10411 "UniqueID: %s\r\n" 10412 "ExitContext: %s\r\n" 10413 "SayDurationMinimum: %d\r\n" 10414 "SayEnvelope: %s\r\n" 10415 "SayCID: %s\r\n" 10416 "AttachMessage: %s\r\n" 10417 "AttachmentFormat: %s\r\n" 10418 "DeleteMessage: %s\r\n" 10419 "VolumeGain: %.2f\r\n" 10420 "CanReview: %s\r\n" 10421 "CallOperator: %s\r\n" 10422 "MaxMessageCount: %d\r\n" 10423 "MaxMessageLength: %d\r\n" 10424 "NewMessageCount: %d\r\n" 10425 #ifdef IMAP_STORAGE 10426 "OldMessageCount: %d\r\n" 10427 "IMAPUser: %s\r\n" 10428 #endif 10429 "\r\n", 10430 actionid, 10431 vmu->context, 10432 vmu->mailbox, 10433 vmu->fullname, 10434 vmu->email, 10435 vmu->pager, 10436 vmu->serveremail, 10437 vmu->mailcmd, 10438 vmu->language, 10439 vmu->zonetag, 10440 vmu->callback, 10441 vmu->dialout, 10442 vmu->uniqueid, 10443 vmu->exit, 10444 vmu->saydurationm, 10445 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 10446 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 10447 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 10448 vmu->attachfmt, 10449 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 10450 vmu->volgain, 10451 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 10452 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 10453 vmu->maxmsg, 10454 vmu->maxsecs, 10455 #ifdef IMAP_STORAGE 10456 new, old, vmu->imapuser 10457 #else 10458 count_messages(vmu, dirname) 10459 #endif 10460 ); 10461 } 10462 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 10463 10464 AST_LIST_UNLOCK(&users); 10465 10466 return RESULT_SUCCESS; 10467 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 10203 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().
10204 { 10205 while (poll_thread_run) { 10206 struct timespec ts = { 0, }; 10207 struct timeval wait; 10208 10209 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 10210 ts.tv_sec = wait.tv_sec; 10211 ts.tv_nsec = wait.tv_usec * 1000; 10212 10213 ast_mutex_lock(&poll_lock); 10214 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 10215 ast_mutex_unlock(&poll_lock); 10216 10217 if (!poll_thread_run) 10218 break; 10219 10220 poll_subscribed_mailboxes(); 10221 } 10222 10223 return NULL; 10224 }
static const char* mbox | ( | int | id | ) | [static] |
Definition at line 1396 of file app_voicemail.c.
Referenced by acf_mailbox_exists(), add_peer_mailboxes(), adsi_load_vmail(), build_gateway(), copy_message(), get_folder(), has_voicemail(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().
01397 { 01398 static const char *msgs[] = { 01399 #ifdef IMAP_STORAGE 01400 imapfolder, 01401 #else 01402 "INBOX", 01403 #endif 01404 "Old", 01405 "Work", 01406 "Family", 01407 "Friends", 01408 "Cust1", 01409 "Cust2", 01410 "Cust3", 01411 "Cust4", 01412 "Cust5", 01413 "Deleted", 01414 "Urgent" 01415 }; 01416 return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown"; 01417 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 4855 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
04856 { 04857 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 04858 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 10226 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
10227 { 10228 ast_free(mwi_sub); 10229 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 10304 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().
10305 { 10306 struct mwi_sub_task *mwist; 10307 10308 if (ast_event_get_type(event) != AST_EVENT_SUB) 10309 return; 10310 10311 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10312 return; 10313 10314 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 10315 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 10316 return; 10317 } 10318 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 10319 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 10320 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10321 10322 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 10323 ast_free(mwist); 10324 } 10325 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 10288 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().
10289 { 10290 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 10291 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 10292 return; 10293 10294 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10295 return; 10296 10297 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10298 *uniqueid = u; 10299 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 10300 ast_free(uniqueid); 10301 } 10302 }
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. |
Definition at line 6400 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, chan, ast_vm_user::context, vm_state::curmsg, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, ast_vm_user::mailbox, make_dir(), make_file(), manager_event, 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.
06401 { 06402 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06403 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06404 const char *category; 06405 char *myserveremail = serveremail; 06406 06407 ast_channel_lock(chan); 06408 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06409 category = ast_strdupa(category); 06410 } 06411 ast_channel_unlock(chan); 06412 06413 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 06414 make_file(fn, sizeof(fn), todir, msgnum); 06415 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06416 06417 if (!ast_strlen_zero(vmu->attachfmt)) { 06418 if (strstr(fmt, vmu->attachfmt)) 06419 fmt = vmu->attachfmt; 06420 else 06421 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); 06422 } 06423 06424 /* Attach only the first format */ 06425 fmt = ast_strdupa(fmt); 06426 stringp = fmt; 06427 strsep(&stringp, "|"); 06428 06429 if (!ast_strlen_zero(vmu->serveremail)) 06430 myserveremail = vmu->serveremail; 06431 06432 if (!ast_strlen_zero(vmu->email)) { 06433 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 06434 06435 if (attach_user_voicemail) 06436 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 06437 06438 /* XXX possible imap issue, should category be NULL XXX */ 06439 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 06440 06441 if (attach_user_voicemail) 06442 DISPOSE(todir, msgnum); 06443 } 06444 06445 if (!ast_strlen_zero(vmu->pager)) { 06446 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category, flag); 06447 } 06448 06449 if (ast_test_flag(vmu, VM_DELETE)) 06450 DELETE(todir, msgnum, fn, vmu); 06451 06452 /* Leave voicemail for someone */ 06453 if (ast_app_has_voicemail(ext_context, NULL)) 06454 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 06455 06456 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 06457 06458 manager_event(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); 06459 run_externnotify(vmu->context, vmu->mailbox, flag); 06460 06461 #ifdef IMAP_STORAGE 06462 vm_delete(fn); /* Delete the file, but not the IMAP message */ 06463 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 06464 vm_imap_delete(NULL, vms->curmsg, vmu); 06465 vms->newmessages--; /* Fix new message count */ 06466 } 06467 #endif 06468 06469 return 0; 06470 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 3799 of file app_voicemail.c.
References BASELINELEN, ENDL, and baseio::linelength.
Referenced by base_encode().
03800 { 03801 if (bio->linelength >= BASELINELEN) { 03802 if (fputs(ENDL, so) == EOF) { 03803 return -1; 03804 } 03805 03806 bio->linelength= 0; 03807 } 03808 03809 if (putc(((unsigned char) c), so) == EOF) { 03810 return -1; 03811 } 03812 03813 bio->linelength++; 03814 03815 return 1; 03816 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7176 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, last_message_index(), vm_state::lastmsg, mbox(), vm_state::username, vm_lock_path(), and vm_state::vmbox.
Referenced by vm_execmain().
07177 { 07178 int count_msg, last_msg; 07179 07180 ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox)); 07181 07182 /* Rename the member vmbox HERE so that we don't try to return before 07183 * we know what's going on. 07184 */ 07185 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07186 07187 /* Faster to make the directory than to check if it exists. */ 07188 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07189 07190 count_msg = count_messages(vmu, vms->curdir); 07191 if (count_msg < 0) 07192 return count_msg; 07193 else 07194 vms->lastmsg = count_msg - 1; 07195 07196 /* 07197 The following test is needed in case sequencing gets messed up. 07198 There appears to be more than one way to mess up sequence, so 07199 we will not try to find all of the root causes--just fix it when 07200 detected. 07201 */ 07202 07203 if (vm_lock_path(vms->curdir)) { 07204 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07205 return -1; 07206 } 07207 07208 last_msg = last_message_index(vmu, vms->curdir); 07209 ast_unlock_path(vms->curdir); 07210 07211 if (last_msg < 0) 07212 return last_msg; 07213 07214 return 0; 07215 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 6974 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(), chan, CONFIG_FLAG_NOCACHE, config_flags, 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_zh(), and vm_execmain().
06975 { 06976 int res = 0; 06977 char filename[256], *cid; 06978 const char *origtime, *context, *category, *duration, *flag; 06979 struct ast_config *msg_cfg; 06980 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06981 06982 vms->starting = 0; 06983 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06984 adsi_message(chan, vms); 06985 if (!vms->curmsg) 06986 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 06987 else if (vms->curmsg == vms->lastmsg) 06988 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 06989 06990 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 06991 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 06992 msg_cfg = ast_config_load(filename, config_flags); 06993 if (!msg_cfg) { 06994 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 06995 return 0; 06996 } 06997 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 06998 06999 /* Play the word urgent if we are listening to urgent messages */ 07000 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07001 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07002 } 07003 07004 if (!res) { 07005 /* POLISH syntax */ 07006 if (!strncasecmp(chan->language, "pl", 2)) { 07007 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07008 int ten, one; 07009 char nextmsg[256]; 07010 ten = (vms->curmsg + 1) / 10; 07011 one = (vms->curmsg + 1) % 10; 07012 07013 if (vms->curmsg < 20) { 07014 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07015 res = wait_file2(chan, vms, nextmsg); 07016 } else { 07017 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07018 res = wait_file2(chan, vms, nextmsg); 07019 if (one > 0) { 07020 if (!res) { 07021 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07022 res = wait_file2(chan, vms, nextmsg); 07023 } 07024 } 07025 } 07026 } 07027 if (!res) 07028 res = wait_file2(chan, vms, "vm-message"); 07029 /* HEBREW syntax */ 07030 } else if (!strncasecmp(chan->language, "he", 2)) { 07031 if (!vms->curmsg) { 07032 res = wait_file2(chan, vms, "vm-message"); 07033 res = wait_file2(chan, vms, "vm-first"); 07034 } else if (vms->curmsg == vms->lastmsg) { 07035 res = wait_file2(chan, vms, "vm-message"); 07036 res = wait_file2(chan, vms, "vm-last"); 07037 } else { 07038 res = wait_file2(chan, vms, "vm-message"); 07039 res = wait_file2(chan, vms, "vm-number"); 07040 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07041 } 07042 } else { 07043 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07044 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07045 } else { /* DEFAULT syntax */ 07046 res = wait_file2(chan, vms, "vm-message"); 07047 } 07048 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07049 if (!res) { 07050 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07051 } 07052 } 07053 } 07054 } 07055 07056 if (!msg_cfg) { 07057 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07058 return 0; 07059 } 07060 07061 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07062 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07063 DISPOSE(vms->curdir, vms->curmsg); 07064 ast_config_destroy(msg_cfg); 07065 return 0; 07066 } 07067 07068 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07069 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07070 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07071 07072 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07073 if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ 07074 context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); 07075 if (!res) { 07076 res = play_message_category(chan, category); 07077 } 07078 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 07079 res = play_message_datetime(chan, vmu, origtime, filename); 07080 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 07081 res = play_message_callerid(chan, vms, cid, context, 0); 07082 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 07083 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07084 /* Allow pressing '1' to skip envelope / callerid */ 07085 if (res == '1') 07086 res = 0; 07087 ast_config_destroy(msg_cfg); 07088 07089 if (!res) { 07090 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07091 vms->heard[vms->curmsg] = 1; 07092 #ifdef IMAP_STORAGE 07093 /*IMAP storage stores any prepended message from a forward 07094 * as a separate file from the rest of the message 07095 */ 07096 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07097 wait_file(chan, vms, vms->introfn); 07098 } 07099 #endif 07100 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07101 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07102 res = 0; 07103 } 07104 } 07105 DISPOSE(vms->curdir, vms->curmsg); 07106 return res; 07107 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 6860 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, chan, cidinternalcontexts, ast_channel::language, MAX_NUM_CID_CONTEXTS, and wait_file2().
Referenced by advanced_options(), and play_message().
06861 { 06862 int res = 0; 06863 int i; 06864 char *callerid, *name; 06865 char prefile[PATH_MAX] = ""; 06866 06867 06868 /* If voicemail cid is not enabled, or we didn't get cid or context from 06869 * the attribute file, leave now. 06870 * 06871 * TODO Still need to change this so that if this function is called by the 06872 * message envelope (and someone is explicitly requesting to hear the CID), 06873 * it does not check to see if CID is enabled in the config file. 06874 */ 06875 if ((cid == NULL)||(context == NULL)) 06876 return res; 06877 06878 /* Strip off caller ID number from name */ 06879 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 06880 ast_callerid_parse(cid, &name, &callerid); 06881 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 06882 /* Check for internal contexts and only */ 06883 /* say extension when the call didn't come from an internal context in the list */ 06884 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 06885 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 06886 if ((strcmp(cidinternalcontexts[i], context) == 0)) 06887 break; 06888 } 06889 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 06890 if (!res) { 06891 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 06892 if (!ast_strlen_zero(prefile)) { 06893 /* See if we can find a recorded name for this person instead of their extension number */ 06894 if (ast_fileexists(prefile, NULL, NULL) > 0) { 06895 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 06896 if (!callback) 06897 res = wait_file2(chan, vms, "vm-from"); 06898 res = ast_stream_and_wait(chan, prefile, ""); 06899 } else { 06900 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 06901 /* Say "from extension" as one saying to sound smoother */ 06902 if (!callback) 06903 res = wait_file2(chan, vms, "vm-from-extension"); 06904 res = ast_say_digit_str(chan, callerid, "", chan->language); 06905 } 06906 } 06907 } 06908 } else if (!res) { 06909 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 06910 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 06911 if (!callback) 06912 res = wait_file2(chan, vms, "vm-from-phonenumber"); 06913 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 06914 } 06915 } else { 06916 /* Number unknown */ 06917 ast_debug(1, "VM-CID: From an unknown number\n"); 06918 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 06919 res = wait_file2(chan, vms, "vm-unknown-caller"); 06920 } 06921 return res; 06922 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 6773 of file app_voicemail.c.
References ast_log(), ast_play_and_wait(), ast_strlen_zero(), and chan.
Referenced by play_message().
06774 { 06775 int res = 0; 06776 06777 if (!ast_strlen_zero(category)) 06778 res = ast_play_and_wait(chan, category); 06779 06780 if (res) { 06781 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 06782 res = 0; 06783 } 06784 06785 return res; 06786 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 6788 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(), chan, 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().
06789 { 06790 int res = 0; 06791 struct vm_zone *the_zone = NULL; 06792 time_t t; 06793 06794 if (ast_get_time_t(origtime, &t, 0, NULL)) { 06795 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 06796 return 0; 06797 } 06798 06799 /* Does this user have a timezone specified? */ 06800 if (!ast_strlen_zero(vmu->zonetag)) { 06801 /* Find the zone in the list */ 06802 struct vm_zone *z; 06803 AST_LIST_LOCK(&zones); 06804 AST_LIST_TRAVERSE(&zones, z, list) { 06805 if (!strcmp(z->name, vmu->zonetag)) { 06806 the_zone = z; 06807 break; 06808 } 06809 } 06810 AST_LIST_UNLOCK(&zones); 06811 } 06812 06813 /* No internal variable parsing for now, so we'll comment it out for the time being */ 06814 #if 0 06815 /* Set the DIFF_* variables */ 06816 ast_localtime(&t, &time_now, NULL); 06817 tv_now = ast_tvnow(); 06818 ast_localtime(&tv_now, &time_then, NULL); 06819 06820 /* Day difference */ 06821 if (time_now.tm_year == time_then.tm_year) 06822 snprintf(temp,sizeof(temp),"%d",time_now.tm_yday); 06823 else 06824 snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 06825 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 06826 06827 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 06828 #endif 06829 if (the_zone) { 06830 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 06831 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 06832 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 06833 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 06834 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 06835 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 06836 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); 06837 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 06838 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 06839 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 06840 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 06841 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 06842 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 06843 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 06844 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); 06845 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 06846 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 06847 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 06848 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 06849 } else { 06850 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 06851 } 06852 #if 0 06853 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 06854 #endif 06855 return res; 06856 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 6924 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), chan, ast_channel::language, num, say_and_wait(), and wait_file2().
Referenced by play_message().
06925 { 06926 int res = 0; 06927 int durationm; 06928 int durations; 06929 /* Verify that we have a duration for the message */ 06930 if (duration == NULL) 06931 return res; 06932 06933 /* Convert from seconds to minutes */ 06934 durations=atoi(duration); 06935 durationm=(durations / 60); 06936 06937 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 06938 06939 if ((!res) && (durationm >= minduration)) { 06940 res = wait_file2(chan, vms, "vm-duration"); 06941 06942 /* POLISH syntax */ 06943 if (!strncasecmp(chan->language, "pl", 2)) { 06944 div_t num = div(durationm, 10); 06945 06946 if (durationm == 1) { 06947 res = ast_play_and_wait(chan, "digits/1z"); 06948 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 06949 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 06950 if (num.rem == 2) { 06951 if (!num.quot) { 06952 res = ast_play_and_wait(chan, "digits/2-ie"); 06953 } else { 06954 res = say_and_wait(chan, durationm - 2 , chan->language); 06955 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 06956 } 06957 } else { 06958 res = say_and_wait(chan, durationm, chan->language); 06959 } 06960 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 06961 } else { 06962 res = say_and_wait(chan, durationm, chan->language); 06963 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 06964 } 06965 /* DEFAULT syntax */ 06966 } else { 06967 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 06968 res = wait_file2(chan, vms, "vm-minutes"); 06969 } 06970 } 06971 return res; 06972 }
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 11523 of file app_voicemail.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), ast_debug, 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(), chan, ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
11526 { 11527 /* Record message & let caller review or re-record it, or set options if applicable */ 11528 int res = 0; 11529 int cmd = 0; 11530 int max_attempts = 3; 11531 int attempts = 0; 11532 int recorded = 0; 11533 int msg_exists = 0; 11534 signed char zero_gain = 0; 11535 char tempfile[PATH_MAX]; 11536 char *acceptdtmf = "#"; 11537 char *canceldtmf = ""; 11538 11539 /* Note that urgent and private are for flagging messages as such in the future */ 11540 11541 /* barf if no pointer passed to store duration in */ 11542 if (duration == NULL) { 11543 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 11544 return -1; 11545 } 11546 11547 if (!outsidecaller) 11548 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 11549 else 11550 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 11551 11552 cmd = '3'; /* Want to start by recording */ 11553 11554 while ((cmd >= 0) && (cmd != 't')) { 11555 switch (cmd) { 11556 case '1': 11557 if (!msg_exists) { 11558 /* In this case, 1 is to record a message */ 11559 cmd = '3'; 11560 break; 11561 } else { 11562 /* Otherwise 1 is to save the existing message */ 11563 ast_verb(3, "Saving message as is\n"); 11564 if (!outsidecaller) 11565 ast_filerename(tempfile, recordfile, NULL); 11566 ast_stream_and_wait(chan, "vm-msgsaved", ""); 11567 if (!outsidecaller) { 11568 /* Saves to IMAP server only if imapgreeting=yes */ 11569 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 11570 DISPOSE(recordfile, -1); 11571 } 11572 cmd = 't'; 11573 return res; 11574 } 11575 case '2': 11576 /* Review */ 11577 ast_verb(3, "Reviewing the message\n"); 11578 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 11579 break; 11580 case '3': 11581 msg_exists = 0; 11582 /* Record */ 11583 if (recorded == 1) 11584 ast_verb(3, "Re-recording the message\n"); 11585 else 11586 ast_verb(3, "Recording the message\n"); 11587 11588 if (recorded && outsidecaller) { 11589 cmd = ast_play_and_wait(chan, INTRO); 11590 cmd = ast_play_and_wait(chan, "beep"); 11591 } 11592 recorded = 1; 11593 /* 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 */ 11594 if (record_gain) 11595 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 11596 if (ast_test_flag(vmu, VM_OPERATOR)) 11597 canceldtmf = "0"; 11598 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 11599 if (record_gain) 11600 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 11601 if (cmd == -1) { 11602 /* User has hung up, no options to give */ 11603 if (!outsidecaller) { 11604 /* user was recording a greeting and they hung up, so let's delete the recording. */ 11605 ast_filedelete(tempfile, NULL); 11606 } 11607 return cmd; 11608 } 11609 if (cmd == '0') { 11610 break; 11611 } else if (cmd == '*') { 11612 break; 11613 #if 0 11614 } else if (vmu->review && (*duration < 5)) { 11615 /* Message is too short */ 11616 ast_verb(3, "Message too short\n"); 11617 cmd = ast_play_and_wait(chan, "vm-tooshort"); 11618 cmd = ast_filedelete(tempfile, NULL); 11619 break; 11620 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 11621 /* Message is all silence */ 11622 ast_verb(3, "Nothing recorded\n"); 11623 cmd = ast_filedelete(tempfile, NULL); 11624 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 11625 if (!cmd) 11626 cmd = ast_play_and_wait(chan, "vm-speakup"); 11627 break; 11628 #endif 11629 } else { 11630 /* If all is well, a message exists */ 11631 msg_exists = 1; 11632 cmd = 0; 11633 } 11634 break; 11635 case '4': 11636 if (outsidecaller) { /* only mark vm messages */ 11637 /* Mark Urgent */ 11638 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 11639 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 11640 ast_debug(1000, "This message is too urgent!\n"); 11641 res = ast_play_and_wait(chan, "vm-marked-urgent"); 11642 strcpy(flag, "Urgent"); 11643 } else if (flag) { 11644 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 11645 res = ast_play_and_wait(chan, "vm-urgent-removed"); 11646 strcpy(flag, ""); 11647 } else { 11648 ast_play_and_wait(chan, "vm-sorry"); 11649 } 11650 cmd = 0; 11651 } else { 11652 cmd = ast_play_and_wait(chan, "vm-sorry"); 11653 } 11654 break; 11655 case '5': 11656 case '6': 11657 case '7': 11658 case '8': 11659 case '9': 11660 case '*': 11661 case '#': 11662 cmd = ast_play_and_wait(chan, "vm-sorry"); 11663 break; 11664 #if 0 11665 /* XXX Commented out for the moment because of the dangers of deleting 11666 a message while recording (can put the message numbers out of sync) */ 11667 case '*': 11668 /* Cancel recording, delete message, offer to take another message*/ 11669 cmd = ast_play_and_wait(chan, "vm-deleted"); 11670 cmd = ast_filedelete(tempfile, NULL); 11671 if (outsidecaller) { 11672 res = vm_exec(chan, NULL); 11673 return res; 11674 } 11675 else 11676 return 1; 11677 #endif 11678 case '0': 11679 if (!ast_test_flag(vmu, VM_OPERATOR) || !outsidecaller) { 11680 cmd = ast_play_and_wait(chan, "vm-sorry"); 11681 break; 11682 } 11683 if (msg_exists || recorded) { 11684 cmd = ast_play_and_wait(chan, "vm-saveoper"); 11685 if (!cmd) 11686 cmd = ast_waitfordigit(chan, 3000); 11687 if (cmd == '1') { 11688 ast_play_and_wait(chan, "vm-msgsaved"); 11689 cmd = '0'; 11690 } else if (cmd == '4') { 11691 if (flag) { 11692 ast_play_and_wait(chan, "vm-marked-urgent"); 11693 strcpy(flag, "Urgent"); 11694 } 11695 ast_play_and_wait(chan, "vm-msgsaved"); 11696 cmd = '0'; 11697 } else { 11698 ast_play_and_wait(chan, "vm-deleted"); 11699 DELETE(recordfile, -1, recordfile, vmu); 11700 cmd = '0'; 11701 } 11702 } 11703 return cmd; 11704 default: 11705 /* If the caller is an ouside caller, and the review option is enabled, 11706 allow them to review the message, but let the owner of the box review 11707 their OGM's */ 11708 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 11709 return cmd; 11710 if (msg_exists) { 11711 cmd = ast_play_and_wait(chan, "vm-review"); 11712 if (!cmd && outsidecaller) { 11713 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 11714 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 11715 } else if (flag) { 11716 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 11717 } 11718 } 11719 } else { 11720 cmd = ast_play_and_wait(chan, "vm-torerecord"); 11721 if (!cmd) 11722 cmd = ast_waitfordigit(chan, 600); 11723 } 11724 11725 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 11726 cmd = ast_play_and_wait(chan, "vm-reachoper"); 11727 if (!cmd) 11728 cmd = ast_waitfordigit(chan, 600); 11729 } 11730 #if 0 11731 if (!cmd) 11732 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 11733 #endif 11734 if (!cmd) 11735 cmd = ast_waitfordigit(chan, 6000); 11736 if (!cmd) { 11737 attempts++; 11738 } 11739 if (attempts > max_attempts) { 11740 cmd = 't'; 11741 } 11742 } 11743 } 11744 if (cmd == 't') 11745 cmd = 0; 11746 else if (outsidecaller) /* won't play if time out occurs */ 11747 ast_play_and_wait(chan, "vm-goodbye"); 11748 return cmd; 11749 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 10176 of file app_voicemail.c.
References inboxcount2(), mwi_sub::mailbox, mwi_sub::old_new, mwi_sub::old_old, mwi_sub::old_urgent, and queue_mwi_event().
Referenced by handle_subscribe(), and poll_subscribed_mailboxes().
10177 { 10178 int new = 0, old = 0, urgent = 0; 10179 10180 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 10181 10182 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 10183 mwi_sub->old_urgent = urgent; 10184 mwi_sub->old_new = new; 10185 mwi_sub->old_old = old; 10186 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 10187 } 10188 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 10190 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub::mailbox, and poll_subscribed_mailbox().
Referenced by mb_poll_thread().
10191 { 10192 struct mwi_sub *mwi_sub; 10193 10194 AST_RWLIST_RDLOCK(&mwi_subs); 10195 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 10196 if (!ast_strlen_zero(mwi_sub->mailbox)) { 10197 poll_subscribed_mailbox(mwi_sub); 10198 } 10199 } 10200 AST_RWLIST_UNLOCK(&mwi_subs); 10201 }
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 815 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::exit, exitcontext, globalflags, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::saydurationm, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.
00816 { 00817 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00818 if (saydurationminfo) 00819 vmu->saydurationm = saydurationminfo; 00820 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 00821 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 00822 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 00823 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 00824 if (vmmaxsecs) 00825 vmu->maxsecs = vmmaxsecs; 00826 if (maxmsg) 00827 vmu->maxmsg = maxmsg; 00828 if (maxdeletedmsg) 00829 vmu->maxdeletedmsg = maxdeletedmsg; 00830 vmu->volgain = volgain; 00831 }
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, | |||
char * | passdata, | |||
size_t | passdatasize, | |||
const char * | category, | |||
const char * | flag | |||
) | [static] |
Definition at line 3887 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(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, and pbx_builtin_setvar_helper().
03888 { 03889 char callerid[256]; 03890 char fromdir[256], fromfile[256]; 03891 struct ast_config *msg_cfg; 03892 const char *origcallerid, *origtime; 03893 char origcidname[80], origcidnum[80], origdate[80]; 03894 int inttime; 03895 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 03896 03897 /* Prepare variables for substitution in email body and subject */ 03898 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 03899 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 03900 snprintf(passdata, passdatasize, "%d", msgnum); 03901 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata); 03902 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 03903 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 03904 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 03905 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 03906 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 03907 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 03908 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 03909 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 03910 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 03911 03912 /* Retrieve info from VM attribute file */ 03913 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 03914 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 03915 if (strlen(fromfile) < sizeof(fromfile) - 5) { 03916 strcat(fromfile, ".txt"); 03917 } 03918 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 03919 if (option_debug > 0) { 03920 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 03921 } 03922 return; 03923 } 03924 03925 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 03926 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 03927 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 03928 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 03929 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 03930 } 03931 03932 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 03933 struct timeval tv = { inttime, }; 03934 struct ast_tm tm; 03935 ast_localtime(&tv, &tm, NULL); 03936 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 03937 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 03938 } 03939 ast_config_destroy(msg_cfg); 03940 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6364 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().
Referenced by append_mailbox(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
06365 { 06366 struct ast_event *event; 06367 char *mailbox, *context; 06368 06369 /* Strip off @default */ 06370 context = mailbox = ast_strdupa(box); 06371 strsep(&context, "@"); 06372 if (ast_strlen_zero(context)) 06373 context = "default"; 06374 06375 if (!(event = ast_event_new(AST_EVENT_MWI, 06376 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06377 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06378 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06379 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06380 AST_EVENT_IE_END))) { 06381 return; 06382 } 06383 06384 ast_event_queue_and_cache(event); 06385 }
static char* quote | ( | const char * | from, | |
char * | to, | |||
size_t | len | |||
) | [static] |
Wraps a character sequence in double quotes, escaping occurences of quotes within the string.
from | The string to work with. | |
to | The string to write the modified quoted string. This buffer should be sufficiently larger than the from string, so as to allow it to be expanded by the surrounding quotes and escaping of internal quotes. |
Definition at line 3949 of file app_voicemail.c.
03950 { 03951 char *ptr = to; 03952 *ptr++ = '"'; 03953 for (; ptr < to + len - 1; from++) { 03954 if (*from == '"') 03955 *ptr++ = '\\'; 03956 else if (*from == '\0') 03957 break; 03958 *ptr++ = *from; 03959 } 03960 if (ptr < to + len - 1) 03961 *ptr++ = '"'; 03962 *ptr = '\0'; 03963 return to; 03964 }
static int reload | ( | void | ) | [static] |
Definition at line 11194 of file app_voicemail.c.
References load_config().
11195 { 11196 return load_config(1); 11197 }
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 3564 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03565 { 03566 char stxt[PATH_MAX]; 03567 char dtxt[PATH_MAX]; 03568 ast_filerename(sfn,dfn,NULL); 03569 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03570 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03571 if (ast_check_realtime("voicemail_data")) { 03572 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 03573 } 03574 rename(stxt, dtxt); 03575 }
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 1222 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().
01223 { 01224 /* This function could be made to generate one from a database, too */ 01225 struct ast_vm_user *cur; 01226 int res = -1; 01227 AST_LIST_LOCK(&users); 01228 AST_LIST_TRAVERSE(&users, cur, list) { 01229 if ((!context || !strcasecmp(context, cur->context)) && 01230 (!strcasecmp(mailbox, cur->mailbox))) 01231 break; 01232 } 01233 if (cur) { 01234 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01235 res = 0; 01236 } 01237 AST_LIST_UNLOCK(&users); 01238 return res; 01239 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 4998 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.
04999 { 05000 char arguments[255]; 05001 char ext_context[256] = ""; 05002 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05003 struct ast_smdi_mwi_message *mwi_msg; 05004 05005 if (!ast_strlen_zero(context)) 05006 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05007 else 05008 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05009 05010 if (smdi_iface) { 05011 if (ast_app_has_voicemail(ext_context, NULL)) 05012 ast_smdi_mwi_set(smdi_iface, extension); 05013 else 05014 ast_smdi_mwi_unset(smdi_iface, extension); 05015 05016 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05017 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05018 if (!strncmp(mwi_msg->cause, "INV", 3)) 05019 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05020 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05021 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05022 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05023 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05024 } else { 05025 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05026 } 05027 } 05028 05029 if (!ast_strlen_zero(externnotify)) { 05030 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05031 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05032 } else { 05033 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05034 ast_debug(1, "Executing %s\n", arguments); 05035 ast_safe_system(arguments); 05036 } 05037 } 05038 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 5577 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock(), ast_mutex_unlock(), ast_unlock_path(), ast_vm_user::context, COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().
Referenced by close_mailbox(), and vm_execmain().
05578 { 05579 #ifdef IMAP_STORAGE 05580 /* we must use mbox(x) folder names, and copy the message there */ 05581 /* simple. huh? */ 05582 char sequence[10]; 05583 char mailbox[256]; 05584 int res; 05585 05586 /* get the real IMAP message number for this message */ 05587 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 05588 05589 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(box)); 05590 ast_mutex_lock(&vms->lock); 05591 /* if save to Old folder, put in INBOX as read */ 05592 if (box == OLD_FOLDER) { 05593 mail_setflag(vms->mailstream, sequence, "\\Seen"); 05594 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 05595 } else if (box == NEW_FOLDER) { 05596 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 05597 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 05598 } 05599 if (!strcasecmp(mbox(NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 05600 ast_mutex_unlock(&vms->lock); 05601 return 0; 05602 } 05603 /* Create the folder if it don't exist */ 05604 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 05605 ast_debug(5, "Checking if folder exists: %s\n",mailbox); 05606 if (mail_create(vms->mailstream, mailbox) == NIL) 05607 ast_debug(5, "Folder exists.\n"); 05608 else 05609 ast_log(AST_LOG_NOTICE, "Folder %s created!\n",mbox(box)); 05610 res = !mail_copy(vms->mailstream, sequence, (char *)mbox(box)); 05611 ast_mutex_unlock(&vms->lock); 05612 return res; 05613 #else 05614 char *dir = vms->curdir; 05615 char *username = vms->username; 05616 char *context = vmu->context; 05617 char sfn[PATH_MAX]; 05618 char dfn[PATH_MAX]; 05619 char ddir[PATH_MAX]; 05620 const char *dbox = mbox(box); 05621 int x, i; 05622 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 05623 05624 if (vm_lock_path(ddir)) 05625 return ERROR_LOCK_PATH; 05626 05627 x = last_message_index(vmu, ddir) + 1; 05628 05629 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 05630 x--; 05631 for (i = 1; i <= x; i++) { 05632 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 05633 make_file(sfn, sizeof(sfn), ddir, i); 05634 make_file(dfn, sizeof(dfn), ddir, i - 1); 05635 if (EXISTS(ddir, i, sfn, NULL)) { 05636 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 05637 } else 05638 break; 05639 } 05640 } else { 05641 if (x >= vmu->maxmsg) { 05642 ast_unlock_path(ddir); 05643 return -1; 05644 } 05645 } 05646 make_file(sfn, sizeof(sfn), dir, msg); 05647 make_file(dfn, sizeof(dfn), ddir, x); 05648 if (strcmp(sfn, dfn)) { 05649 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 05650 } 05651 ast_unlock_path(ddir); 05652 #endif 05653 return 0; 05654 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 5570 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_say_number(), and chan.
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(), and vm_intro_zh().
05571 { 05572 int d; 05573 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 05574 return d; 05575 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 11180 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), chan, DISPOSE, and RETRIEVE.
Referenced by load_module().
11181 { 11182 int res = -1; 11183 char dir[PATH_MAX]; 11184 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 11185 ast_debug(2, "About to try retrieving name file %s\n", dir); 11186 RETRIEVE(dir, -1, mailbox, context); 11187 if (ast_fileexists(dir, NULL, NULL)) { 11188 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 11189 } 11190 DISPOSE(dir, -1); 11191 return res; 11192 }
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 4403 of file app_voicemail.c.
References ast_debug, ast_log(), ast_safe_system(), ast_strlen_zero(), ast_test_flag, chan, ast_vm_user::email, globalflags, ast_vm_user::mailbox, make_email_file(), VM_ATTACH, and vm_mkftemp().
04404 { 04405 FILE *p=NULL; 04406 char tmp[80] = "/tmp/astmail-XXXXXX"; 04407 char tmp2[256]; 04408 04409 if (vmu && ast_strlen_zero(vmu->email)) { 04410 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04411 return(0); 04412 } 04413 if (!strcmp(format, "wav49")) 04414 format = "WAV"; 04415 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)); 04416 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04417 command hangs */ 04418 if ((p = vm_mkftemp(tmp)) == NULL) { 04419 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04420 return -1; 04421 } else { 04422 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04423 fclose(p); 04424 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04425 ast_safe_system(tmp2); 04426 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04427 } 04428 return 0; 04429 }
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 4431 of file app_voicemail.c.
References ast_channel_alloc, ast_channel_free(), ast_copy_string(), ast_debug, ast_log(), ast_safe_system(), AST_STATE_DOWN, ast_strftime(), ast_strlen_zero(), fromstring, MAXHOSTNAMELEN, pagerbody, pagerfromstring, pagersubject, pbx_substitute_variables_helper(), prep_email_sub_vars(), vm_mkftemp(), and vmu_tm().
Referenced by notify_new_message().
04432 { 04433 char date[256]; 04434 char host[MAXHOSTNAMELEN] = ""; 04435 char who[256]; 04436 char dur[PATH_MAX]; 04437 char tmp[80] = "/tmp/astmail-XXXXXX"; 04438 char tmp2[PATH_MAX]; 04439 struct ast_tm tm; 04440 FILE *p; 04441 04442 if ((p = vm_mkftemp(tmp)) == NULL) { 04443 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04444 return -1; 04445 } 04446 gethostname(host, sizeof(host)-1); 04447 if (strchr(srcemail, '@')) 04448 ast_copy_string(who, srcemail, sizeof(who)); 04449 else 04450 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04451 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04452 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04453 fprintf(p, "Date: %s\n", date); 04454 04455 if (*pagerfromstring) { 04456 struct ast_channel *ast; 04457 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04458 char *passdata; 04459 int vmlen = strlen(fromstring)*3 + 200; 04460 passdata = alloca(vmlen); 04461 memset(passdata, 0, vmlen); 04462 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04463 pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen); 04464 fprintf(p, "From: %s <%s>\n", passdata, who); 04465 ast_channel_free(ast); 04466 } else 04467 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04468 } else 04469 fprintf(p, "From: Asterisk PBX <%s>\n", who); 04470 fprintf(p, "To: %s\n", pager); 04471 if (pagersubject) { 04472 struct ast_channel *ast; 04473 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04474 char *passdata; 04475 int vmlen = strlen(pagersubject) * 3 + 200; 04476 passdata = alloca(vmlen); 04477 memset(passdata, 0, vmlen); 04478 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04479 pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen); 04480 fprintf(p, "Subject: %s\n\n", passdata); 04481 ast_channel_free(ast); 04482 } else 04483 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04484 } else { 04485 if (ast_strlen_zero(flag)) { 04486 fprintf(p, "Subject: New VM\n\n"); 04487 } else { 04488 fprintf(p, "Subject: New %s VM\n\n", flag); 04489 } 04490 } 04491 04492 ast_strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); 04493 if (pagerbody) { 04494 struct ast_channel *ast; 04495 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04496 char *passdata; 04497 int vmlen = strlen(pagerbody) * 3 + 200; 04498 passdata = alloca(vmlen); 04499 memset(passdata, 0, vmlen); 04500 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04501 pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen); 04502 fprintf(p, "%s\n", passdata); 04503 ast_channel_free(ast); 04504 } else 04505 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04506 } else { 04507 fprintf(p, "New %s long %s msg in box %s\n" 04508 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04509 } 04510 fclose(p); 04511 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04512 ast_safe_system(tmp2); 04513 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04514 return 0; 04515 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 9974 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().
09975 { 09976 struct ast_config *cfg; 09977 const char *cat = NULL; 09978 09979 if (!(cfg = ast_load_realtime_multientry("voicemail", 09980 "context", context, SENTINEL))) { 09981 return CLI_FAILURE; 09982 } 09983 09984 ast_cli(fd, 09985 "\n" 09986 "=============================================================\n" 09987 "=== Configured Voicemail Users ==============================\n" 09988 "=============================================================\n" 09989 "===\n"); 09990 09991 while ((cat = ast_category_browse(cfg, cat))) { 09992 struct ast_variable *var = NULL; 09993 ast_cli(fd, 09994 "=== Mailbox ...\n" 09995 "===\n"); 09996 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 09997 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 09998 ast_cli(fd, 09999 "===\n" 10000 "=== ---------------------------------------------------------\n" 10001 "===\n"); 10002 } 10003 10004 ast_cli(fd, 10005 "=============================================================\n" 10006 "\n"); 10007 10008 ast_config_destroy(cfg); 10009 10010 return CLI_SUCCESS; 10011 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 10327 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().
10328 { 10329 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, NULL, 10330 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 10331 AST_EVENT_IE_END); 10332 10333 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, NULL, 10334 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 10335 AST_EVENT_IE_END); 10336 10337 if (mwi_sub_sub) 10338 ast_event_report_subs(mwi_sub_sub); 10339 10340 poll_thread_run = 1; 10341 10342 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 10343 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 10345 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().
10346 { 10347 poll_thread_run = 0; 10348 10349 if (mwi_sub_sub) { 10350 ast_event_unsubscribe(mwi_sub_sub); 10351 mwi_sub_sub = NULL; 10352 } 10353 10354 if (mwi_unsub_sub) { 10355 ast_event_unsubscribe(mwi_unsub_sub); 10356 mwi_unsub_sub = NULL; 10357 } 10358 10359 ast_mutex_lock(&poll_lock); 10360 ast_cond_signal(&poll_cond); 10361 ast_mutex_unlock(&poll_lock); 10362 10363 pthread_join(poll_thread, NULL); 10364 10365 poll_thread = AST_PTHREADT_NULL; 10366 }
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 786 of file app_voicemail.c.
Referenced by make_email_file().
00787 { 00788 char *bufptr = buf; 00789 for (; *input; input++) { 00790 if (*input < 32) { 00791 continue; 00792 } 00793 *bufptr++ = *input; 00794 if (bufptr == buf + buflen - 1) { 00795 break; 00796 } 00797 } 00798 *bufptr = '\0'; 00799 return buf; 00800 }
static char* substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 10491 of file app_voicemail.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_create(), and str.
Referenced by load_config().
10492 { 10493 char *current, *result; 10494 10495 /* Add 16 for fudge factor */ 10496 struct ast_str *str = ast_str_create(strlen(value) + 16); 10497 10498 /* Substitute strings \r, \n, and \t into the appropriate characters */ 10499 for (current = (char *) value; *current; current++) { 10500 if (*current == '\\') { 10501 current++; 10502 if (!*current) { 10503 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 10504 break; 10505 } 10506 switch (*current) { 10507 case 'r': 10508 ast_str_append(&str, 0, "\r"); 10509 break; 10510 case 'n': 10511 #ifdef IMAP_STORAGE 10512 if (!str->used || str->str[str->used - 1] != '\r') { 10513 ast_str_append(&str, 0, "\r"); 10514 } 10515 #endif 10516 ast_str_append(&str, 0, "\n"); 10517 break; 10518 case 't': 10519 ast_str_append(&str, 0, "\t"); 10520 break; 10521 default: 10522 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 10523 break; 10524 } 10525 } else { 10526 ast_str_append(&str, 0, "%c", *current); 10527 } 10528 } 10529 10530 result = ast_strdup(str->str); 10531 ast_free(str); 10532 10533 return result; 10534 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11199 of file app_voicemail.c.
References ao2_ref, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), 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().
11200 { 11201 int res; 11202 11203 res = ast_unregister_application(app); 11204 res |= ast_unregister_application(app2); 11205 res |= ast_unregister_application(app3); 11206 res |= ast_unregister_application(app4); 11207 res |= ast_custom_function_unregister(&mailbox_exists_acf); 11208 res |= ast_manager_unregister("VoicemailUsersList"); 11209 ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 11210 ast_uninstall_vm_functions(); 11211 ao2_ref(inprocess_container, -1); 11212 11213 if (poll_thread != AST_PTHREADT_NULL) 11214 stop_poll_thread(); 11215 11216 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 11217 ast_unload_realtime("voicemail"); 11218 ast_unload_realtime("voicemail_data"); 11219 11220 free_vm_users(); 11221 free_vm_zones(); 11222 return res; 11223 }
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 8923 of file app_voicemail.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitstream(), chan, find_user(), ast_vm_user::password, and vm_password.
Referenced by vm_execmain(), and vmauthenticate().
08926 { 08927 int useadsi=0, valid=0, logretries=0; 08928 char password[AST_MAX_EXTENSION]="", *passptr; 08929 struct ast_vm_user vmus, *vmu = NULL; 08930 08931 /* If ADSI is supported, setup login screen */ 08932 adsi_begin(chan, &useadsi); 08933 if (!skipuser && useadsi) 08934 adsi_login(chan); 08935 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 08936 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 08937 return -1; 08938 } 08939 08940 /* Authenticate them and get their mailbox/password */ 08941 08942 while (!valid && (logretries < max_logins)) { 08943 /* Prompt for, and read in the username */ 08944 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 08945 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 08946 return -1; 08947 } 08948 if (ast_strlen_zero(mailbox)) { 08949 if (chan->cid.cid_num) { 08950 ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size); 08951 } else { 08952 ast_verb(3,"Username not entered\n"); 08953 return -1; 08954 } 08955 } 08956 if (useadsi) 08957 adsi_password(chan); 08958 08959 if (!ast_strlen_zero(prefix)) { 08960 char fullusername[80] = ""; 08961 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 08962 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 08963 ast_copy_string(mailbox, fullusername, mailbox_size); 08964 } 08965 08966 ast_debug(1, "Before find user for mailbox %s\n",mailbox); 08967 vmu = find_user(&vmus, context, mailbox); 08968 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 08969 /* saved password is blank, so don't bother asking */ 08970 password[0] = '\0'; 08971 } else { 08972 if (ast_streamfile(chan, vm_password, chan->language)) { 08973 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 08974 return -1; 08975 } 08976 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 08977 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 08978 return -1; 08979 } 08980 } 08981 08982 if (vmu) { 08983 passptr = vmu->password; 08984 if (passptr[0] == '-') passptr++; 08985 } 08986 if (vmu && !strcmp(passptr, password)) 08987 valid++; 08988 else { 08989 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 08990 if (!ast_strlen_zero(prefix)) 08991 mailbox[0] = '\0'; 08992 } 08993 logretries++; 08994 if (!valid) { 08995 if (skipuser || logretries >= max_logins) { 08996 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 08997 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 08998 return -1; 08999 } 09000 } else { 09001 if (useadsi) 09002 adsi_login(chan); 09003 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09004 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09005 return -1; 09006 } 09007 } 09008 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09009 return -1; 09010 } 09011 } 09012 if (!valid && (logretries >= max_logins)) { 09013 ast_stopstream(chan); 09014 ast_play_and_wait(chan, "vm-goodbye"); 09015 return -1; 09016 } 09017 if (vmu && !skipuser) { 09018 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09019 } 09020 return 0; 09021 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9869 of file app_voicemail.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan, find_user(), mbox(), and pbx_builtin_setvar_helper().
Referenced by load_module().
09870 { 09871 struct ast_vm_user svm; 09872 char *context, *box; 09873 AST_DECLARE_APP_ARGS(args, 09874 AST_APP_ARG(mbox); 09875 AST_APP_ARG(options); 09876 ); 09877 static int dep_warning = 0; 09878 09879 if (ast_strlen_zero(data)) { 09880 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 09881 return -1; 09882 } 09883 09884 if (!dep_warning) { 09885 dep_warning = 1; 09886 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *)data); 09887 } 09888 09889 box = ast_strdupa(data); 09890 09891 AST_STANDARD_APP_ARGS(args, box); 09892 09893 if (args.options) { 09894 } 09895 09896 if ((context = strchr(args.mbox, '@'))) { 09897 *context = '\0'; 09898 context++; 09899 } 09900 09901 if (find_user(&svm, context, args.mbox)) { 09902 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 09903 } else 09904 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 09905 09906 return 0; 09907 }
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 8904 of file app_voicemail.c.
References chan, 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(), and vm_browse_messages_zh().
Referenced by vm_execmain().
08905 { 08906 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 08907 return vm_browse_messages_es(chan, vms, vmu); 08908 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 08909 return vm_browse_messages_gr(chan, vms, vmu); 08910 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 08911 return vm_browse_messages_he(chan, vms, vmu); 08912 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 08913 return vm_browse_messages_it(chan, vms, vmu); 08914 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 08915 return vm_browse_messages_pt(chan, vms, vmu); 08916 } else if (!strncasecmp(chan->language, "zh", 2)) { 08917 return vm_browse_messages_zh(chan, vms, vmu); /* CHINESE (Taiwan) */ 08918 } else { /* Default to English syntax */ 08919 return vm_browse_messages_en(chan, vms, vmu); 08920 } 08921 }
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 8767 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08768 { 08769 int cmd=0; 08770 08771 if (vms->lastmsg > -1) { 08772 cmd = play_message(chan, vmu, vms); 08773 } else { 08774 cmd = ast_play_and_wait(chan, "vm-youhave"); 08775 if (!cmd) 08776 cmd = ast_play_and_wait(chan, "vm-no"); 08777 if (!cmd) { 08778 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08779 cmd = ast_play_and_wait(chan, vms->fn); 08780 } 08781 if (!cmd) 08782 cmd = ast_play_and_wait(chan, "vm-messages"); 08783 } 08784 return cmd; 08785 }
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 8821 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08822 { 08823 int cmd=0; 08824 08825 if (vms->lastmsg > -1) { 08826 cmd = play_message(chan, vmu, vms); 08827 } else { 08828 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 08829 if (!cmd) 08830 cmd = ast_play_and_wait(chan, "vm-messages"); 08831 if (!cmd) { 08832 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08833 cmd = ast_play_and_wait(chan, vms->fn); 08834 } 08835 } 08836 return cmd; 08837 }
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 8715 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::curbox, vm_state::fn, vm_state::lastmsg, play_message(), and vm_state::vmbox.
Referenced by vm_browse_messages().
08716 { 08717 int cmd=0; 08718 08719 if (vms->lastmsg > -1) { 08720 cmd = play_message(chan, vmu, vms); 08721 } else { 08722 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 08723 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 08724 if (!cmd) { 08725 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 08726 cmd = ast_play_and_wait(chan, vms->fn); 08727 } 08728 if (!cmd) 08729 cmd = ast_play_and_wait(chan, "vm-messages"); 08730 } else { 08731 if (!cmd) 08732 cmd = ast_play_and_wait(chan, "vm-messages"); 08733 if (!cmd) { 08734 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08735 cmd = ast_play_and_wait(chan, vms->fn); 08736 } 08737 } 08738 } 08739 return cmd; 08740 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 8743 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08744 { 08745 int cmd = 0; 08746 08747 if (vms->lastmsg > -1) { 08748 cmd = play_message(chan, vmu, vms); 08749 } else { 08750 if (!strcasecmp(vms->fn, "INBOX")) { 08751 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 08752 } else { 08753 cmd = ast_play_and_wait(chan, "vm-nomessages"); 08754 } 08755 } 08756 return cmd; 08757 }
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 8795 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08796 { 08797 int cmd=0; 08798 08799 if (vms->lastmsg > -1) { 08800 cmd = play_message(chan, vmu, vms); 08801 } else { 08802 cmd = ast_play_and_wait(chan, "vm-no"); 08803 if (!cmd) 08804 cmd = ast_play_and_wait(chan, "vm-message"); 08805 if (!cmd) { 08806 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08807 cmd = ast_play_and_wait(chan, vms->fn); 08808 } 08809 } 08810 return cmd; 08811 }
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 8847 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08848 { 08849 int cmd=0; 08850 08851 if (vms->lastmsg > -1) { 08852 cmd = play_message(chan, vmu, vms); 08853 } else { 08854 cmd = ast_play_and_wait(chan, "vm-no"); 08855 if (!cmd) { 08856 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08857 cmd = ast_play_and_wait(chan, vms->fn); 08858 } 08859 if (!cmd) 08860 cmd = ast_play_and_wait(chan, "vm-messages"); 08861 } 08862 return cmd; 08863 }
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 8873 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
Referenced by vm_browse_messages().
08874 { 08875 int cmd=0; 08876 08877 if (vms->lastmsg > -1) { 08878 cmd = play_message(chan, vmu, vms); 08879 } else { 08880 cmd = ast_play_and_wait(chan, "vm-you"); 08881 if (!cmd) 08882 cmd = ast_play_and_wait(chan, "vm-haveno"); 08883 if (!cmd) 08884 cmd = ast_play_and_wait(chan, "vm-messages"); 08885 if (!cmd) { 08886 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08887 cmd = ast_play_and_wait(chan, vms->fn); 08888 } 08889 } 08890 return cmd; 08891 }
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 1248 of file app_voicemail.c.
References ast_category_browse(), ast_category_get(), ast_config_load, ast_copy_string(), ast_debug, ast_log(), AST_LOG_WARNING, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, config_flags, config_text_file_save(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, reset_user_pw(), var, and VOICEMAIL_CONFIG.
Referenced by vm_newuser(), and vm_options().
01249 { 01250 struct ast_config *cfg=NULL; 01251 struct ast_variable *var=NULL; 01252 struct ast_category *cat=NULL; 01253 char *category=NULL, *value=NULL, *new=NULL; 01254 const char *tmp=NULL; 01255 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01256 if (!change_password_realtime(vmu, newpassword)) 01257 return; 01258 01259 /* check voicemail.conf */ 01260 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags))) { 01261 while ((category = ast_category_browse(cfg, category))) { 01262 if (!strcasecmp(category, vmu->context)) { 01263 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01264 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01265 break; 01266 } 01267 value = strstr(tmp,","); 01268 if (!value) { 01269 ast_log(AST_LOG_WARNING, "variable has bad format.\n"); 01270 break; 01271 } 01272 new = alloca((strlen(value)+strlen(newpassword)+1)); 01273 sprintf(new,"%s%s", newpassword, value); 01274 if (!(cat = ast_category_get(cfg, category))) { 01275 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01276 break; 01277 } 01278 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01279 } 01280 } 01281 /* save the results */ 01282 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01283 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01284 config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01285 } 01286 category = NULL; 01287 var = NULL; 01288 /* check users.conf and update the password stored for the mailbox*/ 01289 /* if no vmsecret entry exists create one. */ 01290 if ((cfg = ast_config_load("users.conf", config_flags))) { 01291 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01292 while ((category = ast_category_browse(cfg, category))) { 01293 ast_debug(4, "users.conf: %s\n", category); 01294 if (!strcasecmp(category, vmu->mailbox)) { 01295 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01296 ast_debug(3, "looks like we need to make vmsecret!\n"); 01297 var = ast_variable_new("vmsecret", newpassword, ""); 01298 } 01299 new = alloca(strlen(newpassword)+1); 01300 sprintf(new, "%s", newpassword); 01301 if (!(cat = ast_category_get(cfg, category))) { 01302 ast_debug(4, "failed to get category!\n"); 01303 break; 01304 } 01305 if (!var) 01306 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01307 else 01308 ast_variable_append(cat, var); 01309 } 01310 } 01311 /* save the results and clean things up */ 01312 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01313 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01314 config_text_file_save("users.conf", cfg, "AppVoicemail"); 01315 } 01316 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1318 of file app_voicemail.c.
References ast_copy_string(), ast_safe_system(), buf, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
Referenced by vm_newuser(), and vm_options().
01319 { 01320 char buf[255]; 01321 snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword); 01322 if (!ast_safe_system(buf)) { 01323 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01324 /* Reset the password in memory, too */ 01325 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01326 } 01327 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 942 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().
00943 { 00944 int fds[2], pid = 0; 00945 00946 memset(buf, 0, len); 00947 00948 if (pipe(fds)) { 00949 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 00950 } else { 00951 /* good to go*/ 00952 pid = ast_safe_fork(0); 00953 00954 if (pid < 0) { 00955 /* ok maybe not */ 00956 close(fds[0]); 00957 close(fds[1]); 00958 snprintf(buf, len, "FAILURE: Fork failed"); 00959 } else if (pid) { 00960 /* parent */ 00961 close(fds[1]); 00962 if (read(fds[0], buf, len) < 0) { 00963 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 00964 } 00965 close(fds[0]); 00966 } else { 00967 /* child */ 00968 AST_DECLARE_APP_ARGS(arg, 00969 AST_APP_ARG(v)[20]; 00970 ); 00971 char *mycmd = ast_strdupa(command); 00972 00973 close(fds[0]); 00974 dup2(fds[1], STDOUT_FILENO); 00975 close(fds[1]); 00976 ast_close_fds_above_n(STDOUT_FILENO); 00977 00978 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 00979 00980 execv(arg.v[0], arg.v); 00981 printf("FAILURE: %s", strerror(errno)); 00982 _exit(0); 00983 } 00984 } 00985 return buf; 00986 }
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 3741 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
03742 { 03743 char *txt; 03744 int txtsize = 0; 03745 03746 txtsize = (strlen(file) + 5)*sizeof(char); 03747 txt = alloca(txtsize); 03748 /* Sprintf here would safe because we alloca'd exactly the right length, 03749 * but trying to eliminate all sprintf's anyhow 03750 */ 03751 if (ast_check_realtime("voicemail_data")) { 03752 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 03753 } 03754 snprintf(txt, txtsize, "%s.txt", file); 03755 unlink(txt); 03756 return ast_filedelete(file, NULL); 03757 }
static int vm_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9734 of file app_voicemail.c.
References ast_channel::_state, 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_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, chan, 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().
09735 { 09736 int res = 0; 09737 char *tmp; 09738 struct leave_vm_options leave_options; 09739 struct ast_flags flags = { 0 }; 09740 char *opts[OPT_ARG_ARRAY_SIZE]; 09741 AST_DECLARE_APP_ARGS(args, 09742 AST_APP_ARG(argv0); 09743 AST_APP_ARG(argv1); 09744 ); 09745 09746 memset(&leave_options, 0, sizeof(leave_options)); 09747 09748 if (chan->_state != AST_STATE_UP) 09749 ast_answer(chan); 09750 09751 if (!ast_strlen_zero(data)) { 09752 tmp = ast_strdupa(data); 09753 AST_STANDARD_APP_ARGS(args, tmp); 09754 if (args.argc == 2) { 09755 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09756 return -1; 09757 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 09758 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09759 int gain; 09760 09761 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09762 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09763 return -1; 09764 } else { 09765 leave_options.record_gain = (signed char) gain; 09766 } 09767 } 09768 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 09769 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 09770 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 09771 } 09772 } 09773 } else { 09774 char temp[256]; 09775 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 09776 if (res < 0) 09777 return res; 09778 if (ast_strlen_zero(temp)) 09779 return 0; 09780 args.argv0 = ast_strdupa(temp); 09781 } 09782 09783 res = leave_voicemail(chan, args.argv0, &leave_options); 09784 if (res == OPERATOR_EXIT) { 09785 res = 0; 09786 } 09787 09788 if (res == ERROR_LOCK_PATH) { 09789 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 09790 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 09791 res = 0; 09792 } 09793 09794 return res; 09795 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9023 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(), 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_log(), AST_LOG_ERROR, 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, chan, close_mailbox(), ast_vm_user::context, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free_user(), get_folder2(), globalflags, has_voicemail(), language, ast_vm_user::language, ast_vm_user::mailbox, make_file(), manager_event, 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().
09024 { 09025 /* XXX This is, admittedly, some pretty horrendous code. For some 09026 reason it just seemed a lot easier to do with GOTO's. I feel 09027 like I'm back in my GWBASIC days. XXX */ 09028 int res=-1; 09029 int cmd=0; 09030 int valid = 0; 09031 char prefixstr[80] =""; 09032 char ext_context[256]=""; 09033 int box; 09034 int useadsi = 0; 09035 int skipuser = 0; 09036 struct vm_state vms; 09037 struct ast_vm_user *vmu = NULL, vmus; 09038 char *context=NULL; 09039 int silentexit = 0; 09040 struct ast_flags flags = { 0 }; 09041 signed char record_gain = 0; 09042 int play_auto = 0; 09043 int play_folder = 0; 09044 int in_urgent = 0; 09045 #ifdef IMAP_STORAGE 09046 int deleted = 0; 09047 #endif 09048 09049 /* Add the vm_state to the active list and keep it active */ 09050 memset(&vms, 0, sizeof(vms)); 09051 09052 vms.lastmsg = -1; 09053 09054 memset(&vmus, 0, sizeof(vmus)); 09055 09056 if (chan->_state != AST_STATE_UP) { 09057 ast_debug(1, "Before ast_answer\n"); 09058 ast_answer(chan); 09059 } 09060 09061 if (!ast_strlen_zero(data)) { 09062 char *opts[OPT_ARG_ARRAY_SIZE]; 09063 char *parse; 09064 AST_DECLARE_APP_ARGS(args, 09065 AST_APP_ARG(argv0); 09066 AST_APP_ARG(argv1); 09067 ); 09068 09069 parse = ast_strdupa(data); 09070 09071 AST_STANDARD_APP_ARGS(args, parse); 09072 09073 if (args.argc == 2) { 09074 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09075 return -1; 09076 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09077 int gain; 09078 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09079 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09080 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09081 return -1; 09082 } else { 09083 record_gain = (signed char) gain; 09084 } 09085 } else { 09086 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09087 } 09088 } 09089 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09090 play_auto = 1; 09091 if (opts[OPT_ARG_PLAYFOLDER]) { 09092 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09093 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]); 09094 } 09095 } else { 09096 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09097 } 09098 if ( play_folder > 9 || play_folder < 0) { 09099 ast_log(AST_LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder); 09100 play_folder = 0; 09101 } 09102 } 09103 } else { 09104 /* old style options parsing */ 09105 while (*(args.argv0)) { 09106 if (*(args.argv0) == 's') 09107 ast_set_flag(&flags, OPT_SILENT); 09108 else if (*(args.argv0) == 'p') 09109 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09110 else 09111 break; 09112 (args.argv0)++; 09113 } 09114 09115 } 09116 09117 valid = ast_test_flag(&flags, OPT_SILENT); 09118 09119 if ((context = strchr(args.argv0, '@'))) 09120 *context++ = '\0'; 09121 09122 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09123 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09124 else 09125 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09126 09127 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09128 skipuser++; 09129 else 09130 valid = 0; 09131 } 09132 09133 if (!valid) 09134 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09135 09136 ast_debug(1, "After vm_authenticate\n"); 09137 if (!res) { 09138 valid = 1; 09139 if (!skipuser) 09140 vmu = &vmus; 09141 } else { 09142 res = 0; 09143 } 09144 09145 /* If ADSI is supported, setup login screen */ 09146 adsi_begin(chan, &useadsi); 09147 09148 if (!valid) { 09149 goto out; 09150 } 09151 09152 #ifdef IMAP_STORAGE 09153 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 09154 pthread_setspecific(ts_vmstate.key, &vms); 09155 09156 vms.interactive = 1; 09157 vms.updated = 1; 09158 if (vmu) 09159 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 09160 vmstate_insert(&vms); 09161 init_vm_state(&vms); 09162 #endif 09163 if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) { 09164 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 09165 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09166 return -1; 09167 } 09168 if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) { 09169 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 09170 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09171 return -1; 09172 } 09173 09174 /* Set language from config to override channel language */ 09175 if (!ast_strlen_zero(vmu->language)) 09176 ast_string_field_set(chan, language, vmu->language); 09177 09178 /* Retrieve urgent, old and new message counts */ 09179 ast_debug(1, "Before open_mailbox\n"); 09180 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09181 if (res == ERROR_LOCK_PATH) 09182 goto out; 09183 vms.oldmessages = vms.lastmsg + 1; 09184 ast_debug(1, "Number of old messages: %d\n",vms.oldmessages); 09185 /* check INBOX */ 09186 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09187 if (res == ERROR_LOCK_PATH) 09188 goto out; 09189 vms.newmessages = vms.lastmsg + 1; 09190 ast_debug(1, "Number of new messages: %d\n",vms.newmessages); 09191 /* Start in Urgent */ 09192 in_urgent = 1; 09193 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 09194 if (res == ERROR_LOCK_PATH) 09195 goto out; 09196 vms.urgentmessages = vms.lastmsg + 1; 09197 ast_debug(1, "Number of urgent messages: %d\n",vms.urgentmessages); 09198 09199 /* Select proper mailbox FIRST!! */ 09200 if (play_auto) { 09201 if (vms.urgentmessages) { 09202 in_urgent = 1; 09203 res = open_mailbox(&vms, vmu, 11); 09204 } else { 09205 in_urgent = 0; 09206 res = open_mailbox(&vms, vmu, play_folder); 09207 } 09208 if (res == ERROR_LOCK_PATH) 09209 goto out; 09210 09211 /* If there are no new messages, inform the user and hangup */ 09212 if (vms.lastmsg == -1) { 09213 in_urgent = 0; 09214 cmd = vm_browse_messages(chan, &vms, vmu); 09215 res = 0; 09216 goto out; 09217 } 09218 } else { 09219 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 09220 /* If we only have old messages start here */ 09221 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09222 in_urgent = 0; 09223 play_folder = 1; 09224 if (res == ERROR_LOCK_PATH) 09225 goto out; 09226 } else if (!vms.urgentmessages && vms.newmessages) { 09227 /* If we have new messages but none are urgent */ 09228 in_urgent = 0; 09229 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09230 if (res == ERROR_LOCK_PATH) 09231 goto out; 09232 } 09233 } 09234 09235 if (useadsi) 09236 adsi_status(chan, &vms); 09237 res = 0; 09238 09239 /* Check to see if this is a new user */ 09240 if (!strcasecmp(vmu->mailbox, vmu->password) && 09241 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 09242 if (ast_play_and_wait(chan, "vm-newuser") == -1) 09243 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 09244 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 09245 if ((cmd == 't') || (cmd == '#')) { 09246 /* Timeout */ 09247 res = 0; 09248 goto out; 09249 } else if (cmd < 0) { 09250 /* Hangup */ 09251 res = -1; 09252 goto out; 09253 } 09254 } 09255 #ifdef IMAP_STORAGE 09256 ast_debug(3, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit); 09257 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 09258 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 09259 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09260 } 09261 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg); 09262 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 09263 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09264 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09265 } 09266 #endif 09267 if (play_auto) { 09268 cmd = '1'; 09269 } else { 09270 cmd = vm_intro(chan, vmu, &vms); 09271 } 09272 09273 vms.repeats = 0; 09274 vms.starting = 1; 09275 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09276 /* Run main menu */ 09277 switch (cmd) { 09278 case '1': /* First message */ 09279 vms.curmsg = 0; 09280 /* Fall through */ 09281 case '5': /* Play current message */ 09282 cmd = vm_browse_messages(chan, &vms, vmu); 09283 break; 09284 case '2': /* Change folders */ 09285 if (useadsi) 09286 adsi_folders(chan, 0, "Change to folder..."); 09287 cmd = get_folder2(chan, "vm-changeto", 0); 09288 if (cmd == '#') { 09289 cmd = 0; 09290 } else if (cmd > 0) { 09291 cmd = cmd - '0'; 09292 res = close_mailbox(&vms, vmu); 09293 if (res == ERROR_LOCK_PATH) 09294 goto out; 09295 /* If folder is not urgent, set in_urgent to zero! */ 09296 if (cmd != 11) in_urgent = 0; 09297 res = open_mailbox(&vms, vmu, cmd); 09298 if (res == ERROR_LOCK_PATH) 09299 goto out; 09300 play_folder = cmd; 09301 cmd = 0; 09302 } 09303 if (useadsi) 09304 adsi_status2(chan, &vms); 09305 09306 if (!cmd) 09307 cmd = vm_play_folder_name(chan, vms.vmbox); 09308 09309 vms.starting = 1; 09310 break; 09311 case '3': /* Advanced options */ 09312 cmd = 0; 09313 vms.repeats = 0; 09314 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09315 switch (cmd) { 09316 case '1': /* Reply */ 09317 if (vms.lastmsg > -1 && !vms.starting) { 09318 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 09319 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 09320 res = cmd; 09321 goto out; 09322 } 09323 } else 09324 cmd = ast_play_and_wait(chan, "vm-sorry"); 09325 cmd = 't'; 09326 break; 09327 case '2': /* Callback */ 09328 if (!vms.starting) 09329 ast_verb(3, "Callback Requested\n"); 09330 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 09331 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 09332 if (cmd == 9) { 09333 silentexit = 1; 09334 goto out; 09335 } else if (cmd == ERROR_LOCK_PATH) { 09336 res = cmd; 09337 goto out; 09338 } 09339 } else 09340 cmd = ast_play_and_wait(chan, "vm-sorry"); 09341 cmd = 't'; 09342 break; 09343 case '3': /* Envelope */ 09344 if (vms.lastmsg > -1 && !vms.starting) { 09345 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 09346 if (cmd == ERROR_LOCK_PATH) { 09347 res = cmd; 09348 goto out; 09349 } 09350 } else 09351 cmd = ast_play_and_wait(chan, "vm-sorry"); 09352 cmd = 't'; 09353 break; 09354 case '4': /* Dialout */ 09355 if (!ast_strlen_zero(vmu->dialout)) { 09356 cmd = dialout(chan, vmu, NULL, vmu->dialout); 09357 if (cmd == 9) { 09358 silentexit = 1; 09359 goto out; 09360 } 09361 } else 09362 cmd = ast_play_and_wait(chan, "vm-sorry"); 09363 cmd = 't'; 09364 break; 09365 09366 case '5': /* Leave VoiceMail */ 09367 if (ast_test_flag(vmu, VM_SVMAIL)) { 09368 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 09369 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 09370 res = cmd; 09371 goto out; 09372 } 09373 } else 09374 cmd = ast_play_and_wait(chan,"vm-sorry"); 09375 cmd='t'; 09376 break; 09377 09378 case '*': /* Return to main menu */ 09379 cmd = 't'; 09380 break; 09381 09382 default: 09383 cmd = 0; 09384 if (!vms.starting) { 09385 cmd = ast_play_and_wait(chan, "vm-toreply"); 09386 } 09387 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 09388 cmd = ast_play_and_wait(chan, "vm-tocallback"); 09389 } 09390 if (!cmd && !vms.starting) { 09391 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 09392 } 09393 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 09394 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 09395 } 09396 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) 09397 cmd=ast_play_and_wait(chan, "vm-leavemsg"); 09398 if (!cmd) 09399 cmd = ast_play_and_wait(chan, "vm-starmain"); 09400 if (!cmd) 09401 cmd = ast_waitfordigit(chan,6000); 09402 if (!cmd) 09403 vms.repeats++; 09404 if (vms.repeats > 3) 09405 cmd = 't'; 09406 } 09407 } 09408 if (cmd == 't') { 09409 cmd = 0; 09410 vms.repeats = 0; 09411 } 09412 break; 09413 case '4': /* Go to the previous message */ 09414 if (vms.curmsg > 0) { 09415 vms.curmsg--; 09416 cmd = play_message(chan, vmu, &vms); 09417 } else { 09418 /* Check if we were listening to new 09419 messages. If so, go to Urgent messages 09420 instead of saying "no more messages" 09421 */ 09422 if (in_urgent == 0 && vms.urgentmessages > 0) { 09423 /* Check for Urgent messages */ 09424 in_urgent = 1; 09425 res = close_mailbox(&vms, vmu); 09426 if (res == ERROR_LOCK_PATH) 09427 goto out; 09428 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 09429 if (res == ERROR_LOCK_PATH) 09430 goto out; 09431 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n",vms.lastmsg + 1); 09432 vms.curmsg = vms.lastmsg; 09433 if (vms.lastmsg < 0) 09434 cmd = ast_play_and_wait(chan, "vm-nomore"); 09435 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09436 vms.curmsg = vms.lastmsg; 09437 cmd = play_message(chan, vmu, &vms); 09438 } else { 09439 cmd = ast_play_and_wait(chan, "vm-nomore"); 09440 } 09441 } 09442 break; 09443 case '6': /* Go to the next message */ 09444 if (vms.curmsg < vms.lastmsg) { 09445 vms.curmsg++; 09446 cmd = play_message(chan, vmu, &vms); 09447 } else { 09448 if (in_urgent && vms.newmessages > 0) { 09449 /* Check if we were listening to urgent 09450 * messages. If so, go to regular new messages 09451 * instead of saying "no more messages" 09452 */ 09453 in_urgent = 0; 09454 res = close_mailbox(&vms, vmu); 09455 if (res == ERROR_LOCK_PATH) 09456 goto out; 09457 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09458 if (res == ERROR_LOCK_PATH) 09459 goto out; 09460 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09461 vms.curmsg = -1; 09462 if (vms.lastmsg < 0) { 09463 cmd = ast_play_and_wait(chan, "vm-nomore"); 09464 } 09465 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09466 vms.curmsg = 0; 09467 cmd = play_message(chan, vmu, &vms); 09468 } else { 09469 cmd = ast_play_and_wait(chan, "vm-nomore"); 09470 } 09471 } 09472 break; 09473 case '7': /* Delete the current message */ 09474 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 09475 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 09476 if (useadsi) 09477 adsi_delete(chan, &vms); 09478 if (vms.deleted[vms.curmsg]) { 09479 if (play_folder == 0) { 09480 if (in_urgent) { 09481 vms.urgentmessages--; 09482 } else { 09483 vms.newmessages--; 09484 } 09485 } 09486 else if (play_folder == 1) 09487 vms.oldmessages--; 09488 cmd = ast_play_and_wait(chan, "vm-deleted"); 09489 } else { 09490 if (play_folder == 0) { 09491 if (in_urgent) { 09492 vms.urgentmessages++; 09493 } else { 09494 vms.newmessages++; 09495 } 09496 } 09497 else if (play_folder == 1) 09498 vms.oldmessages++; 09499 cmd = ast_play_and_wait(chan, "vm-undeleted"); 09500 } 09501 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 09502 if (vms.curmsg < vms.lastmsg) { 09503 vms.curmsg++; 09504 cmd = play_message(chan, vmu, &vms); 09505 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09506 vms.curmsg = 0; 09507 cmd = play_message(chan, vmu, &vms); 09508 } else { 09509 /* Check if we were listening to urgent 09510 messages. If so, go to regular new messages 09511 instead of saying "no more messages" 09512 */ 09513 if (in_urgent == 1) { 09514 /* Check for new messages */ 09515 in_urgent = 0; 09516 res = close_mailbox(&vms, vmu); 09517 if (res == ERROR_LOCK_PATH) 09518 goto out; 09519 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09520 if (res == ERROR_LOCK_PATH) 09521 goto out; 09522 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09523 vms.curmsg = -1; 09524 if (vms.lastmsg < 0) 09525 cmd = ast_play_and_wait(chan, "vm-nomore"); 09526 } else { 09527 cmd = ast_play_and_wait(chan, "vm-nomore"); 09528 } 09529 } 09530 } 09531 } else /* Delete not valid if we haven't selected a message */ 09532 cmd = 0; 09533 #ifdef IMAP_STORAGE 09534 deleted = 1; 09535 #endif 09536 break; 09537 09538 case '8': /* Forward the current messgae */ 09539 if (vms.lastmsg > -1) { 09540 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 09541 if (cmd == ERROR_LOCK_PATH) { 09542 res = cmd; 09543 goto out; 09544 } 09545 } else { 09546 /* Check if we were listening to urgent 09547 messages. If so, go to regular new messages 09548 instead of saying "no more messages" 09549 */ 09550 if (in_urgent == 1 && vms.newmessages > 0) { 09551 /* Check for new messages */ 09552 in_urgent = 0; 09553 res = close_mailbox(&vms, vmu); 09554 if (res == ERROR_LOCK_PATH) 09555 goto out; 09556 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09557 if (res == ERROR_LOCK_PATH) 09558 goto out; 09559 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09560 vms.curmsg = -1; 09561 if (vms.lastmsg < 0) 09562 cmd = ast_play_and_wait(chan, "vm-nomore"); 09563 } else { 09564 cmd = ast_play_and_wait(chan, "vm-nomore"); 09565 } 09566 } 09567 break; 09568 case '9': /* Save message to folder */ 09569 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 09570 /* No message selected */ 09571 cmd = 0; 09572 break; 09573 } 09574 if (useadsi) 09575 adsi_folders(chan, 1, "Save to folder..."); 09576 cmd = get_folder2(chan, "vm-savefolder", 1); 09577 box = 0; /* Shut up compiler */ 09578 if (cmd == '#') { 09579 cmd = 0; 09580 break; 09581 } else if (cmd > 0) { 09582 box = cmd = cmd - '0'; 09583 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 09584 if (cmd == ERROR_LOCK_PATH) { 09585 res = cmd; 09586 goto out; 09587 #ifndef IMAP_STORAGE 09588 } else if (!cmd) { 09589 vms.deleted[vms.curmsg] = 1; 09590 #endif 09591 } else { 09592 vms.deleted[vms.curmsg] = 0; 09593 vms.heard[vms.curmsg] = 0; 09594 } 09595 } 09596 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 09597 if (useadsi) 09598 adsi_message(chan, &vms); 09599 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box)); 09600 if (!cmd) { 09601 cmd = ast_play_and_wait(chan, "vm-message"); 09602 if (!cmd) 09603 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 09604 if (!cmd) 09605 cmd = ast_play_and_wait(chan, "vm-savedto"); 09606 if (!cmd) 09607 cmd = vm_play_folder_name(chan, vms.fn); 09608 } else { 09609 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09610 } 09611 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 09612 if (vms.curmsg < vms.lastmsg) { 09613 vms.curmsg++; 09614 cmd = play_message(chan, vmu, &vms); 09615 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09616 vms.curmsg = 0; 09617 cmd = play_message(chan, vmu, &vms); 09618 } else { 09619 /* Check if we were listening to urgent 09620 messages. If so, go to regular new messages 09621 instead of saying "no more messages" 09622 */ 09623 if (in_urgent == 1 && vms.newmessages > 0) { 09624 /* Check for new messages */ 09625 in_urgent = 0; 09626 res = close_mailbox(&vms, vmu); 09627 if (res == ERROR_LOCK_PATH) 09628 goto out; 09629 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09630 if (res == ERROR_LOCK_PATH) 09631 goto out; 09632 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09633 vms.curmsg = -1; 09634 if (vms.lastmsg < 0) 09635 cmd = ast_play_and_wait(chan, "vm-nomore"); 09636 } else { 09637 cmd = ast_play_and_wait(chan, "vm-nomore"); 09638 } 09639 } 09640 } 09641 break; 09642 case '*': /* Help */ 09643 if (!vms.starting) { 09644 cmd = ast_play_and_wait(chan, "vm-onefor"); 09645 if (!strncasecmp(chan->language, "he", 2)) { 09646 cmd = ast_play_and_wait(chan, "vm-for"); 09647 } 09648 if (!cmd) 09649 cmd = vm_play_folder_name(chan, vms.vmbox); 09650 if (!cmd) 09651 cmd = ast_play_and_wait(chan, "vm-opts"); 09652 if (!cmd) 09653 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 09654 } else 09655 cmd = 0; 09656 break; 09657 case '0': /* Mailbox options */ 09658 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 09659 if (useadsi) 09660 adsi_status(chan, &vms); 09661 break; 09662 default: /* Nothing */ 09663 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 09664 break; 09665 } 09666 } 09667 if ((cmd == 't') || (cmd == '#')) { 09668 /* Timeout */ 09669 res = 0; 09670 } else { 09671 /* Hangup */ 09672 res = -1; 09673 } 09674 09675 out: 09676 if (res > -1) { 09677 ast_stopstream(chan); 09678 adsi_goodbye(chan); 09679 if (valid && res != OPERATOR_EXIT) { 09680 if (silentexit) 09681 res = ast_play_and_wait(chan, "vm-dialout"); 09682 else 09683 res = ast_play_and_wait(chan, "vm-goodbye"); 09684 } 09685 if ((valid && res > 0) || res == OPERATOR_EXIT) { 09686 res = 0; 09687 } 09688 if (useadsi) 09689 ast_adsi_unload_session(chan); 09690 } 09691 if (vmu) 09692 close_mailbox(&vms, vmu); 09693 if (valid) { 09694 int new = 0, old = 0, urgent = 0; 09695 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 09696 manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 09697 /* Urgent flag not passwd to externnotify here */ 09698 run_externnotify(vmu->context, vmu->mailbox, NULL); 09699 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 09700 queue_mwi_event(ext_context, urgent, new, old); 09701 } 09702 #ifdef IMAP_STORAGE 09703 /* expunge message - use UID Expunge if supported on IMAP server*/ 09704 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup); 09705 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 09706 ast_mutex_lock(&vms.lock); 09707 #ifdef HAVE_IMAP_TK2006 09708 if (LEVELUIDPLUS (vms.mailstream)) { 09709 mail_expunge_full(vms.mailstream,NIL,EX_UID); 09710 } else 09711 #endif 09712 mail_expunge(vms.mailstream); 09713 ast_mutex_unlock(&vms.lock); 09714 } 09715 /* before we delete the state, we should copy pertinent info 09716 * back to the persistent model */ 09717 if (vmu) { 09718 vmstate_delete(&vms); 09719 } 09720 #endif 09721 if (vmu) 09722 free_user(vmu); 09723 if (vms.deleted) 09724 ast_free(vms.deleted); 09725 if (vms.heard) 09726 ast_free(vms.heard); 09727 09728 #ifdef IMAP_STORAGE 09729 pthread_setspecific(ts_vmstate.key, NULL); 09730 #endif 09731 return res; 09732 }
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 | ||
vmfmts | ||
context | ||
record_gain | ||
duration | ||
vms | Presents a prompt for 1 to prepend the current message, 2 to forward the message without prepending, or * to return to the main menu. |
Definition at line 6225 of file app_voicemail.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), chan, CONFIG_FLAG_NOCACHE, config_flags, config_text_file_save(), copy(), INTRO, make_file(), ast_vm_user::maxsecs, and play_record_review().
Referenced by forward_message().
06227 { 06228 #ifdef IMAP_STORAGE 06229 int res; 06230 #endif 06231 int cmd = 0; 06232 int retries = 0, prepend_duration = 0, already_recorded = 0; 06233 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06234 char textfile[PATH_MAX]; 06235 struct ast_config *msg_cfg; 06236 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06237 #ifndef IMAP_STORAGE 06238 signed char zero_gain = 0; 06239 #endif 06240 const char *duration_str; 06241 06242 /* Must always populate duration correctly */ 06243 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06244 strcpy(textfile, msgfile); 06245 strcpy(backup, msgfile); 06246 strcpy(backup_textfile, msgfile); 06247 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06248 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06249 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06250 06251 if ((msg_cfg = ast_config_load(textfile, config_flags)) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06252 *duration = atoi(duration_str); 06253 } else { 06254 *duration = 0; 06255 } 06256 06257 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06258 if (cmd) 06259 retries = 0; 06260 switch (cmd) { 06261 case '1': 06262 06263 #ifdef IMAP_STORAGE 06264 /* Record new intro file */ 06265 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06266 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06267 res = ast_play_and_wait(chan, INTRO); 06268 res = ast_play_and_wait(chan, "beep"); 06269 res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *)duration, NULL, record_gain, vms, flag); 06270 cmd = 't'; 06271 #else 06272 06273 /* prepend a message to the current message, update the metadata and return */ 06274 06275 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06276 strcpy(textfile, msgfile); 06277 strncat(textfile, ".txt", sizeof(textfile) - 1); 06278 *duration = 0; 06279 06280 /* if we can't read the message metadata, stop now */ 06281 if (!msg_cfg) { 06282 cmd = 0; 06283 break; 06284 } 06285 06286 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06287 if (already_recorded) { 06288 ast_filecopy(backup, msgfile, NULL); 06289 copy(backup_textfile, textfile); 06290 } 06291 else { 06292 ast_filecopy(msgfile, backup, NULL); 06293 copy(textfile,backup_textfile); 06294 } 06295 already_recorded = 1; 06296 06297 if (record_gain) 06298 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06299 06300 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence); 06301 if (record_gain) 06302 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06303 06304 06305 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06306 *duration = atoi(duration_str); 06307 06308 if (prepend_duration) { 06309 struct ast_category *msg_cat; 06310 /* need enough space for a maximum-length message duration */ 06311 char duration_buf[12]; 06312 06313 *duration += prepend_duration; 06314 msg_cat = ast_category_get(msg_cfg, "message"); 06315 snprintf(duration_buf, 11, "%ld", *duration); 06316 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06317 config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06318 } 06319 } 06320 06321 #endif 06322 break; 06323 case '2': 06324 /* NULL out introfile so we know there is no intro! */ 06325 #ifdef IMAP_STORAGE 06326 *vms->introfn = '\0'; 06327 #endif 06328 cmd = 't'; 06329 break; 06330 case '*': 06331 cmd = '*'; 06332 break; 06333 default: 06334 cmd = ast_play_and_wait(chan,"vm-forwardoptions"); 06335 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06336 if (!cmd) 06337 cmd = ast_play_and_wait(chan,"vm-starmain"); 06338 /* "press star to return to the main menu" */ 06339 if (!cmd) 06340 cmd = ast_waitfordigit(chan,6000); 06341 if (!cmd) 06342 retries++; 06343 if (retries > 3) 06344 cmd = 't'; 06345 } 06346 } 06347 06348 if (msg_cfg) 06349 ast_config_destroy(msg_cfg); 06350 if (prepend_duration) 06351 *duration = prepend_duration; 06352 06353 if (already_recorded && cmd == -1) { 06354 /* restore original message if prepention cancelled */ 06355 ast_filerename(backup, msgfile, NULL); 06356 rename(backup_textfile, textfile); 06357 } 06358 06359 if (cmd == 't' || cmd == 'S') 06360 cmd = 0; 06361 return cmd; 06362 }
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 8407 of file app_voicemail.c.
References chan, ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
Referenced by vm_execmain().
08408 { 08409 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08410 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 08411 } else { /* Default to ENGLISH */ 08412 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08413 } 08414 }
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 8306 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), chan, 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().
08307 { 08308 int res = 0; 08309 /* Play instructions and wait for new command */ 08310 while (!res) { 08311 if (vms->starting) { 08312 if (vms->lastmsg > -1) { 08313 if (skipadvanced) 08314 res = ast_play_and_wait(chan, "vm-onefor-full"); 08315 else 08316 res = ast_play_and_wait(chan, "vm-onefor"); 08317 if (!res) 08318 res = vm_play_folder_name(chan, vms->vmbox); 08319 } 08320 if (!res) { 08321 if (skipadvanced) 08322 res = ast_play_and_wait(chan, "vm-opts-full"); 08323 else 08324 res = ast_play_and_wait(chan, "vm-opts"); 08325 } 08326 } else { 08327 /* Added for additional help */ 08328 if (skipadvanced) { 08329 res = ast_play_and_wait(chan, "vm-onefor-full"); 08330 if (!res) 08331 res = vm_play_folder_name(chan, vms->vmbox); 08332 res = ast_play_and_wait(chan, "vm-opts-full"); 08333 } 08334 /* Logic: 08335 * If the current message is not the first OR 08336 * if we're listening to the first new message and there are 08337 * also urgent messages, then prompt for navigation to the 08338 * previous message 08339 */ 08340 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 08341 res = ast_play_and_wait(chan, "vm-prev"); 08342 } 08343 if (!res && !skipadvanced) 08344 res = ast_play_and_wait(chan, "vm-advopts"); 08345 if (!res) 08346 res = ast_play_and_wait(chan, "vm-repeat"); 08347 /* Logic: 08348 * If we're not listening to the last message OR 08349 * we're listening to the last urgent message and there are 08350 * also new non-urgent messages, then prompt for navigation 08351 * to the next message 08352 */ 08353 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 08354 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 08355 res = ast_play_and_wait(chan, "vm-next"); 08356 } 08357 if (!res) { 08358 if (!vms->deleted[vms->curmsg]) 08359 res = ast_play_and_wait(chan, "vm-delete"); 08360 else 08361 res = ast_play_and_wait(chan, "vm-undelete"); 08362 if (!res) 08363 res = ast_play_and_wait(chan, "vm-toforward"); 08364 if (!res) 08365 res = ast_play_and_wait(chan, "vm-savemessage"); 08366 } 08367 } 08368 if (!res) { 08369 res = ast_play_and_wait(chan, "vm-helpexit"); 08370 } 08371 if (!res) 08372 res = ast_waitfordigit(chan, 6000); 08373 if (!res) { 08374 vms->repeats++; 08375 if (vms->repeats > 2) { 08376 res = 't'; 08377 } 08378 } 08379 } 08380 return res; 08381 }
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 8383 of file app_voicemail.c.
References ast_play_and_wait(), chan, vm_state::lastmsg, vm_state::starting, vm_instructions_en(), vm_play_folder_name(), and vm_state::vmbox.
Referenced by vm_instructions().
08384 { 08385 int res = 0; 08386 /* Play instructions and wait for new command */ 08387 while (!res) { 08388 if (vms->lastmsg > -1) { 08389 res = ast_play_and_wait(chan, "vm-listen"); 08390 if (!res) 08391 res = vm_play_folder_name(chan, vms->vmbox); 08392 if (!res) 08393 res = ast_play_and_wait(chan, "press"); 08394 if (!res) 08395 res = ast_play_and_wait(chan, "digits/1"); 08396 } 08397 if (!res) 08398 res = ast_play_and_wait(chan, "vm-opts"); 08399 if (!res) { 08400 vms->starting = 0; 08401 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08402 } 08403 } 08404 return res; 08405 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 8246 of file app_voicemail.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, chan, 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_zh(), and VM_TEMPGREETWARN.
Referenced by vm_execmain().
08247 { 08248 char prefile[256]; 08249 08250 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08251 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08252 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08253 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08254 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08255 ast_play_and_wait(chan, "vm-tempgreetactive"); 08256 } 08257 DISPOSE(prefile, -1); 08258 } 08259 08260 /* Play voicemail intro - syntax is different for different languages */ 08261 if (0) { 08262 return 0; 08263 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 08264 return vm_intro_cs(chan, vms); 08265 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 08266 static int deprecation_warning = 0; 08267 if (deprecation_warning++ % 10 == 0) { 08268 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 08269 } 08270 return vm_intro_cs(chan, vms); 08271 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 08272 return vm_intro_de(chan, vms); 08273 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 08274 return vm_intro_es(chan, vms); 08275 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 08276 return vm_intro_fr(chan, vms); 08277 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 08278 return vm_intro_gr(chan, vms); 08279 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 08280 return vm_intro_he(chan, vms); 08281 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 08282 return vm_intro_it(chan, vms); 08283 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 08284 return vm_intro_nl(chan, vms); 08285 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 08286 return vm_intro_no(chan, vms); 08287 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 08288 return vm_intro_pl(chan, vms); 08289 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 08290 return vm_intro_pt_BR(chan, vms); 08291 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 08292 return vm_intro_pt(chan, vms); 08293 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 08294 return vm_intro_multilang(chan, vms, "n"); 08295 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 08296 return vm_intro_se(chan, vms); 08297 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 08298 return vm_intro_multilang(chan, vms, "n"); 08299 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08300 return vm_intro_zh(chan, vms); 08301 } else { /* Default to ENGLISH */ 08302 return vm_intro_en(chan, vms); 08303 } 08304 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8147 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08148 { 08149 int res; 08150 res = ast_play_and_wait(chan, "vm-youhave"); 08151 if (!res) { 08152 if (vms->newmessages) { 08153 if (vms->newmessages == 1) { 08154 res = ast_play_and_wait(chan, "digits/jednu"); 08155 } else { 08156 res = say_and_wait(chan, vms->newmessages, chan->language); 08157 } 08158 if (!res) { 08159 if ((vms->newmessages == 1)) 08160 res = ast_play_and_wait(chan, "vm-novou"); 08161 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08162 res = ast_play_and_wait(chan, "vm-nove"); 08163 if (vms->newmessages > 4) 08164 res = ast_play_and_wait(chan, "vm-novych"); 08165 } 08166 if (vms->oldmessages && !res) 08167 res = ast_play_and_wait(chan, "vm-and"); 08168 else if (!res) { 08169 if ((vms->newmessages == 1)) 08170 res = ast_play_and_wait(chan, "vm-zpravu"); 08171 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08172 res = ast_play_and_wait(chan, "vm-zpravy"); 08173 if (vms->newmessages > 4) 08174 res = ast_play_and_wait(chan, "vm-zprav"); 08175 } 08176 } 08177 if (!res && vms->oldmessages) { 08178 res = say_and_wait(chan, vms->oldmessages, chan->language); 08179 if (!res) { 08180 if ((vms->oldmessages == 1)) 08181 res = ast_play_and_wait(chan, "vm-starou"); 08182 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08183 res = ast_play_and_wait(chan, "vm-stare"); 08184 if (vms->oldmessages > 4) 08185 res = ast_play_and_wait(chan, "vm-starych"); 08186 } 08187 if (!res) { 08188 if ((vms->oldmessages == 1)) 08189 res = ast_play_and_wait(chan, "vm-zpravu"); 08190 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08191 res = ast_play_and_wait(chan, "vm-zpravy"); 08192 if (vms->oldmessages > 4) 08193 res = ast_play_and_wait(chan, "vm-zprav"); 08194 } 08195 } 08196 if (!res) { 08197 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08198 res = ast_play_and_wait(chan, "vm-no"); 08199 if (!res) 08200 res = ast_play_and_wait(chan, "vm-zpravy"); 08201 } 08202 } 08203 } 08204 return res; 08205 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7843 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07844 { 07845 /* Introduce messages they have */ 07846 int res; 07847 res = ast_play_and_wait(chan, "vm-youhave"); 07848 if (!res) { 07849 if (vms->newmessages) { 07850 if ((vms->newmessages == 1)) 07851 res = ast_play_and_wait(chan, "digits/1F"); 07852 else 07853 res = say_and_wait(chan, vms->newmessages, chan->language); 07854 if (!res) 07855 res = ast_play_and_wait(chan, "vm-INBOX"); 07856 if (vms->oldmessages && !res) 07857 res = ast_play_and_wait(chan, "vm-and"); 07858 else if (!res) { 07859 if ((vms->newmessages == 1)) 07860 res = ast_play_and_wait(chan, "vm-message"); 07861 else 07862 res = ast_play_and_wait(chan, "vm-messages"); 07863 } 07864 07865 } 07866 if (!res && vms->oldmessages) { 07867 if (vms->oldmessages == 1) 07868 res = ast_play_and_wait(chan, "digits/1F"); 07869 else 07870 res = say_and_wait(chan, vms->oldmessages, chan->language); 07871 if (!res) 07872 res = ast_play_and_wait(chan, "vm-Old"); 07873 if (!res) { 07874 if (vms->oldmessages == 1) 07875 res = ast_play_and_wait(chan, "vm-message"); 07876 else 07877 res = ast_play_and_wait(chan, "vm-messages"); 07878 } 07879 } 07880 if (!res) { 07881 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07882 res = ast_play_and_wait(chan, "vm-no"); 07883 if (!res) 07884 res = ast_play_and_wait(chan, "vm-messages"); 07885 } 07886 } 07887 } 07888 return res; 07889 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7592 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07593 { 07594 int res; 07595 07596 /* Introduce messages they have */ 07597 res = ast_play_and_wait(chan, "vm-youhave"); 07598 if (!res) { 07599 if (vms->urgentmessages) { 07600 res = say_and_wait(chan, vms->urgentmessages, chan->language); 07601 if (!res) 07602 res = ast_play_and_wait(chan, "vm-Urgent"); 07603 if ((vms->oldmessages || vms->newmessages) && !res) { 07604 res = ast_play_and_wait(chan, "vm-and"); 07605 } else if (!res) { 07606 if ((vms->urgentmessages == 1)) 07607 res = ast_play_and_wait(chan, "vm-message"); 07608 else 07609 res = ast_play_and_wait(chan, "vm-messages"); 07610 } 07611 } 07612 if (vms->newmessages) { 07613 res = say_and_wait(chan, vms->newmessages, chan->language); 07614 if (!res) 07615 res = ast_play_and_wait(chan, "vm-INBOX"); 07616 if (vms->oldmessages && !res) 07617 res = ast_play_and_wait(chan, "vm-and"); 07618 else if (!res) { 07619 if ((vms->newmessages == 1)) 07620 res = ast_play_and_wait(chan, "vm-message"); 07621 else 07622 res = ast_play_and_wait(chan, "vm-messages"); 07623 } 07624 07625 } 07626 if (!res && vms->oldmessages) { 07627 res = say_and_wait(chan, vms->oldmessages, chan->language); 07628 if (!res) 07629 res = ast_play_and_wait(chan, "vm-Old"); 07630 if (!res) { 07631 if (vms->oldmessages == 1) 07632 res = ast_play_and_wait(chan, "vm-message"); 07633 else 07634 res = ast_play_and_wait(chan, "vm-messages"); 07635 } 07636 } 07637 if (!res) { 07638 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 07639 res = ast_play_and_wait(chan, "vm-no"); 07640 if (!res) 07641 res = ast_play_and_wait(chan, "vm-messages"); 07642 } 07643 } 07644 } 07645 return res; 07646 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7892 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07893 { 07894 /* Introduce messages they have */ 07895 int res; 07896 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07897 res = ast_play_and_wait(chan, "vm-youhaveno"); 07898 if (!res) 07899 res = ast_play_and_wait(chan, "vm-messages"); 07900 } else { 07901 res = ast_play_and_wait(chan, "vm-youhave"); 07902 } 07903 if (!res) { 07904 if (vms->newmessages) { 07905 if (!res) { 07906 if ((vms->newmessages == 1)) { 07907 res = ast_play_and_wait(chan, "digits/1M"); 07908 if (!res) 07909 res = ast_play_and_wait(chan, "vm-message"); 07910 if (!res) 07911 res = ast_play_and_wait(chan, "vm-INBOXs"); 07912 } else { 07913 res = say_and_wait(chan, vms->newmessages, chan->language); 07914 if (!res) 07915 res = ast_play_and_wait(chan, "vm-messages"); 07916 if (!res) 07917 res = ast_play_and_wait(chan, "vm-INBOX"); 07918 } 07919 } 07920 if (vms->oldmessages && !res) 07921 res = ast_play_and_wait(chan, "vm-and"); 07922 } 07923 if (vms->oldmessages) { 07924 if (!res) { 07925 if (vms->oldmessages == 1) { 07926 res = ast_play_and_wait(chan, "digits/1M"); 07927 if (!res) 07928 res = ast_play_and_wait(chan, "vm-message"); 07929 if (!res) 07930 res = ast_play_and_wait(chan, "vm-Olds"); 07931 } else { 07932 res = say_and_wait(chan, vms->oldmessages, chan->language); 07933 if (!res) 07934 res = ast_play_and_wait(chan, "vm-messages"); 07935 if (!res) 07936 res = ast_play_and_wait(chan, "vm-Old"); 07937 } 07938 } 07939 } 07940 } 07941 return res; 07942 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7990 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07991 { 07992 /* Introduce messages they have */ 07993 int res; 07994 res = ast_play_and_wait(chan, "vm-youhave"); 07995 if (!res) { 07996 if (vms->newmessages) { 07997 res = say_and_wait(chan, vms->newmessages, chan->language); 07998 if (!res) 07999 res = ast_play_and_wait(chan, "vm-INBOX"); 08000 if (vms->oldmessages && !res) 08001 res = ast_play_and_wait(chan, "vm-and"); 08002 else if (!res) { 08003 if ((vms->newmessages == 1)) 08004 res = ast_play_and_wait(chan, "vm-message"); 08005 else 08006 res = ast_play_and_wait(chan, "vm-messages"); 08007 } 08008 08009 } 08010 if (!res && vms->oldmessages) { 08011 res = say_and_wait(chan, vms->oldmessages, chan->language); 08012 if (!res) 08013 res = ast_play_and_wait(chan, "vm-Old"); 08014 if (!res) { 08015 if (vms->oldmessages == 1) 08016 res = ast_play_and_wait(chan, "vm-message"); 08017 else 08018 res = ast_play_and_wait(chan, "vm-messages"); 08019 } 08020 } 08021 if (!res) { 08022 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08023 res = ast_play_and_wait(chan, "vm-no"); 08024 if (!res) 08025 res = ast_play_and_wait(chan, "vm-messages"); 08026 } 08027 } 08028 } 08029 return res; 08030 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7391 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), chan, ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
07392 { 07393 int res = 0; 07394 07395 if (vms->newmessages) { 07396 res = ast_play_and_wait(chan, "vm-youhave"); 07397 if (!res) 07398 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 07399 if (!res) { 07400 if ((vms->newmessages == 1)) { 07401 res = ast_play_and_wait(chan, "vm-INBOX"); 07402 if (!res) 07403 res = ast_play_and_wait(chan, "vm-message"); 07404 } else { 07405 res = ast_play_and_wait(chan, "vm-INBOXs"); 07406 if (!res) 07407 res = ast_play_and_wait(chan, "vm-messages"); 07408 } 07409 } 07410 } else if (vms->oldmessages){ 07411 res = ast_play_and_wait(chan, "vm-youhave"); 07412 if (!res) 07413 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 07414 if ((vms->oldmessages == 1)){ 07415 res = ast_play_and_wait(chan, "vm-Old"); 07416 if (!res) 07417 res = ast_play_and_wait(chan, "vm-message"); 07418 } else { 07419 res = ast_play_and_wait(chan, "vm-Olds"); 07420 if (!res) 07421 res = ast_play_and_wait(chan, "vm-messages"); 07422 } 07423 } else if (!vms->oldmessages && !vms->newmessages) 07424 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 07425 return res; 07426 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7525 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), chan, ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
07526 { 07527 int res = 0; 07528 07529 /* Introduce messages they have */ 07530 if (!res) { 07531 if ((vms->newmessages) || (vms->oldmessages)) { 07532 res = ast_play_and_wait(chan, "vm-youhave"); 07533 } 07534 /* 07535 * The word "shtei" refers to the number 2 in hebrew when performing a count 07536 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 07537 * an element, this is one of them. 07538 */ 07539 if (vms->newmessages) { 07540 if (!res) { 07541 if (vms->newmessages == 1) { 07542 res = ast_play_and_wait(chan, "vm-INBOX1"); 07543 } else { 07544 if (vms->newmessages == 2) { 07545 res = ast_play_and_wait(chan, "vm-shtei"); 07546 } else { 07547 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07548 } 07549 res = ast_play_and_wait(chan, "vm-INBOX"); 07550 } 07551 } 07552 if (vms->oldmessages && !res) { 07553 res = ast_play_and_wait(chan, "vm-and"); 07554 if (vms->oldmessages == 1) { 07555 res = ast_play_and_wait(chan, "vm-Old1"); 07556 } else { 07557 if (vms->oldmessages == 2) { 07558 res = ast_play_and_wait(chan, "vm-shtei"); 07559 } else { 07560 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07561 } 07562 res = ast_play_and_wait(chan, "vm-Old"); 07563 } 07564 } 07565 } 07566 if (!res && vms->oldmessages && !vms->newmessages) { 07567 if (!res) { 07568 if (vms->oldmessages == 1) { 07569 res = ast_play_and_wait(chan, "vm-Old1"); 07570 } else { 07571 if (vms->oldmessages == 2) { 07572 res = ast_play_and_wait(chan, "vm-shtei"); 07573 } else { 07574 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07575 } 07576 res = ast_play_and_wait(chan, "vm-Old"); 07577 } 07578 } 07579 } 07580 if (!res) { 07581 if (!vms->oldmessages && !vms->newmessages) { 07582 if (!res) { 07583 res = ast_play_and_wait(chan, "vm-nomessages"); 07584 } 07585 } 07586 } 07587 } 07588 return res; 07589 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7649 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07650 { 07651 /* Introduce messages they have */ 07652 int res; 07653 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 07654 res = ast_play_and_wait(chan, "vm-no") || 07655 ast_play_and_wait(chan, "vm-message"); 07656 else 07657 res = ast_play_and_wait(chan, "vm-youhave"); 07658 if (!res && vms->newmessages) { 07659 res = (vms->newmessages == 1) ? 07660 ast_play_and_wait(chan, "digits/un") || 07661 ast_play_and_wait(chan, "vm-nuovo") || 07662 ast_play_and_wait(chan, "vm-message") : 07663 /* 2 or more new messages */ 07664 say_and_wait(chan, vms->newmessages, chan->language) || 07665 ast_play_and_wait(chan, "vm-nuovi") || 07666 ast_play_and_wait(chan, "vm-messages"); 07667 if (!res && vms->oldmessages) 07668 res = ast_play_and_wait(chan, "vm-and"); 07669 } 07670 if (!res && vms->oldmessages) { 07671 res = (vms->oldmessages == 1) ? 07672 ast_play_and_wait(chan, "digits/un") || 07673 ast_play_and_wait(chan, "vm-vecchio") || 07674 ast_play_and_wait(chan, "vm-message") : 07675 /* 2 or more old messages */ 07676 say_and_wait(chan, vms->oldmessages, chan->language) || 07677 ast_play_and_wait(chan, "vm-vecchi") || 07678 ast_play_and_wait(chan, "vm-messages"); 07679 } 07680 return res; 07681 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 7485 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), chan, ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_intro().
07486 { 07487 int res; 07488 int lastnum = 0; 07489 07490 res = ast_play_and_wait(chan, "vm-youhave"); 07491 07492 if (!res && vms->newmessages) { 07493 lastnum = vms->newmessages; 07494 07495 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 07496 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 07497 } 07498 07499 if (!res && vms->oldmessages) { 07500 res = ast_play_and_wait(chan, "vm-and"); 07501 } 07502 } 07503 07504 if (!res && vms->oldmessages) { 07505 lastnum = vms->oldmessages; 07506 07507 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 07508 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 07509 } 07510 } 07511 07512 if (!res) { 07513 if (lastnum == 0) { 07514 res = ast_play_and_wait(chan, "vm-no"); 07515 } 07516 if (!res) { 07517 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 07518 } 07519 } 07520 07521 return res; 07522 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8033 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
08034 { 08035 /* Introduce messages they have */ 08036 int res; 08037 res = ast_play_and_wait(chan, "vm-youhave"); 08038 if (!res) { 08039 if (vms->newmessages) { 08040 res = say_and_wait(chan, vms->newmessages, chan->language); 08041 if (!res) { 08042 if (vms->newmessages == 1) 08043 res = ast_play_and_wait(chan, "vm-INBOXs"); 08044 else 08045 res = ast_play_and_wait(chan, "vm-INBOX"); 08046 } 08047 if (vms->oldmessages && !res) 08048 res = ast_play_and_wait(chan, "vm-and"); 08049 else if (!res) { 08050 if ((vms->newmessages == 1)) 08051 res = ast_play_and_wait(chan, "vm-message"); 08052 else 08053 res = ast_play_and_wait(chan, "vm-messages"); 08054 } 08055 08056 } 08057 if (!res && vms->oldmessages) { 08058 res = say_and_wait(chan, vms->oldmessages, chan->language); 08059 if (!res) { 08060 if (vms->oldmessages == 1) 08061 res = ast_play_and_wait(chan, "vm-Olds"); 08062 else 08063 res = ast_play_and_wait(chan, "vm-Old"); 08064 } 08065 if (!res) { 08066 if (vms->oldmessages == 1) 08067 res = ast_play_and_wait(chan, "vm-message"); 08068 else 08069 res = ast_play_and_wait(chan, "vm-messages"); 08070 } 08071 } 08072 if (!res) { 08073 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08074 res = ast_play_and_wait(chan, "vm-no"); 08075 if (!res) 08076 res = ast_play_and_wait(chan, "vm-messages"); 08077 } 08078 } 08079 } 08080 return res; 08081 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7799 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07800 { 07801 /* Introduce messages they have */ 07802 int res; 07803 07804 res = ast_play_and_wait(chan, "vm-youhave"); 07805 if (res) 07806 return res; 07807 07808 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07809 res = ast_play_and_wait(chan, "vm-no"); 07810 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07811 return res; 07812 } 07813 07814 if (vms->newmessages) { 07815 if ((vms->newmessages == 1)) { 07816 res = ast_play_and_wait(chan, "digits/1"); 07817 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 07818 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07819 } else { 07820 res = say_and_wait(chan, vms->newmessages, chan->language); 07821 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 07822 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07823 } 07824 if (!res && vms->oldmessages) 07825 res = ast_play_and_wait(chan, "vm-and"); 07826 } 07827 if (!res && vms->oldmessages) { 07828 if (vms->oldmessages == 1) { 07829 res = ast_play_and_wait(chan, "digits/1"); 07830 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 07831 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07832 } else { 07833 res = say_and_wait(chan, vms->oldmessages, chan->language); 07834 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 07835 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07836 } 07837 } 07838 07839 return res; 07840 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7684 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, num, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
07685 { 07686 /* Introduce messages they have */ 07687 int res; 07688 div_t num; 07689 07690 if (!vms->oldmessages && !vms->newmessages) { 07691 res = ast_play_and_wait(chan, "vm-no"); 07692 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07693 return res; 07694 } else { 07695 res = ast_play_and_wait(chan, "vm-youhave"); 07696 } 07697 07698 if (vms->newmessages) { 07699 num = div(vms->newmessages, 10); 07700 if (vms->newmessages == 1) { 07701 res = ast_play_and_wait(chan, "digits/1-a"); 07702 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 07703 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07704 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07705 if (num.rem == 2) { 07706 if (!num.quot) { 07707 res = ast_play_and_wait(chan, "digits/2-ie"); 07708 } else { 07709 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 07710 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07711 } 07712 } else { 07713 res = say_and_wait(chan, vms->newmessages, chan->language); 07714 } 07715 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 07716 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07717 } else { 07718 res = say_and_wait(chan, vms->newmessages, chan->language); 07719 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 07720 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07721 } 07722 if (!res && vms->oldmessages) 07723 res = ast_play_and_wait(chan, "vm-and"); 07724 } 07725 if (!res && vms->oldmessages) { 07726 num = div(vms->oldmessages, 10); 07727 if (vms->oldmessages == 1) { 07728 res = ast_play_and_wait(chan, "digits/1-a"); 07729 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 07730 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07731 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07732 if (num.rem == 2) { 07733 if (!num.quot) { 07734 res = ast_play_and_wait(chan, "digits/2-ie"); 07735 } else { 07736 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 07737 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07738 } 07739 } else { 07740 res = say_and_wait(chan, vms->oldmessages, chan->language); 07741 } 07742 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 07743 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07744 } else { 07745 res = say_and_wait(chan, vms->oldmessages, chan->language); 07746 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 07747 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07748 } 07749 } 07750 07751 return res; 07752 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8084 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
08085 { 08086 /* Introduce messages they have */ 08087 int res; 08088 res = ast_play_and_wait(chan, "vm-youhave"); 08089 if (!res) { 08090 if (vms->newmessages) { 08091 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08092 if (!res) { 08093 if ((vms->newmessages == 1)) { 08094 res = ast_play_and_wait(chan, "vm-message"); 08095 if (!res) 08096 res = ast_play_and_wait(chan, "vm-INBOXs"); 08097 } else { 08098 res = ast_play_and_wait(chan, "vm-messages"); 08099 if (!res) 08100 res = ast_play_and_wait(chan, "vm-INBOX"); 08101 } 08102 } 08103 if (vms->oldmessages && !res) 08104 res = ast_play_and_wait(chan, "vm-and"); 08105 } 08106 if (!res && vms->oldmessages) { 08107 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08108 if (!res) { 08109 if (vms->oldmessages == 1) { 08110 res = ast_play_and_wait(chan, "vm-message"); 08111 if (!res) 08112 res = ast_play_and_wait(chan, "vm-Olds"); 08113 } else { 08114 res = ast_play_and_wait(chan, "vm-messages"); 08115 if (!res) 08116 res = ast_play_and_wait(chan, "vm-Old"); 08117 } 08118 } 08119 } 08120 if (!res) { 08121 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08122 res = ast_play_and_wait(chan, "vm-no"); 08123 if (!res) 08124 res = ast_play_and_wait(chan, "vm-messages"); 08125 } 08126 } 08127 } 08128 return res; 08129 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7945 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.
Referenced by vm_intro().
07945 { 07946 /* Introduce messages they have */ 07947 int res; 07948 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07949 res = ast_play_and_wait(chan, "vm-nomessages"); 07950 return res; 07951 } else { 07952 res = ast_play_and_wait(chan, "vm-youhave"); 07953 } 07954 if (vms->newmessages) { 07955 if (!res) 07956 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07957 if ((vms->newmessages == 1)) { 07958 if (!res) 07959 res = ast_play_and_wait(chan, "vm-message"); 07960 if (!res) 07961 res = ast_play_and_wait(chan, "vm-INBOXs"); 07962 } else { 07963 if (!res) 07964 res = ast_play_and_wait(chan, "vm-messages"); 07965 if (!res) 07966 res = ast_play_and_wait(chan, "vm-INBOX"); 07967 } 07968 if (vms->oldmessages && !res) 07969 res = ast_play_and_wait(chan, "vm-and"); 07970 } 07971 if (vms->oldmessages) { 07972 if (!res) 07973 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07974 if (vms->oldmessages == 1) { 07975 if (!res) 07976 res = ast_play_and_wait(chan, "vm-message"); 07977 if (!res) 07978 res = ast_play_and_wait(chan, "vm-Olds"); 07979 } else { 07980 if (!res) 07981 res = ast_play_and_wait(chan, "vm-messages"); 07982 if (!res) 07983 res = ast_play_and_wait(chan, "vm-Old"); 07984 } 07985 } 07986 return res; 07987 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7755 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.
Referenced by vm_intro().
07756 { 07757 /* Introduce messages they have */ 07758 int res; 07759 07760 res = ast_play_and_wait(chan, "vm-youhave"); 07761 if (res) 07762 return res; 07763 07764 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07765 res = ast_play_and_wait(chan, "vm-no"); 07766 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07767 return res; 07768 } 07769 07770 if (vms->newmessages) { 07771 if ((vms->newmessages == 1)) { 07772 res = ast_play_and_wait(chan, "digits/ett"); 07773 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 07774 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07775 } else { 07776 res = say_and_wait(chan, vms->newmessages, chan->language); 07777 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 07778 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07779 } 07780 if (!res && vms->oldmessages) 07781 res = ast_play_and_wait(chan, "vm-and"); 07782 } 07783 if (!res && vms->oldmessages) { 07784 if (vms->oldmessages == 1) { 07785 res = ast_play_and_wait(chan, "digits/ett"); 07786 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 07787 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07788 } else { 07789 res = say_and_wait(chan, vms->oldmessages, chan->language); 07790 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 07791 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07792 } 07793 } 07794 07795 return res; 07796 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8208 of file app_voicemail.c.
References ast_play_and_wait(), chan, ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
Referenced by vm_intro().
08209 { 08210 int res; 08211 /* Introduce messages they have */ 08212 res = ast_play_and_wait(chan, "vm-you"); 08213 08214 if (!res && vms->newmessages) { 08215 res = ast_play_and_wait(chan, "vm-have"); 08216 if (!res) 08217 res = say_and_wait(chan, vms->newmessages, chan->language); 08218 if (!res) 08219 res = ast_play_and_wait(chan, "vm-tong"); 08220 if (!res) 08221 res = ast_play_and_wait(chan, "vm-INBOX"); 08222 if (vms->oldmessages && !res) 08223 res = ast_play_and_wait(chan, "vm-and"); 08224 else if (!res) 08225 res = ast_play_and_wait(chan, "vm-messages"); 08226 } 08227 if (!res && vms->oldmessages) { 08228 res = ast_play_and_wait(chan, "vm-have"); 08229 if (!res) 08230 res = say_and_wait(chan, vms->oldmessages, chan->language); 08231 if (!res) 08232 res = ast_play_and_wait(chan, "vm-tong"); 08233 if (!res) 08234 res = ast_play_and_wait(chan, "vm-Old"); 08235 if (!res) 08236 res = ast_play_and_wait(chan, "vm-messages"); 08237 } 08238 if (!res && !vms->oldmessages && !vms->newmessages) { 08239 res = ast_play_and_wait(chan, "vm-haveno"); 08240 if (!res) 08241 res = ast_play_and_wait(chan, "vm-messages"); 08242 } 08243 return res; 08244 }
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 2873 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
02874 { 02875 switch (ast_lock_path(path)) { 02876 case AST_LOCK_TIMEOUT: 02877 return -1; 02878 default: 02879 return 0; 02880 } 02881 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1360 of file app_voicemail.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01361 { 01362 FILE *p = NULL; 01363 int pfd = mkstemp(template); 01364 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01365 if (pfd > -1) { 01366 p = fdopen(pfd, "w+"); 01367 if (!p) { 01368 close(pfd); 01369 pfd = -1; 01370 } 01371 } 01372 return p; 01373 }
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 8417 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, chan, 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().
08418 { 08419 int cmd = 0; 08420 int duration = 0; 08421 int tries = 0; 08422 char newpassword[80] = ""; 08423 char newpassword2[80] = ""; 08424 char prefile[PATH_MAX] = ""; 08425 unsigned char buf[256]; 08426 int bytes=0; 08427 08428 if (ast_adsi_available(chan)) { 08429 bytes += adsi_logo(buf + bytes); 08430 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 08431 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08432 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08433 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08434 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08435 } 08436 08437 /* First, have the user change their password 08438 so they won't get here again */ 08439 for (;;) { 08440 newpassword[1] = '\0'; 08441 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08442 if (cmd == '#') 08443 newpassword[0] = '\0'; 08444 if (cmd < 0 || cmd == 't' || cmd == '#') 08445 return cmd; 08446 cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#"); 08447 if (cmd < 0 || cmd == 't' || cmd == '#') 08448 return cmd; 08449 cmd = check_password(vmu, newpassword); /* perform password validation */ 08450 if (cmd != 0) { 08451 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 08452 cmd = ast_play_and_wait(chan, vm_invalid_password); 08453 } else { 08454 newpassword2[1] = '\0'; 08455 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 08456 if (cmd == '#') 08457 newpassword2[0] = '\0'; 08458 if (cmd < 0 || cmd == 't' || cmd == '#') 08459 return cmd; 08460 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 08461 if (cmd < 0 || cmd == 't' || cmd == '#') 08462 return cmd; 08463 if (!strcmp(newpassword, newpassword2)) 08464 break; 08465 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 08466 cmd = ast_play_and_wait(chan, vm_mismatch); 08467 } 08468 if (++tries == 3) 08469 return -1; 08470 if (cmd != 0) { 08471 cmd = ast_play_and_wait(chan, vm_pls_try_again); 08472 } 08473 } 08474 if (pwdchange & PWDCHANGE_INTERNAL) 08475 vm_change_password(vmu, newpassword); 08476 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 08477 vm_change_password_shell(vmu, newpassword); 08478 08479 ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword)); 08480 cmd = ast_play_and_wait(chan, vm_passchanged); 08481 08482 /* If forcename is set, have the user record their name */ 08483 if (ast_test_flag(vmu, VM_FORCENAME)) { 08484 snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 08485 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08486 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08487 if (cmd < 0 || cmd == 't' || cmd == '#') 08488 return cmd; 08489 } 08490 } 08491 08492 /* If forcegreetings is set, have the user record their greetings */ 08493 if (ast_test_flag(vmu, VM_FORCEGREET)) { 08494 snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 08495 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08496 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08497 if (cmd < 0 || cmd == 't' || cmd == '#') 08498 return cmd; 08499 } 08500 08501 snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 08502 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08503 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08504 if (cmd < 0 || cmd == 't' || cmd == '#') 08505 return cmd; 08506 } 08507 } 08508 08509 return cmd; 08510 }
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 8512 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(), chan, 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().
08513 { 08514 int cmd = 0; 08515 int retries = 0; 08516 int duration = 0; 08517 char newpassword[80] = ""; 08518 char newpassword2[80] = ""; 08519 char prefile[PATH_MAX] = ""; 08520 unsigned char buf[256]; 08521 int bytes=0; 08522 08523 if (ast_adsi_available(chan)) { 08524 bytes += adsi_logo(buf + bytes); 08525 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 08526 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08527 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08528 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08529 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08530 } 08531 while ((cmd >= 0) && (cmd != 't')) { 08532 if (cmd) 08533 retries = 0; 08534 switch (cmd) { 08535 case '1': /* Record your unavailable message */ 08536 snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 08537 cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08538 break; 08539 case '2': /* Record your busy message */ 08540 snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 08541 cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08542 break; 08543 case '3': /* Record greeting */ 08544 snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 08545 cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08546 break; 08547 case '4': /* manage the temporary greeting */ 08548 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 08549 break; 08550 case '5': /* change password */ 08551 if (vmu->password[0] == '-') { 08552 cmd = ast_play_and_wait(chan, "vm-no"); 08553 break; 08554 } 08555 newpassword[1] = '\0'; 08556 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08557 if (cmd == '#') 08558 newpassword[0] = '\0'; 08559 else { 08560 if (cmd < 0) 08561 break; 08562 if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) { 08563 break; 08564 } 08565 } 08566 cmd = check_password(vmu, newpassword); /* perform password validation */ 08567 if (cmd != 0) { 08568 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 08569 cmd = ast_play_and_wait(chan, vm_invalid_password); 08570 if (!cmd) { 08571 cmd = ast_play_and_wait(chan, vm_pls_try_again); 08572 } 08573 break; 08574 } 08575 newpassword2[1] = '\0'; 08576 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 08577 if (cmd == '#') 08578 newpassword2[0] = '\0'; 08579 else { 08580 if (cmd < 0) 08581 break; 08582 08583 if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) { 08584 break; 08585 } 08586 } 08587 if (strcmp(newpassword, newpassword2)) { 08588 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 08589 cmd = ast_play_and_wait(chan, vm_mismatch); 08590 if (!cmd) { 08591 cmd = ast_play_and_wait(chan, vm_pls_try_again); 08592 } 08593 break; 08594 } 08595 if (pwdchange & PWDCHANGE_INTERNAL) 08596 vm_change_password(vmu, newpassword); 08597 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 08598 vm_change_password_shell(vmu, newpassword); 08599 08600 ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword)); 08601 cmd = ast_play_and_wait(chan, vm_passchanged); 08602 break; 08603 case '*': 08604 cmd = 't'; 08605 break; 08606 default: 08607 cmd = 0; 08608 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08609 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08610 if (ast_fileexists(prefile, NULL, NULL)) { 08611 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 08612 } 08613 DISPOSE(prefile, -1); 08614 if (!cmd) { 08615 cmd = ast_play_and_wait(chan, "vm-options"); 08616 } 08617 if (!cmd) { 08618 cmd = ast_waitfordigit(chan,6000); 08619 } 08620 if (!cmd) { 08621 retries++; 08622 } 08623 if (retries > 3) { 08624 cmd = 't'; 08625 } 08626 } 08627 } 08628 if (cmd == 't') 08629 cmd = 0; 08630 return cmd; 08631 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 7356 of file app_voicemail.c.
References ast_play_and_wait(), chan, 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().
07357 { 07358 int cmd; 07359 07360 if ( !strncasecmp(chan->language, "it", 2) || 07361 !strncasecmp(chan->language, "es", 2) || 07362 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 07363 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07364 return cmd ? cmd : ast_play_and_wait(chan, box); 07365 } else if (!strncasecmp(chan->language, "gr", 2)) { 07366 return vm_play_folder_name_gr(chan, box); 07367 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 07368 return ast_play_and_wait(chan, box); 07369 } else if (!strncasecmp(chan->language, "pl", 2)) { 07370 return vm_play_folder_name_pl(chan, box); 07371 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 07372 return vm_play_folder_name_ua(chan, box); 07373 } else { /* Default English */ 07374 cmd = ast_play_and_wait(chan, box); 07375 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07376 } 07377 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7309 of file app_voicemail.c.
References ast_play_and_wait(), and chan.
Referenced by vm_play_folder_name().
07310 { 07311 int cmd; 07312 char *buf; 07313 07314 buf = alloca(strlen(box)+2); 07315 strcpy(buf, box); 07316 strcat(buf,"s"); 07317 07318 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 07319 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 07320 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07321 } else { 07322 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07323 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 07324 } 07325 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7327 of file app_voicemail.c.
References ast_play_and_wait(), and chan.
Referenced by vm_play_folder_name().
07328 { 07329 int cmd; 07330 07331 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 07332 if (!strcasecmp(box, "vm-INBOX")) 07333 cmd = ast_play_and_wait(chan, "vm-new-e"); 07334 else 07335 cmd = ast_play_and_wait(chan, "vm-old-e"); 07336 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07337 } else { 07338 cmd = ast_play_and_wait(chan, "vm-messages"); 07339 return cmd ? cmd : ast_play_and_wait(chan, box); 07340 } 07341 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7343 of file app_voicemail.c.
References ast_play_and_wait(), and chan.
Referenced by vm_play_folder_name().
07344 { 07345 int cmd; 07346 07347 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 07348 cmd = ast_play_and_wait(chan, "vm-messages"); 07349 return cmd ? cmd : ast_play_and_wait(chan, box); 07350 } else { 07351 cmd = ast_play_and_wait(chan, box); 07352 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07353 } 07354 }
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 8649 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(), chan, ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.
Referenced by vm_options().
08650 { 08651 int cmd = 0; 08652 int retries = 0; 08653 int duration = 0; 08654 char prefile[PATH_MAX] = ""; 08655 unsigned char buf[256]; 08656 int bytes = 0; 08657 08658 if (ast_adsi_available(chan)) { 08659 bytes += adsi_logo(buf + bytes); 08660 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 08661 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08662 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08663 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08664 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08665 } 08666 08667 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08668 while ((cmd >= 0) && (cmd != 't')) { 08669 if (cmd) 08670 retries = 0; 08671 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08672 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 08673 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08674 cmd = 't'; 08675 } else { 08676 switch (cmd) { 08677 case '1': 08678 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08679 break; 08680 case '2': 08681 DELETE(prefile, -1, prefile, vmu); 08682 ast_play_and_wait(chan, "vm-tempremoved"); 08683 cmd = 't'; 08684 break; 08685 case '*': 08686 cmd = 't'; 08687 break; 08688 default: 08689 cmd = ast_play_and_wait(chan, 08690 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 08691 "vm-tempgreeting2" : "vm-tempgreeting"); 08692 if (!cmd) 08693 cmd = ast_waitfordigit(chan,6000); 08694 if (!cmd) 08695 retries++; 08696 if (retries > 3) 08697 cmd = 't'; 08698 } 08699 } 08700 DISPOSE(prefile, -1); 08701 } 08702 if (cmd == 't') 08703 cmd = 0; 08704 return cmd; 08705 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9938 of file app_voicemail.c.
References ast_copy_string(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), chan, ast_vm_user::context, pbx_builtin_setvar_helper(), s, strsep(), and vm_authenticate().
Referenced by load_module().
09939 { 09940 char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = ""; 09941 struct ast_vm_user vmus; 09942 char *options = NULL; 09943 int silent = 0, skipuser = 0; 09944 int res = -1; 09945 09946 if (s) { 09947 s = ast_strdupa(s); 09948 user = strsep(&s, ","); 09949 options = strsep(&s, ","); 09950 if (user) { 09951 s = user; 09952 user = strsep(&s, "@"); 09953 context = strsep(&s, ""); 09954 if (!ast_strlen_zero(user)) 09955 skipuser++; 09956 ast_copy_string(mailbox, user, sizeof(mailbox)); 09957 } 09958 } 09959 09960 if (options) { 09961 silent = (strchr(options, 's')) != NULL; 09962 } 09963 09964 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 09965 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 09966 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 09967 ast_play_and_wait(chan, "auth-thankyou"); 09968 res = 0; 09969 } 09970 09971 return res; 09972 }
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. Return tm so it can be used as a function argument.
Definition at line 3970 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().
03971 { 03972 const struct vm_zone *z = NULL; 03973 struct timeval t = ast_tvnow(); 03974 03975 /* Does this user have a timezone specified? */ 03976 if (!ast_strlen_zero(vmu->zonetag)) { 03977 /* Find the zone in the list */ 03978 AST_LIST_LOCK(&zones); 03979 AST_LIST_TRAVERSE(&zones, z, list) { 03980 if (!strcmp(z->name, vmu->zonetag)) 03981 break; 03982 } 03983 AST_LIST_UNLOCK(&zones); 03984 } 03985 ast_localtime(&t, tm, z ? z->timezone : NULL); 03986 return tm; 03987 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 6768 of file app_voicemail.c.
References ast_control_streamfile(), chan, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, and listen_control_stop_key.
06769 { 06770 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); 06771 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 6760 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_log(), ast_stream_and_wait(), and chan.
Referenced by play_message(), play_message_callerid(), and play_message_duration().
06761 { 06762 int res; 06763 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 06764 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 06765 return res; 06766 }
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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 11759 of file app_voicemail.c.
char* addesc = "Comedian Mail" [static] |
Definition at line 513 of file app_voicemail.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 706 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 708 of file app_voicemail.c.
Referenced by adsi_begin(), adsi_load_vmail(), and load_config().
char* app = "VoiceMail" [static] |
Definition at line 598 of file app_voicemail.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 601 of file app_voicemail.c.
char* app3 = "MailboxExists" [static] |
Definition at line 603 of file app_voicemail.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 604 of file app_voicemail.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 11759 of file app_voicemail.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 692 of file app_voicemail.c.
Referenced by load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 704 of file app_voicemail.c.
Referenced by encode_mime_str(), load_config(), make_email_file(), and tds_load_module().
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 695 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 10170 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* descrip_vm [static] |
Definition at line 517 of file app_voicemail.c.
char* descrip_vm_box_exists [static] |
Definition at line 575 of file app_voicemail.c.
char* descrip_vmain [static] |
Definition at line 546 of file app_voicemail.c.
char* descrip_vmauthenticate [static] |
Definition at line 587 of file app_voicemail.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 691 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 698 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 709 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 693 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 493 of file app_voicemail.c.
char ext_pass_cmd[128] [static] |
Definition at line 492 of file app_voicemail.c.
char externnotify[160] [static] |
Definition at line 615 of file app_voicemail.c.
char fromstring[100] [static] |
Definition at line 702 of file app_voicemail.c.
Referenced by load_config(), make_email_file(), and sendpage().
struct ast_flags globalflags = {0} [static] |
Definition at line 687 of file app_voicemail.c.
struct ao2_container* inprocess_container |
Definition at line 726 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] |
struct ast_custom_function mailbox_exists_acf [static] |
char mailcmd[160] [static] |
Definition at line 614 of file app_voicemail.c.
int maxdeletedmsg [static] |
Definition at line 611 of file app_voicemail.c.
int maxgreet [static] |
Definition at line 621 of file app_voicemail.c.
int maxlogins [static] |
Definition at line 623 of file app_voicemail.c.
int maxmsg [static] |
Definition at line 610 of file app_voicemail.c.
int maxsilence [static] |
int minpassword [static] |
Definition at line 624 of file app_voicemail.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 641 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 667 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 643 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
int my_umask [static] |
Definition at line 495 of file app_voicemail.c.
char* pagerbody = NULL [static] |
char pagerfromstring[100] [static] |
char* pagersubject = NULL [static] |
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 636 of file app_voicemail.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 631 of file app_voicemail.c.
ast_mutex_t poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 635 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 628 of file app_voicemail.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 637 of file app_voicemail.c.
unsigned char poll_thread_run [static] |
Definition at line 638 of file app_voicemail.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 499 of file app_voicemail.c.
int saydurationminfo [static] |
Definition at line 689 of file app_voicemail.c.
Referenced by load_config(), and populate_defaults().
char serveremail[80] [static] |
Definition at line 613 of file app_voicemail.c.
int silencethreshold = 128 [static] |
Definition at line 612 of file app_voicemail.c.
int skipms [static] |
Definition at line 622 of file app_voicemail.c.
Referenced by controlplayback_exec(), and handle_controlstreamfile().
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 616 of file app_voicemail.c.
Referenced by load_config(), and run_externnotify().
char* synopsis_vm = "Leave a Voicemail message" [static] |
Definition at line 515 of file app_voicemail.c.
char* synopsis_vm_box_exists [static] |
Initial value:
"Check to see if Voicemail mailbox exists"
Definition at line 572 of file app_voicemail.c.
char* synopsis_vmain = "Check Voicemail messages" [static] |
Definition at line 544 of file app_voicemail.c.
char* synopsis_vmauthenticate = "Authenticate with Voicemail passwords" [static] |
Definition at line 585 of file app_voicemail.c.
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] |
enum { ... } vm_box |
char vm_invalid_password[80] = "vm-invalid-password" [static] |
Definition at line 684 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 683 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 680 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
enum { ... } vm_option_args |
enum { ... } vm_option_flags |
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 681 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 685 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 682 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 490 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 617 of file app_voicemail.c.
int vmmaxsecs [static] |
Definition at line 620 of file app_voicemail.c.
int vmminsecs [static] |
Definition at line 619 of file app_voicemail.c.
double volgain [static] |
Definition at line 618 of file app_voicemail.c.
char zonetag[80] [static] |