#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/event.h"
#include "asterisk/taskprocessor.h"
Go to the source code of this file.
Data Structures | |
struct | ast_vm_user |
struct | baseio |
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 | eol "\r\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 | 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 | 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_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 (const char *input, char *buf, size_t buflen) |
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_tw (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_tw (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_cz (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_tw (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} |
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_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 183 of file app_voicemail.c.
#define BASELINELEN 72 |
#define BASEMAXINLINE 256 |
#define CHUNKSIZE 65536 |
Definition at line 180 of file app_voicemail.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 176 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 606 of file app_voicemail.c.
Referenced by load_config().
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 470 of file app_voicemail.c.
Referenced by notify_new_message(), play_record_review(), and vm_tempgreeting().
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 465 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" |
Referenced by add_email_attachment(), and make_email_file().
#define eol "\r\n" |
#define ERROR_LOCK_PATH -100 |
Definition at line 232 of file app_voicemail.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 467 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 199 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
#define MAX_DATETIME_FORMAT 512 |
Definition at line 210 of file app_voicemail.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 211 of file app_voicemail.c.
#define MAXMSG 100 |
#define MAXMSGLIMIT 9999 |
Definition at line 202 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 204 of file app_voicemail.c.
Referenced by load_config().
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 482 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 481 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 468 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), and save_to_folder().
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 464 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 197 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 466 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 491 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 226 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 224 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 225 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 223 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 217 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 221 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 220 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 231 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 230 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 229 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 214 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 222 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 213 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 215 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 218 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 227 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 219 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 216 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 228 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_intro().
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 409 of file app_voicemail.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 182 of file app_voicemail.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 178 of file app_voicemail.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 179 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
anonymous enum |
Definition at line 235 of file app_voicemail.c.
00235 { 00236 NEW_FOLDER, 00237 OLD_FOLDER, 00238 WORK_FOLDER, 00239 FAMILY_FOLDER, 00240 FRIENDS_FOLDER, 00241 GREETINGS_FOLDER 00242 } 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 244 of file app_voicemail.c.
00244 { 00245 OPT_SILENT = (1 << 0), 00246 OPT_BUSY_GREETING = (1 << 1), 00247 OPT_UNAVAIL_GREETING = (1 << 2), 00248 OPT_RECORDGAIN = (1 << 3), 00249 OPT_PREPEND_MAILBOX = (1 << 4), 00250 OPT_AUTOPLAY = (1 << 6), 00251 OPT_DTMFEXIT = (1 << 7), 00252 OPT_MESSAGE_Urgent = (1 << 8), 00253 OPT_MESSAGE_PRIORITY = (1 << 9) 00254 } vm_option_flags;
anonymous enum |
Definition at line 256 of file app_voicemail.c.
00256 { 00257 OPT_ARG_RECORDGAIN = 0, 00258 OPT_ARG_PLAYFOLDER = 1, 00259 OPT_ARG_DTMFEXIT = 2, 00260 /* This *must* be the last value in this enum! */ 00261 OPT_ARG_ARRAY_SIZE = 3, 00262 } vm_option_args;
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 4674 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
04675 { 04676 DIR *dir; 04677 struct dirent *de; 04678 char fn[256]; 04679 int ret = 0; 04680 04681 /* If no mailbox, return immediately */ 04682 if (ast_strlen_zero(mailbox)) 04683 return 0; 04684 04685 if (ast_strlen_zero(folder)) 04686 folder = "INBOX"; 04687 if (ast_strlen_zero(context)) 04688 context = "default"; 04689 04690 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 04691 04692 if (!(dir = opendir(fn))) 04693 return 0; 04694 04695 while ((de = readdir(dir))) { 04696 if (!strncasecmp(de->d_name, "msg", 3)) { 04697 if (shortcircuit) { 04698 ret = 1; 04699 break; 04700 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 04701 if (shortcircuit) return 1; 04702 ret++; 04703 } 04704 } 04705 } 04706 04707 closedir(dir); 04708 04709 /* If we are checking INBOX, we should check Urgent as well */ 04710 if (strcmp(folder, "INBOX") == 0) { 04711 return (ret + __has_voicemail(context, mailbox, "Urgent", shortcircuit)); 04712 } else { 04713 return ret; 04714 } 04715 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 11463 of file app_voicemail.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 11463 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 9636 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().
09637 { 09638 struct ast_vm_user svm; 09639 AST_DECLARE_APP_ARGS(arg, 09640 AST_APP_ARG(mbox); 09641 AST_APP_ARG(context); 09642 ); 09643 09644 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 09645 09646 if (ast_strlen_zero(arg.mbox)) { 09647 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 09648 return -1; 09649 } 09650 09651 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 09652 return 0; 09653 }
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 4173 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().
04174 { 04175 char tmpdir[256], newtmp[256]; 04176 char fname[256]; 04177 char tmpcmd[256]; 04178 int tmpfd = -1; 04179 04180 /* Eww. We want formats to tell us their own MIME type */ 04181 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04182 04183 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04184 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04185 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04186 tmpfd = mkstemp(newtmp); 04187 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04188 ast_debug(3, "newtmp: %s\n", newtmp); 04189 if (tmpfd > -1) { 04190 int soxstatus; 04191 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04192 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04193 attach = newtmp; 04194 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04195 } else { 04196 ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04197 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04198 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04199 } 04200 } 04201 } 04202 fprintf(p, "--%s" ENDL, bound); 04203 if (msgnum > -1) 04204 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04205 else 04206 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, attach, format); 04207 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04208 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04209 if (msgnum > -1) 04210 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04211 else 04212 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, attach, format); 04213 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04214 base_encode(fname, p); 04215 if (last) 04216 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04217 if (tmpfd > -1) { 04218 unlink(fname); 04219 close(tmpfd); 04220 unlink(newtmp); 04221 } 04222 return 0; 04223 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 5583 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().
05584 { 05585 int x; 05586 if (!ast_adsi_available(chan)) 05587 return; 05588 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 05589 if (x < 0) 05590 return; 05591 if (!x) { 05592 if (adsi_load_vmail(chan, useadsi)) { 05593 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 05594 return; 05595 } 05596 } else 05597 *useadsi = 1; 05598 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 5772 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available, chan, and vm_state::curmsg.
Referenced by vm_execmain().
05773 { 05774 int bytes=0; 05775 unsigned char buf[256]; 05776 unsigned char keys[8]; 05777 05778 int x; 05779 05780 if (!ast_adsi_available(chan)) 05781 return; 05782 05783 /* New meaning for keys */ 05784 for (x=0;x<5;x++) 05785 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05786 05787 keys[6] = 0x0; 05788 keys[7] = 0x0; 05789 05790 if (!vms->curmsg) { 05791 /* No prev key, provide "Folder" instead */ 05792 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05793 } 05794 if (vms->curmsg >= vms->lastmsg) { 05795 /* If last message ... */ 05796 if (vms->curmsg) { 05797 /* but not only message, provide "Folder" instead */ 05798 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05799 } else { 05800 /* Otherwise if only message, leave blank */ 05801 keys[3] = 1; 05802 } 05803 } 05804 05805 /* If deleted, show "undeleted" */ 05806 if (vms->deleted[vms->curmsg]) 05807 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05808 05809 /* Except "Exit" */ 05810 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05811 bytes += ast_adsi_set_keys(buf + bytes, keys); 05812 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05813 05814 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05815 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 5648 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().
05649 { 05650 unsigned char buf[256]; 05651 int bytes=0; 05652 unsigned char keys[8]; 05653 int x,y; 05654 05655 if (!ast_adsi_available(chan)) 05656 return; 05657 05658 for (x=0;x<5;x++) { 05659 y = ADSI_KEY_APPS + 12 + start + x; 05660 if (y > ADSI_KEY_APPS + 12 + 4) 05661 y = 0; 05662 keys[x] = ADSI_KEY_SKT | y; 05663 } 05664 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 05665 keys[6] = 0; 05666 keys[7] = 0; 05667 05668 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 05669 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 05670 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05671 bytes += ast_adsi_set_keys(buf + bytes, keys); 05672 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05673 05674 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05675 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5920 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().
05921 { 05922 unsigned char buf[256]; 05923 int bytes=0; 05924 05925 if (!ast_adsi_available(chan)) 05926 return; 05927 bytes += adsi_logo(buf + bytes); 05928 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 05929 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 05930 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05931 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05932 05933 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05934 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 5454 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().
05455 { 05456 unsigned char buf[256]; 05457 int bytes=0; 05458 int x; 05459 char num[5]; 05460 05461 *useadsi = 0; 05462 bytes += ast_adsi_data_mode(buf + bytes); 05463 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05464 05465 bytes = 0; 05466 bytes += adsi_logo(buf); 05467 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05468 #ifdef DISPLAY 05469 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 05470 #endif 05471 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05472 bytes += ast_adsi_data_mode(buf + bytes); 05473 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05474 05475 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 05476 bytes = 0; 05477 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 05478 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05479 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05480 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05481 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05482 return 0; 05483 } 05484 05485 #ifdef DISPLAY 05486 /* Add a dot */ 05487 bytes = 0; 05488 bytes += ast_adsi_logo(buf); 05489 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05490 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 05491 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05492 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05493 #endif 05494 bytes = 0; 05495 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 05496 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 05497 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 05498 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 05499 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 05500 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 05501 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05502 05503 #ifdef DISPLAY 05504 /* Add another dot */ 05505 bytes = 0; 05506 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 05507 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05508 05509 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05510 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05511 #endif 05512 05513 bytes = 0; 05514 /* These buttons we load but don't use yet */ 05515 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 05516 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 05517 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 05518 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 05519 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 05520 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 05521 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05522 05523 #ifdef DISPLAY 05524 /* Add another dot */ 05525 bytes = 0; 05526 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 05527 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05528 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05529 #endif 05530 05531 bytes = 0; 05532 for (x=0;x<5;x++) { 05533 snprintf(num, sizeof(num), "%d", x); 05534 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1); 05535 } 05536 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 05537 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05538 05539 #ifdef DISPLAY 05540 /* Add another dot */ 05541 bytes = 0; 05542 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 05543 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05544 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05545 #endif 05546 05547 if (ast_adsi_end_download(chan)) { 05548 bytes = 0; 05549 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 05550 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05551 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05552 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05553 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05554 return 0; 05555 } 05556 bytes = 0; 05557 bytes += ast_adsi_download_disconnect(buf + bytes); 05558 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05559 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05560 05561 ast_debug(1, "Done downloading scripts...\n"); 05562 05563 #ifdef DISPLAY 05564 /* Add last dot */ 05565 bytes = 0; 05566 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 05567 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05568 #endif 05569 ast_debug(1, "Restarting session...\n"); 05570 05571 bytes = 0; 05572 /* Load the session now */ 05573 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 05574 *useadsi = 1; 05575 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 05576 } else 05577 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 05578 05579 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05580 return 0; 05581 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5600 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().
05601 { 05602 unsigned char buf[256]; 05603 int bytes=0; 05604 unsigned char keys[8]; 05605 int x; 05606 if (!ast_adsi_available(chan)) 05607 return; 05608 05609 for (x=0;x<8;x++) 05610 keys[x] = 0; 05611 /* Set one key for next */ 05612 keys[3] = ADSI_KEY_APPS + 3; 05613 05614 bytes += adsi_logo(buf + bytes); 05615 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 05616 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 05617 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05618 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 05619 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 05620 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 05621 bytes += ast_adsi_set_keys(buf + bytes, keys); 05622 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05623 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05624 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 5446 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().
05447 { 05448 int bytes = 0; 05449 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 05450 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 05451 return bytes; 05452 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 5677 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().
05678 { 05679 int bytes=0; 05680 unsigned char buf[256]; 05681 char buf1[256], buf2[256]; 05682 char fn2[PATH_MAX]; 05683 05684 char cid[256]=""; 05685 char *val; 05686 char *name, *num; 05687 char datetime[21]=""; 05688 FILE *f; 05689 05690 unsigned char keys[8]; 05691 05692 int x; 05693 05694 if (!ast_adsi_available(chan)) 05695 return; 05696 05697 /* Retrieve important info */ 05698 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 05699 f = fopen(fn2, "r"); 05700 if (f) { 05701 while (!feof(f)) { 05702 if (!fgets((char *)buf, sizeof(buf), f)) { 05703 continue; 05704 } 05705 if (!feof(f)) { 05706 char *stringp=NULL; 05707 stringp = (char *)buf; 05708 strsep(&stringp, "="); 05709 val = strsep(&stringp, "="); 05710 if (!ast_strlen_zero(val)) { 05711 if (!strcmp((char *)buf, "callerid")) 05712 ast_copy_string(cid, val, sizeof(cid)); 05713 if (!strcmp((char *)buf, "origdate")) 05714 ast_copy_string(datetime, val, sizeof(datetime)); 05715 } 05716 } 05717 } 05718 fclose(f); 05719 } 05720 /* New meaning for keys */ 05721 for (x=0;x<5;x++) 05722 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05723 keys[6] = 0x0; 05724 keys[7] = 0x0; 05725 05726 if (!vms->curmsg) { 05727 /* No prev key, provide "Folder" instead */ 05728 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05729 } 05730 if (vms->curmsg >= vms->lastmsg) { 05731 /* If last message ... */ 05732 if (vms->curmsg) { 05733 /* but not only message, provide "Folder" instead */ 05734 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05735 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05736 05737 } else { 05738 /* Otherwise if only message, leave blank */ 05739 keys[3] = 1; 05740 } 05741 } 05742 05743 if (!ast_strlen_zero(cid)) { 05744 ast_callerid_parse(cid, &name, &num); 05745 if (!name) 05746 name = num; 05747 } else 05748 name = "Unknown Caller"; 05749 05750 /* If deleted, show "undeleted" */ 05751 05752 if (vms->deleted[vms->curmsg]) 05753 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05754 05755 /* Except "Exit" */ 05756 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05757 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 05758 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 05759 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 05760 05761 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05762 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05763 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 05764 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 05765 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05766 bytes += ast_adsi_set_keys(buf + bytes, keys); 05767 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05768 05769 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05770 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5626 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().
05627 { 05628 unsigned char buf[256]; 05629 int bytes=0; 05630 unsigned char keys[8]; 05631 int x; 05632 if (!ast_adsi_available(chan)) 05633 return; 05634 05635 for (x=0;x<8;x++) 05636 keys[x] = 0; 05637 /* Set one key for next */ 05638 keys[3] = ADSI_KEY_APPS + 3; 05639 05640 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05641 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 05642 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 05643 bytes += ast_adsi_set_keys(buf + bytes, keys); 05644 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05645 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05646 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 5817 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().
05818 { 05819 unsigned char buf[256] = ""; 05820 char buf1[256] = "", buf2[256] = ""; 05821 int bytes=0; 05822 unsigned char keys[8]; 05823 int x; 05824 05825 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 05826 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 05827 if (!ast_adsi_available(chan)) 05828 return; 05829 if (vms->newmessages) { 05830 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 05831 if (vms->oldmessages) { 05832 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 05833 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 05834 } else { 05835 snprintf(buf2, sizeof(buf2), "%s.", newm); 05836 } 05837 } else if (vms->oldmessages) { 05838 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 05839 snprintf(buf2, sizeof(buf2), "%s.", oldm); 05840 } else { 05841 strcpy(buf1, "You have no messages."); 05842 buf2[0] = ' '; 05843 buf2[1] = '\0'; 05844 } 05845 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05846 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05847 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05848 05849 for (x=0;x<6;x++) 05850 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 05851 keys[6] = 0; 05852 keys[7] = 0; 05853 05854 /* Don't let them listen if there are none */ 05855 if (vms->lastmsg < 0) 05856 keys[0] = 1; 05857 bytes += ast_adsi_set_keys(buf + bytes, keys); 05858 05859 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05860 05861 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05862 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 5864 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().
05865 { 05866 unsigned char buf[256] = ""; 05867 char buf1[256] = "", buf2[256] = ""; 05868 int bytes=0; 05869 unsigned char keys[8]; 05870 int x; 05871 05872 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 05873 05874 if (!ast_adsi_available(chan)) 05875 return; 05876 05877 /* Original command keys */ 05878 for (x=0;x<6;x++) 05879 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 05880 05881 keys[6] = 0; 05882 keys[7] = 0; 05883 05884 if ((vms->lastmsg + 1) < 1) 05885 keys[0] = 0; 05886 05887 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 05888 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 05889 05890 if (vms->lastmsg + 1) 05891 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 05892 else 05893 strcpy(buf2, "no messages."); 05894 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05895 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05896 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 05897 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05898 bytes += ast_adsi_set_keys(buf + bytes, keys); 05899 05900 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05901 05902 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05903 05904 }
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 11037 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().
11038 { 11039 int res = 0; 11040 char filename[PATH_MAX]; 11041 struct ast_config *msg_cfg = NULL; 11042 const char *origtime, *context; 11043 char *name, *num; 11044 int retries = 0; 11045 char *cid; 11046 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 11047 11048 vms->starting = 0; 11049 11050 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11051 11052 /* Retrieve info from VM attribute file */ 11053 snprintf(filename,sizeof(filename), "%s.txt", vms->fn); 11054 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 11055 msg_cfg = ast_config_load(filename, config_flags); 11056 DISPOSE(vms->curdir, vms->curmsg); 11057 if (!msg_cfg) { 11058 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 11059 return 0; 11060 } 11061 11062 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 11063 ast_config_destroy(msg_cfg); 11064 return 0; 11065 } 11066 11067 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 11068 11069 context = ast_variable_retrieve(msg_cfg, "message", "context"); 11070 if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ 11071 context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); 11072 switch (option) { 11073 case 3: /* Play message envelope */ 11074 if (!res) 11075 res = play_message_datetime(chan, vmu, origtime, filename); 11076 if (!res) 11077 res = play_message_callerid(chan, vms, cid, context, 0); 11078 11079 res = 't'; 11080 break; 11081 11082 case 2: /* Call back */ 11083 11084 if (ast_strlen_zero(cid)) 11085 break; 11086 11087 ast_callerid_parse(cid, &name, &num); 11088 while ((res > -1) && (res != 't')) { 11089 switch (res) { 11090 case '1': 11091 if (num) { 11092 /* Dial the CID number */ 11093 res = dialout(chan, vmu, num, vmu->callback); 11094 if (res) { 11095 ast_config_destroy(msg_cfg); 11096 return 9; 11097 } 11098 } else { 11099 res = '2'; 11100 } 11101 break; 11102 11103 case '2': 11104 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 11105 if (!ast_strlen_zero(vmu->dialout)) { 11106 res = dialout(chan, vmu, NULL, vmu->dialout); 11107 if (res) { 11108 ast_config_destroy(msg_cfg); 11109 return 9; 11110 } 11111 } else { 11112 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 11113 res = ast_play_and_wait(chan, "vm-sorry"); 11114 } 11115 ast_config_destroy(msg_cfg); 11116 return res; 11117 case '*': 11118 res = 't'; 11119 break; 11120 case '3': 11121 case '4': 11122 case '5': 11123 case '6': 11124 case '7': 11125 case '8': 11126 case '9': 11127 case '0': 11128 11129 res = ast_play_and_wait(chan, "vm-sorry"); 11130 retries++; 11131 break; 11132 default: 11133 if (num) { 11134 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 11135 res = ast_play_and_wait(chan, "vm-num-i-have"); 11136 if (!res) 11137 res = play_message_callerid(chan, vms, num, vmu->context, 1); 11138 if (!res) 11139 res = ast_play_and_wait(chan, "vm-tocallnum"); 11140 /* Only prompt for a caller-specified number if there is a dialout context specified */ 11141 if (!ast_strlen_zero(vmu->dialout)) { 11142 if (!res) 11143 res = ast_play_and_wait(chan, "vm-calldiffnum"); 11144 } 11145 } else { 11146 res = ast_play_and_wait(chan, "vm-nonumber"); 11147 if (!ast_strlen_zero(vmu->dialout)) { 11148 if (!res) 11149 res = ast_play_and_wait(chan, "vm-toenternumber"); 11150 } 11151 } 11152 if (!res) 11153 res = ast_play_and_wait(chan, "vm-star-cancel"); 11154 if (!res) 11155 res = ast_waitfordigit(chan, 6000); 11156 if (!res) { 11157 retries++; 11158 if (retries > 3) 11159 res = 't'; 11160 } 11161 break; 11162 11163 } 11164 if (res == 't') 11165 res = 0; 11166 else if (res == '*') 11167 res = -1; 11168 } 11169 break; 11170 11171 case 1: /* Reply */ 11172 /* Send reply directly to sender */ 11173 if (ast_strlen_zero(cid)) 11174 break; 11175 11176 ast_callerid_parse(cid, &name, &num); 11177 if (!num) { 11178 ast_verb(3, "No CID number available, no reply sent\n"); 11179 if (!res) 11180 res = ast_play_and_wait(chan, "vm-nonumber"); 11181 ast_config_destroy(msg_cfg); 11182 return res; 11183 } else { 11184 struct ast_vm_user vmu2; 11185 if (find_user(&vmu2, vmu->context, num)) { 11186 struct leave_vm_options leave_options; 11187 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 11188 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 11189 11190 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 11191 11192 memset(&leave_options, 0, sizeof(leave_options)); 11193 leave_options.record_gain = record_gain; 11194 res = leave_voicemail(chan, mailbox, &leave_options); 11195 if (!res) 11196 res = 't'; 11197 ast_config_destroy(msg_cfg); 11198 return res; 11199 } else { 11200 /* Sender has no mailbox, can't reply */ 11201 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 11202 ast_play_and_wait(chan, "vm-nobox"); 11203 res = 't'; 11204 ast_config_destroy(msg_cfg); 11205 return res; 11206 } 11207 } 11208 res = 0; 11209 11210 break; 11211 } 11212 11213 #ifndef IMAP_STORAGE 11214 ast_config_destroy(msg_cfg); 11215 11216 if (!res) { 11217 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11218 vms->heard[msg] = 1; 11219 res = wait_file(chan, vms, vms->fn); 11220 } 11221 #endif 11222 return res; 11223 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 9556 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().
09557 { 09558 /* Assumes lock is already held */ 09559 char *tmp; 09560 char *stringp; 09561 char *s; 09562 struct ast_vm_user *vmu; 09563 char *mailbox_full; 09564 int new = 0, old = 0, urgent = 0; 09565 09566 tmp = ast_strdupa(data); 09567 09568 if (!(vmu = find_or_create(context, box))) 09569 return -1; 09570 09571 populate_defaults(vmu); 09572 09573 stringp = tmp; 09574 if ((s = strsep(&stringp, ","))) 09575 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 09576 if (stringp && (s = strsep(&stringp, ","))) 09577 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 09578 if (stringp && (s = strsep(&stringp, ","))) 09579 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 09580 if (stringp && (s = strsep(&stringp, ","))) 09581 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 09582 if (stringp && (s = strsep(&stringp, ","))) 09583 apply_options(vmu, s); 09584 09585 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 09586 strcpy(mailbox_full, box); 09587 strcat(mailbox_full, "@"); 09588 strcat(mailbox_full, context); 09589 09590 inboxcount2(mailbox_full, &urgent, &new, &old); 09591 queue_mwi_event(mailbox_full, urgent, new, old); 09592 09593 return 0; 09594 }
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 757 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().
00758 { 00759 int x; 00760 if (!strcasecmp(var, "attach")) { 00761 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 00762 } else if (!strcasecmp(var, "attachfmt")) { 00763 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 00764 } else if (!strcasecmp(var, "serveremail")) { 00765 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 00766 } else if (!strcasecmp(var, "language")) { 00767 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 00768 } else if (!strcasecmp(var, "tz")) { 00769 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 00770 #ifdef IMAP_STORAGE 00771 } else if (!strcasecmp(var, "imapuser")) { 00772 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 00773 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 00774 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 00775 } else if (!strcasecmp(var, "imapvmshareid")) { 00776 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 00777 #endif 00778 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 00779 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 00780 } else if (!strcasecmp(var, "saycid")){ 00781 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 00782 } else if (!strcasecmp(var,"sendvoicemail")){ 00783 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 00784 } else if (!strcasecmp(var, "review")){ 00785 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 00786 } else if (!strcasecmp(var, "tempgreetwarn")){ 00787 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 00788 } else if (!strcasecmp(var, "messagewrap")){ 00789 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 00790 } else if (!strcasecmp(var, "operator")) { 00791 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 00792 } else if (!strcasecmp(var, "envelope")){ 00793 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 00794 } else if (!strcasecmp(var, "moveheard")){ 00795 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 00796 } else if (!strcasecmp(var, "sayduration")){ 00797 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 00798 } else if (!strcasecmp(var, "saydurationm")){ 00799 if (sscanf(value, "%d", &x) == 1) { 00800 vmu->saydurationm = x; 00801 } else { 00802 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 00803 } 00804 } else if (!strcasecmp(var, "forcename")){ 00805 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 00806 } else if (!strcasecmp(var, "forcegreetings")){ 00807 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 00808 } else if (!strcasecmp(var, "callback")) { 00809 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 00810 } else if (!strcasecmp(var, "dialout")) { 00811 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 00812 } else if (!strcasecmp(var, "exitcontext")) { 00813 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 00814 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 00815 if (vmu->maxsecs <= 0) { 00816 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 00817 vmu->maxsecs = vmmaxsecs; 00818 } else { 00819 vmu->maxsecs = atoi(value); 00820 } 00821 if (!strcasecmp(var, "maxmessage")) 00822 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 00823 } else if (!strcasecmp(var, "maxmsg")) { 00824 vmu->maxmsg = atoi(value); 00825 if (vmu->maxmsg <= 0) { 00826 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 00827 vmu->maxmsg = MAXMSG; 00828 } else if (vmu->maxmsg > MAXMSGLIMIT) { 00829 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 00830 vmu->maxmsg = MAXMSGLIMIT; 00831 } 00832 } else if (!strcasecmp(var, "backupdeleted")) { 00833 if (sscanf(value, "%d", &x) == 1) 00834 vmu->maxdeletedmsg = x; 00835 else if (ast_true(value)) 00836 vmu->maxdeletedmsg = MAXMSG; 00837 else 00838 vmu->maxdeletedmsg = 0; 00839 00840 if (vmu->maxdeletedmsg < 0) { 00841 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 00842 vmu->maxdeletedmsg = MAXMSG; 00843 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 00844 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 00845 vmu->maxdeletedmsg = MAXMSGLIMIT; 00846 } 00847 } else if (!strcasecmp(var, "volgain")) { 00848 sscanf(value, "%lf", &vmu->volgain); 00849 } else if (!strcasecmp(var, "options")) { 00850 apply_options(vmu, value); 00851 } 00852 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 967 of file app_voicemail.c.
References apply_option(), ast_strdupa, s, strsep(), and var.
Referenced by append_mailbox(), and apply_option().
00968 { 00969 char *stringp; 00970 char *s; 00971 char *var, *value; 00972 stringp = ast_strdupa(options); 00973 while ((s = strsep(&stringp, "|"))) { 00974 value = s; 00975 if ((var = strsep(&value, "=")) && value) { 00976 apply_option(vmu, var, value); 00977 } 00978 } 00979 }
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 986 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().
00987 { 00988 struct ast_variable *tmp; 00989 tmp = var; 00990 while (tmp) { 00991 if (!strcasecmp(tmp->name, "vmsecret")) { 00992 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 00993 } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */ 00994 if (ast_strlen_zero(retval->password)) 00995 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 00996 } else if (!strcasecmp(tmp->name, "uniqueid")) { 00997 ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid)); 00998 } else if (!strcasecmp(tmp->name, "pager")) { 00999 ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager)); 01000 } else if (!strcasecmp(tmp->name, "email")) { 01001 ast_copy_string(retval->email, tmp->value, sizeof(retval->email)); 01002 } else if (!strcasecmp(tmp->name, "fullname")) { 01003 ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname)); 01004 } else if (!strcasecmp(tmp->name, "context")) { 01005 ast_copy_string(retval->context, tmp->value, sizeof(retval->context)); 01006 #ifdef IMAP_STORAGE 01007 } else if (!strcasecmp(tmp->name, "imapuser")) { 01008 ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser)); 01009 } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) { 01010 ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword)); 01011 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01012 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01013 #endif 01014 } else 01015 apply_option(retval, tmp->name, tmp->value); 01016 tmp = tmp->next; 01017 } 01018 }
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 3661 of file app_voicemail.c.
References ast_log(), BASEMAXINLINE, eol, errno, inchar(), and ochar().
03662 { 03663 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 03664 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 03665 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 03666 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 03667 int i,hiteof= 0; 03668 FILE *fi; 03669 struct baseio bio; 03670 03671 memset(&bio, 0, sizeof(bio)); 03672 bio.iocp = BASEMAXINLINE; 03673 03674 if (!(fi = fopen(filename, "rb"))) { 03675 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 03676 return -1; 03677 } 03678 03679 while (!hiteof){ 03680 unsigned char igroup[3], ogroup[4]; 03681 int c,n; 03682 03683 igroup[0]= igroup[1]= igroup[2]= 0; 03684 03685 for (n= 0;n<3;n++) { 03686 if ((c = inchar(&bio, fi)) == EOF) { 03687 hiteof= 1; 03688 break; 03689 } 03690 03691 igroup[n]= (unsigned char)c; 03692 } 03693 03694 if (n> 0) { 03695 ogroup[0]= dtable[igroup[0]>>2]; 03696 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 03697 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 03698 ogroup[3]= dtable[igroup[2]&0x3F]; 03699 03700 if (n<3) { 03701 ogroup[3]= '='; 03702 03703 if (n<2) 03704 ogroup[2]= '='; 03705 } 03706 03707 for (i= 0;i<4;i++) 03708 ochar(&bio, ogroup[i], so); 03709 } 03710 } 03711 03712 fclose(fi); 03713 03714 if (fputs(eol,so)==EOF) 03715 return 0; 03716 03717 return 1; 03718 }
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 945 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().
00946 { 00947 int res; 00948 if (!ast_strlen_zero(vmu->uniqueid)) { 00949 if (strlen(password) > 10) { 00950 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 00951 } 00952 res = ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, SENTINEL); 00953 if (res > 0) { 00954 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 00955 res = 0; 00956 } else if (!res) { 00957 res = -1; 00958 } 00959 return res; 00960 } 00961 return -1; 00962 }
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 3826 of file app_voicemail.c.
Referenced by make_email_file().
03827 { 03828 for (; *str; str++) { 03829 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 03830 return 1; 03831 } 03832 } 03833 return 0; 03834 }
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 907 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().
00908 { 00909 /* check minimum length */ 00910 if (strlen(password) < minpassword) 00911 return 1; 00912 if (!ast_strlen_zero(ext_pass_check_cmd)) { 00913 char cmd[255], buf[255]; 00914 00915 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 00916 00917 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 00918 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 00919 ast_debug(5, "Result: %s\n", buf); 00920 if (!strncasecmp(buf, "VALID", 5)) { 00921 ast_debug(3, "Passed password check: '%s'\n", buf); 00922 return 0; 00923 } else if (!strncasecmp(buf, "FAILURE", 7)) { 00924 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 00925 return 0; 00926 } else { 00927 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 00928 return 1; 00929 } 00930 } 00931 } 00932 return 0; 00933 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 6973 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().
06974 { 06975 int x = 0; 06976 #ifndef IMAP_STORAGE 06977 int res = 0, nummsg; 06978 char fn2[PATH_MAX]; 06979 #endif 06980 06981 if (vms->lastmsg <= -1) 06982 goto done; 06983 06984 vms->curmsg = -1; 06985 #ifndef IMAP_STORAGE 06986 /* Get the deleted messages fixed */ 06987 if (vm_lock_path(vms->curdir)) 06988 return ERROR_LOCK_PATH; 06989 06990 for (x = 0; x < vmu->maxmsg; x++) { 06991 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 06992 /* Save this message. It's not in INBOX or hasn't been heard */ 06993 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 06994 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 06995 break; 06996 vms->curmsg++; 06997 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 06998 if (strcmp(vms->fn, fn2)) { 06999 RENAME(vms->curdir, x, vmu->mailbox,vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07000 } 07001 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07002 /* Move to old folder before deleting */ 07003 res = save_to_folder(vmu, vms, x, 1); 07004 if (res == ERROR_LOCK_PATH) { 07005 /* If save failed do not delete the message */ 07006 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07007 vms->deleted[x] = 0; 07008 vms->heard[x] = 0; 07009 --x; 07010 } 07011 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07012 /* Move to deleted folder */ 07013 res = save_to_folder(vmu, vms, x, 10); 07014 if (res == ERROR_LOCK_PATH) { 07015 /* If save failed do not delete the message */ 07016 vms->deleted[x] = 0; 07017 vms->heard[x] = 0; 07018 --x; 07019 } 07020 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07021 /* If realtime storage enabled - we should explicitly delete this message, 07022 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07023 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07024 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07025 DELETE(vms->curdir, x, vms->fn, vmu); 07026 } 07027 } 07028 07029 /* Delete ALL remaining messages */ 07030 nummsg = x - 1; 07031 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07032 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07033 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07034 DELETE(vms->curdir, x, vms->fn, vmu); 07035 } 07036 ast_unlock_path(vms->curdir); 07037 #else 07038 if (vms->deleted) { 07039 for (x=0;x < vmu->maxmsg;x++) { 07040 if (vms->deleted[x]) { 07041 ast_debug(3,"IMAP delete of %d\n",x); 07042 DELETE(vms->curdir, x, vms->fn, vmu); 07043 } 07044 } 07045 } 07046 #endif 07047 07048 done: 07049 if (vms->deleted) 07050 memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 07051 if (vms->heard) 07052 memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 07053 07054 return 0; 07055 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 9740 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().
09741 { 09742 int which = 0; 09743 int wordlen; 09744 struct ast_vm_user *vmu; 09745 const char *context = ""; 09746 09747 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 09748 if (pos > 4) 09749 return NULL; 09750 if (pos == 3) 09751 return (state == 0) ? ast_strdup("for") : NULL; 09752 wordlen = strlen(word); 09753 AST_LIST_TRAVERSE(&users, vmu, list) { 09754 if (!strncasecmp(word, vmu->context, wordlen)) { 09755 if (context && strcmp(context, vmu->context) && ++which > state) 09756 return ast_strdup(vmu->context); 09757 /* ignore repeated contexts ? */ 09758 context = vmu->context; 09759 } 09760 } 09761 return NULL; 09762 }
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 3467 of file app_voicemail.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
03468 { 03469 int ifd; 03470 int ofd; 03471 int res; 03472 int len; 03473 char buf[4096]; 03474 03475 #ifdef HARDLINK_WHEN_POSSIBLE 03476 /* Hard link if possible; saves disk space & is faster */ 03477 if (link(infile, outfile)) { 03478 #endif 03479 if ((ifd = open(infile, O_RDONLY)) < 0) { 03480 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03481 return -1; 03482 } 03483 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03484 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03485 close(ifd); 03486 return -1; 03487 } 03488 do { 03489 len = read(ifd, buf, sizeof(buf)); 03490 if (len < 0) { 03491 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03492 close(ifd); 03493 close(ofd); 03494 unlink(outfile); 03495 } 03496 if (len) { 03497 res = write(ofd, buf, len); 03498 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03499 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03500 close(ifd); 03501 close(ofd); 03502 unlink(outfile); 03503 } 03504 } 03505 } while (len); 03506 close(ifd); 03507 close(ofd); 03508 return 0; 03509 #ifdef HARDLINK_WHEN_POSSIBLE 03510 } else { 03511 /* Hard link succeeded */ 03512 return 0; 03513 } 03514 #endif 03515 }
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 4618 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, 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().
04619 { 04620 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 04621 const char *frombox = mbox(imbox); 04622 int recipmsgnum; 04623 04624 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 04625 04626 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 04627 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 04628 } else { 04629 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04630 } 04631 04632 if (!dir) 04633 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 04634 else 04635 ast_copy_string(fromdir, dir, sizeof(fromdir)); 04636 04637 make_file(frompath, sizeof(frompath), fromdir, msgnum); 04638 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04639 04640 if (vm_lock_path(todir)) 04641 return ERROR_LOCK_PATH; 04642 04643 recipmsgnum = last_message_index(recip, todir) + 1; 04644 if (recipmsgnum < recip->maxmsg) { 04645 make_file(topath, sizeof(topath), todir, recipmsgnum); 04646 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 04647 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 04648 } else { 04649 /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL 04650 * copy will fail. Instead, we need to create a local copy, store it, and delete the local 04651 * copy. We don't have to #ifdef this because if file storage reaches this point, there's a 04652 * much worse problem happening and IMAP storage doesn't call this function 04653 */ 04654 copy_plain_file(frompath, topath); 04655 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 04656 vm_delete(topath); 04657 } 04658 } else { 04659 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 04660 } 04661 ast_unlock_path(todir); 04662 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 04663 04664 return 0; 04665 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 3526 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().
03527 { 03528 char frompath2[PATH_MAX], topath2[PATH_MAX]; 03529 struct ast_variable *tmp,*var = NULL; 03530 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 03531 ast_filecopy(frompath, topath, NULL); 03532 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 03533 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 03534 if (ast_check_realtime("voicemail_data")) { 03535 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 03536 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 03537 for (tmp = var; tmp; tmp = tmp->next) { 03538 if (!strcasecmp(tmp->name, "origmailbox")) { 03539 origmailbox = tmp->value; 03540 } else if (!strcasecmp(tmp->name, "context")) { 03541 context = tmp->value; 03542 } else if (!strcasecmp(tmp->name, "macrocontext")) { 03543 macrocontext = tmp->value; 03544 } else if (!strcasecmp(tmp->name, "exten")) { 03545 exten = tmp->value; 03546 } else if (!strcasecmp(tmp->name, "priority")) { 03547 priority = tmp->value; 03548 } else if (!strcasecmp(tmp->name, "callerchan")) { 03549 callerchan = tmp->value; 03550 } else if (!strcasecmp(tmp->name, "callerid")) { 03551 callerid = tmp->value; 03552 } else if (!strcasecmp(tmp->name, "origdate")) { 03553 origdate = tmp->value; 03554 } else if (!strcasecmp(tmp->name, "origtime")) { 03555 origtime = tmp->value; 03556 } else if (!strcasecmp(tmp->name, "category")) { 03557 category = tmp->value; 03558 } else if (!strcasecmp(tmp->name, "duration")) { 03559 duration = tmp->value; 03560 } 03561 } 03562 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); 03563 } 03564 copy(frompath2, topath2); 03565 ast_variables_destroy(var); 03566 }
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 3373 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().
03374 { 03375 03376 int vmcount = 0; 03377 DIR *vmdir = NULL; 03378 struct dirent *vment = NULL; 03379 03380 if (vm_lock_path(dir)) 03381 return ERROR_LOCK_PATH; 03382 03383 if ((vmdir = opendir(dir))) { 03384 while ((vment = readdir(vmdir))) { 03385 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03386 vmcount++; 03387 } 03388 } 03389 closedir(vmdir); 03390 } 03391 ast_unlock_path(dir); 03392 03393 return vmcount; 03394 }
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 1288 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01289 { 01290 mode_t mode = VOICEMAIL_DIR_MODE; 01291 int res; 01292 01293 make_dir(dest, len, context, ext, folder); 01294 if ((res = ast_mkdir(dest, mode))) { 01295 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01296 return -1; 01297 } 01298 return 0; 01299 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 10965 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().
10966 { 10967 int cmd = 0; 10968 char destination[80] = ""; 10969 int retries = 0; 10970 10971 if (!num) { 10972 ast_verb(3, "Destination number will be entered manually\n"); 10973 while (retries < 3 && cmd != 't') { 10974 destination[1] = '\0'; 10975 destination[0] = cmd = ast_play_and_wait(chan,"vm-enter-num-to-call"); 10976 if (!cmd) 10977 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 10978 if (!cmd) 10979 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 10980 if (!cmd) { 10981 cmd = ast_waitfordigit(chan, 6000); 10982 if (cmd) 10983 destination[0] = cmd; 10984 } 10985 if (!cmd) { 10986 retries++; 10987 } else { 10988 10989 if (cmd < 0) 10990 return 0; 10991 if (cmd == '*') { 10992 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 10993 return 0; 10994 } 10995 if ((cmd = ast_readstring(chan,destination + strlen(destination),sizeof(destination)-1,6000,10000,"#")) < 0) 10996 retries++; 10997 else 10998 cmd = 't'; 10999 } 11000 } 11001 if (retries >= 3) { 11002 return 0; 11003 } 11004 11005 } else { 11006 if (option_verbose > 2) 11007 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 11008 ast_copy_string(destination, num, sizeof(destination)); 11009 } 11010 11011 if (!ast_strlen_zero(destination)) { 11012 if (destination[strlen(destination) -1 ] == '*') 11013 return 0; 11014 if (option_verbose > 2) 11015 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 11016 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 11017 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 11018 chan->priority = 0; 11019 return 9; 11020 } 11021 return 0; 11022 }
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 3852 of file app_voicemail.c.
References charset.
Referenced by make_email_file().
03853 { 03854 char tmp[80]; 03855 int first_section = 1; 03856 size_t endlen = 0, tmplen = 0; 03857 *end = '\0'; 03858 03859 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 03860 for (; *start; start++) { 03861 int need_encoding = 0; 03862 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 03863 need_encoding = 1; 03864 } 03865 if ((first_section && need_encoding && preamble + tmplen > 70) || 03866 (first_section && !need_encoding && preamble + tmplen > 72) || 03867 (!first_section && need_encoding && tmplen > 70) || 03868 (!first_section && !need_encoding && tmplen > 72)) { 03869 /* Start new line */ 03870 endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp); 03871 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 03872 first_section = 0; 03873 } 03874 if (need_encoding && *start == ' ') { 03875 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_"); 03876 } else if (need_encoding) { 03877 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start); 03878 } else { 03879 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start); 03880 } 03881 } 03882 snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : ""); 03883 return end; 03884 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 9524 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().
09525 { 09526 struct ast_vm_user *vmu; 09527 09528 AST_LIST_TRAVERSE(&users, vmu, list) { 09529 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 09530 if (strcasecmp(vmu->context, context)) { 09531 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 09532 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 09533 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 09534 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 09535 } 09536 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 09537 return NULL; 09538 } 09539 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 09540 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 09541 return NULL; 09542 } 09543 } 09544 09545 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 09546 return NULL; 09547 09548 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 09549 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 09550 09551 AST_LIST_INSERT_TAIL(&users, vmu, list); 09552 09553 return vmu; 09554 }
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 1089 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.
01090 { 01091 /* This function could be made to generate one from a database, too */ 01092 struct ast_vm_user *vmu=NULL, *cur; 01093 AST_LIST_LOCK(&users); 01094 01095 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01096 context = "default"; 01097 01098 AST_LIST_TRAVERSE(&users, cur, list) { 01099 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01100 break; 01101 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01102 break; 01103 } 01104 if (cur) { 01105 /* Make a copy, so that on a reload, we have no race */ 01106 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01107 memcpy(vmu, cur, sizeof(*vmu)); 01108 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01109 AST_LIST_NEXT(vmu, list) = NULL; 01110 } 01111 } else 01112 vmu = find_user_realtime(ivm, context, mailbox); 01113 AST_LIST_UNLOCK(&users); 01114 return vmu; 01115 }
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 1052 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.
01053 { 01054 struct ast_variable *var; 01055 struct ast_vm_user *retval; 01056 01057 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01058 if (!ivm) 01059 ast_set_flag(retval, VM_ALLOCED); 01060 else 01061 memset(retval, 0, sizeof(*retval)); 01062 if (mailbox) 01063 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01064 populate_defaults(retval); 01065 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01066 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01067 else 01068 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01069 if (var) { 01070 apply_options_full(retval, var); 01071 ast_variables_destroy(var); 01072 } else { 01073 if (!ivm) 01074 ast_free(retval); 01075 retval = NULL; 01076 } 01077 } 01078 return retval; 01079 }
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 6274 of file app_voicemail.c.
References ast_clear_flag, ast_copy_string(), ast_fileexists(), 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, 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().
06275 { 06276 #ifdef IMAP_STORAGE 06277 int todircount=0; 06278 struct vm_state *dstvms; 06279 #endif 06280 char username[70]=""; 06281 char fn[PATH_MAX]; /* for playback of name greeting */ 06282 char ecodes[16] = "#"; 06283 int res = 0, cmd = 0; 06284 struct ast_vm_user *receiver = NULL, *vmtmp; 06285 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 06286 char *stringp; 06287 const char *s; 06288 int saved_messages = 0, found = 0; 06289 int valid_extensions = 0; 06290 char *dir; 06291 int curmsg; 06292 char urgent_str[7] = ""; 06293 char tmptxtfile[PATH_MAX]; 06294 06295 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 06296 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 06297 } 06298 06299 if (vms == NULL) return -1; 06300 dir = vms->curdir; 06301 curmsg = vms->curmsg; 06302 06303 tmptxtfile[0] = '\0'; 06304 while (!res && !valid_extensions) { 06305 int use_directory = 0; 06306 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 06307 int done = 0; 06308 int retries = 0; 06309 cmd=0; 06310 while ((cmd >= 0) && !done ){ 06311 if (cmd) 06312 retries = 0; 06313 switch (cmd) { 06314 case '1': 06315 use_directory = 0; 06316 done = 1; 06317 break; 06318 case '2': 06319 use_directory = 1; 06320 done=1; 06321 break; 06322 case '*': 06323 cmd = 't'; 06324 done = 1; 06325 break; 06326 default: 06327 /* Press 1 to enter an extension press 2 to use the directory */ 06328 cmd = ast_play_and_wait(chan,"vm-forward"); 06329 if (!cmd) 06330 cmd = ast_waitfordigit(chan,3000); 06331 if (!cmd) 06332 retries++; 06333 if (retries > 3) { 06334 cmd = 't'; 06335 done = 1; 06336 } 06337 06338 } 06339 } 06340 if (cmd < 0 || cmd == 't') 06341 break; 06342 } 06343 06344 if (use_directory) { 06345 /* use app_directory */ 06346 06347 char old_context[sizeof(chan->context)]; 06348 char old_exten[sizeof(chan->exten)]; 06349 int old_priority; 06350 struct ast_app* directory_app; 06351 06352 directory_app = pbx_findapp("Directory"); 06353 if (directory_app) { 06354 char vmcontext[256]; 06355 /* make backup copies */ 06356 memcpy(old_context, chan->context, sizeof(chan->context)); 06357 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 06358 old_priority = chan->priority; 06359 06360 /* call the the Directory, changes the channel */ 06361 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 06362 res = pbx_exec(chan, directory_app, vmcontext); 06363 06364 ast_copy_string(username, chan->exten, sizeof(username)); 06365 06366 /* restore the old context, exten, and priority */ 06367 memcpy(chan->context, old_context, sizeof(chan->context)); 06368 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 06369 chan->priority = old_priority; 06370 } else { 06371 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 06372 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 06373 } 06374 } else { 06375 /* Ask for an extension */ 06376 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 06377 if (res) 06378 break; 06379 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 06380 break; 06381 } 06382 06383 /* start all over if no username */ 06384 if (ast_strlen_zero(username)) 06385 continue; 06386 stringp = username; 06387 s = strsep(&stringp, "*"); 06388 /* start optimistic */ 06389 valid_extensions = 1; 06390 while (s) { 06391 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 06392 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 06393 found++; 06394 } else { 06395 /* XXX Optimization for the future. When we encounter a single bad extension, 06396 * bailing out on all of the extensions may not be the way to go. We should 06397 * probably just bail on that single extension, then allow the user to enter 06398 * several more. XXX 06399 */ 06400 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 06401 free_user(receiver); 06402 } 06403 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 06404 valid_extensions = 0; 06405 break; 06406 } 06407 06408 /* play name if available, else play extension number */ 06409 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 06410 RETRIEVE(fn, -1, s, receiver->context); 06411 if (ast_fileexists(fn, NULL, NULL) > 0) { 06412 res = ast_stream_and_wait(chan, fn, ecodes); 06413 if (res) { 06414 DISPOSE(fn, -1); 06415 return res; 06416 } 06417 } else { 06418 res = ast_say_digit_str(chan, s, ecodes, chan->language); 06419 } 06420 DISPOSE(fn, -1); 06421 06422 s = strsep(&stringp, "*"); 06423 } 06424 /* break from the loop of reading the extensions */ 06425 if (valid_extensions) 06426 break; 06427 /* "I am sorry, that's not a valid extension. Please try again." */ 06428 res = ast_play_and_wait(chan, "pbx-invalid"); 06429 } 06430 /* check if we're clear to proceed */ 06431 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 06432 return res; 06433 if (is_new_message == 1) { 06434 struct leave_vm_options leave_options; 06435 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 06436 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 06437 06438 /* Send VoiceMail */ 06439 memset(&leave_options, 0, sizeof(leave_options)); 06440 leave_options.record_gain = record_gain; 06441 cmd = leave_voicemail(chan, mailbox, &leave_options); 06442 } else { 06443 /* Forward VoiceMail */ 06444 long duration = 0; 06445 struct vm_state vmstmp; 06446 memcpy(&vmstmp, vms, sizeof(vmstmp)); 06447 06448 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 06449 06450 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 06451 if (!cmd) { 06452 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 06453 #ifdef IMAP_STORAGE 06454 int attach_user_voicemail; 06455 char *myserveremail = serveremail; 06456 06457 /* get destination mailbox */ 06458 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 06459 if (!dstvms) { 06460 dstvms = create_vm_state_from_user(vmtmp); 06461 } 06462 if (dstvms) { 06463 init_mailstream(dstvms, 0); 06464 if (!dstvms->mailstream) { 06465 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 06466 } else { 06467 STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 06468 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 06469 } 06470 } else { 06471 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 06472 } 06473 if (!ast_strlen_zero(vmtmp->serveremail)) 06474 myserveremail = vmtmp->serveremail; 06475 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 06476 /* NULL category for IMAP storage */ 06477 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); 06478 #else 06479 copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 06480 #endif 06481 saved_messages++; 06482 AST_LIST_REMOVE_CURRENT(list); 06483 free_user(vmtmp); 06484 if (res) 06485 break; 06486 } 06487 AST_LIST_TRAVERSE_SAFE_END; 06488 if (saved_messages > 0) { 06489 /* give confirmation that the message was saved */ 06490 /* commented out since we can't forward batches yet 06491 if (saved_messages == 1) 06492 res = ast_play_and_wait(chan, "vm-message"); 06493 else 06494 res = ast_play_and_wait(chan, "vm-messages"); 06495 if (!res) 06496 res = ast_play_and_wait(chan, "vm-saved"); */ 06497 #ifdef IMAP_STORAGE 06498 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 06499 if (ast_strlen_zero(vmstmp.introfn)) 06500 #endif 06501 res = ast_play_and_wait(chan, "vm-msgsaved"); 06502 } 06503 } 06504 DISPOSE(dir, curmsg); 06505 } 06506 06507 /* If anything failed above, we still have this list to free */ 06508 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) 06509 free_user(vmtmp); 06510 return res ? res : cmd; 06511 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1324 of file app_voicemail.c.
References ast_free, ast_test_flag, and VM_ALLOCED.
01325 { 01326 if (ast_test_flag(vmu, VM_ALLOCED)) 01327 ast_free(vmu); 01328 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 10192 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().
10193 { 10194 struct ast_vm_user *current; 10195 AST_LIST_LOCK(&users); 10196 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 10197 ast_set_flag(current, VM_ALLOCED); 10198 free_user(current); 10199 } 10200 AST_LIST_UNLOCK(&users); 10201 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 10204 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().
10205 { 10206 struct vm_zone *zcur; 10207 AST_LIST_LOCK(&zones); 10208 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 10209 free_zone(zcur); 10210 AST_LIST_UNLOCK(&zones); 10211 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4393 of file app_voicemail.c.
References ast_free.
04394 { 04395 ast_free(z); 04396 }
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 4349 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
04350 { 04351 struct ast_tm tm; 04352 struct timeval t = ast_tvnow(); 04353 04354 ast_localtime(&t, &tm, "UTC"); 04355 04356 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04357 }
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 5940 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().
05941 { 05942 int x; 05943 int d; 05944 char fn[PATH_MAX]; 05945 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 05946 if (d) 05947 return d; 05948 for (x = start; x< 5; x++) { /* For all folders */ 05949 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 05950 return d; 05951 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 05952 if (d) 05953 return d; 05954 snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */ 05955 d = vm_play_folder_name(chan, fn); 05956 if (d) 05957 return d; 05958 d = ast_waitfordigit(chan, 500); 05959 if (d) 05960 return d; 05961 } 05962 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 05963 if (d) 05964 return d; 05965 d = ast_waitfordigit(chan, 4000); 05966 return d; 05967 }
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 5981 of file app_voicemail.c.
References ast_play_and_wait(), chan, and get_folder().
Referenced by vm_execmain().
05982 { 05983 int res = 0; 05984 res = ast_play_and_wait(chan, fn); /* Folder name */ 05985 while (((res < '0') || (res > '9')) && 05986 (res != '#') && (res >= 0)) { 05987 res = get_folder(chan, 0); 05988 } 05989 return res; 05990 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 9976 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, mwi_sub_task::uniqueid, and mwi_sub::uniqueid.
Referenced by mwi_sub_event_cb().
09977 { 09978 unsigned int len; 09979 struct mwi_sub *mwi_sub; 09980 struct mwi_sub_task *p = datap; 09981 09982 len = sizeof(*mwi_sub); 09983 if (!ast_strlen_zero(p->mailbox)) 09984 len += strlen(p->mailbox); 09985 09986 if (!ast_strlen_zero(p->context)) 09987 len += strlen(p->context) + 1; /* Allow for seperator */ 09988 09989 if (!(mwi_sub = ast_calloc(1, len))) 09990 return -1; 09991 09992 mwi_sub->uniqueid = p->uniqueid; 09993 if (!ast_strlen_zero(p->mailbox)) 09994 strcpy(mwi_sub->mailbox, p->mailbox); 09995 09996 if (!ast_strlen_zero(p->context)) { 09997 strcat(mwi_sub->mailbox, "@"); 09998 strcat(mwi_sub->mailbox, p->context); 09999 } 10000 10001 AST_RWLIST_WRLOCK(&mwi_subs); 10002 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 10003 AST_RWLIST_UNLOCK(&mwi_subs); 10004 ast_free((void *) p->mailbox); 10005 ast_free((void *) p->context); 10006 ast_free(p); 10007 return 0; 10008 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 9954 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().
09955 { 09956 struct mwi_sub *mwi_sub; 09957 uint32_t *uniqueid = datap; 09958 09959 AST_RWLIST_WRLOCK(&mwi_subs); 09960 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 09961 if (mwi_sub->uniqueid == *uniqueid) { 09962 AST_LIST_REMOVE_CURRENT(entry); 09963 break; 09964 } 09965 } 09966 AST_RWLIST_TRAVERSE_SAFE_END 09967 AST_RWLIST_UNLOCK(&mwi_subs); 09968 09969 if (mwi_sub) 09970 mwi_sub_destroy(mwi_sub); 09971 09972 ast_free(uniqueid); 09973 return 0; 09974 }
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 9875 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.
09876 { 09877 switch (cmd) { 09878 case CLI_INIT: 09879 e->command = "voicemail reload"; 09880 e->usage = 09881 "Usage: voicemail reload\n" 09882 " Reload voicemail configuration\n"; 09883 return NULL; 09884 case CLI_GENERATE: 09885 return NULL; 09886 } 09887 09888 if (a->argc != 2) 09889 return CLI_SHOWUSAGE; 09890 09891 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 09892 load_config(1); 09893 09894 return CLI_SUCCESS; 09895 }
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 9765 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.
09766 { 09767 struct ast_vm_user *vmu; 09768 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 09769 const char *context = NULL; 09770 int users_counter = 0; 09771 09772 switch (cmd) { 09773 case CLI_INIT: 09774 e->command = "voicemail show users"; 09775 e->usage = 09776 "Usage: voicemail show users [for <context>]\n" 09777 " Lists all mailboxes currently set up\n"; 09778 return NULL; 09779 case CLI_GENERATE: 09780 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 09781 } 09782 09783 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 09784 return CLI_SHOWUSAGE; 09785 if (a->argc == 5) { 09786 if (strcmp(a->argv[3],"for")) 09787 return CLI_SHOWUSAGE; 09788 context = a->argv[4]; 09789 } 09790 09791 if (ast_check_realtime("voicemail")) { 09792 if (!context) { 09793 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 09794 return CLI_SHOWUSAGE; 09795 } 09796 return show_users_realtime(a->fd, context); 09797 } 09798 09799 AST_LIST_LOCK(&users); 09800 if (AST_LIST_EMPTY(&users)) { 09801 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 09802 AST_LIST_UNLOCK(&users); 09803 return CLI_FAILURE; 09804 } 09805 if (a->argc == 3) 09806 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 09807 else { 09808 int count = 0; 09809 AST_LIST_TRAVERSE(&users, vmu, list) { 09810 if (!strcmp(context, vmu->context)) 09811 count++; 09812 } 09813 if (count) { 09814 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 09815 } else { 09816 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 09817 AST_LIST_UNLOCK(&users); 09818 return CLI_FAILURE; 09819 } 09820 } 09821 AST_LIST_TRAVERSE(&users, vmu, list) { 09822 int newmsgs = 0, oldmsgs = 0; 09823 char count[12], tmp[256] = ""; 09824 09825 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 09826 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 09827 inboxcount(tmp, &newmsgs, &oldmsgs); 09828 snprintf(count, sizeof(count), "%d", newmsgs); 09829 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 09830 users_counter++; 09831 } 09832 } 09833 AST_LIST_UNLOCK(&users); 09834 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 09835 return CLI_SUCCESS; 09836 }
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 9839 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.
09840 { 09841 struct vm_zone *zone; 09842 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 09843 char *res = CLI_SUCCESS; 09844 09845 switch (cmd) { 09846 case CLI_INIT: 09847 e->command = "voicemail show zones"; 09848 e->usage = 09849 "Usage: voicemail show zones\n" 09850 " Lists zone message formats\n"; 09851 return NULL; 09852 case CLI_GENERATE: 09853 return NULL; 09854 } 09855 09856 if (a->argc != 3) 09857 return CLI_SHOWUSAGE; 09858 09859 AST_LIST_LOCK(&zones); 09860 if (!AST_LIST_EMPTY(&zones)) { 09861 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 09862 AST_LIST_TRAVERSE(&zones, zone, list) { 09863 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 09864 } 09865 } else { 09866 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 09867 res = CLI_FAILURE; 09868 } 09869 AST_LIST_UNLOCK(&zones); 09870 09871 return res; 09872 }
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 4726 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and strsep().
04727 { 04728 char tmp[256], *tmp2 = tmp, *box, *context; 04729 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04730 while ((box = strsep(&tmp2, ","))) { 04731 if ((context = strchr(box, '@'))) 04732 *context++ = '\0'; 04733 else 04734 context = "default"; 04735 if (__has_voicemail(context, box, folder, 1)) 04736 return 1; 04737 } 04738 return 0; 04739 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 4798 of file app_voicemail.c.
References inboxcount2().
Referenced by handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
04799 { 04800 return inboxcount2(mailbox, NULL, newmsgs, oldmsgs); 04801 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 4742 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_mailboxes(), and run_externnotify().
04743 { 04744 char tmp[256]; 04745 char *context; 04746 04747 /* If no mailbox, return immediately */ 04748 if (ast_strlen_zero(mailbox)) 04749 return 0; 04750 04751 if (newmsgs) 04752 *newmsgs = 0; 04753 if (oldmsgs) 04754 *oldmsgs = 0; 04755 if (urgentmsgs) 04756 *urgentmsgs = 0; 04757 04758 if (strchr(mailbox, ',')) { 04759 int tmpnew, tmpold, tmpurgent; 04760 char *mb, *cur; 04761 04762 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04763 mb = tmp; 04764 while ((cur = strsep(&mb, ", "))) { 04765 if (!ast_strlen_zero(cur)) { 04766 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 04767 return -1; 04768 else { 04769 if (newmsgs) 04770 *newmsgs += tmpnew; 04771 if (oldmsgs) 04772 *oldmsgs += tmpold; 04773 if (urgentmsgs) 04774 *urgentmsgs += tmpurgent; 04775 } 04776 } 04777 } 04778 return 0; 04779 } 04780 04781 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04782 04783 if ((context = strchr(tmp, '@'))) 04784 *context++ = '\0'; 04785 else 04786 context = "default"; 04787 04788 if (newmsgs) 04789 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 04790 if (oldmsgs) 04791 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 04792 if (urgentmsgs) 04793 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 04794 04795 return 0; 04796 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 3598 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().
03599 { 03600 int l; 03601 03602 if (bio->ateof) 03603 return 0; 03604 03605 if ((l = fread(bio->iobuf,1,BASEMAXINLINE,fi)) <= 0) { 03606 if (ferror(fi)) 03607 return -1; 03608 03609 bio->ateof = 1; 03610 return 0; 03611 } 03612 03613 bio->iolen= l; 03614 bio->iocp= 0; 03615 03616 return 1; 03617 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 3622 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
03623 { 03624 if (bio->iocp>=bio->iolen) { 03625 if (!inbuf(bio, fi)) 03626 return EOF; 03627 } 03628 03629 return bio->iobuf[bio->iocp++]; 03630 }
static int invent_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | ext, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 4359 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.
04360 { 04361 int res; 04362 char fn[PATH_MAX]; 04363 char dest[PATH_MAX]; 04364 04365 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04366 04367 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04368 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04369 return -1; 04370 } 04371 04372 RETRIEVE(fn, -1, ext, context); 04373 if (ast_fileexists(fn, NULL, NULL) > 0) { 04374 res = ast_stream_and_wait(chan, fn, ecodes); 04375 if (res) { 04376 DISPOSE(fn, -1); 04377 return res; 04378 } 04379 } else { 04380 /* Dispose just in case */ 04381 DISPOSE(fn, -1); 04382 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04383 if (res) 04384 return res; 04385 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04386 if (res) 04387 return res; 04388 } 04389 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04390 return res; 04391 }
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 1027 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by load_config().
01028 { 01029 int i; 01030 char *local_key = ast_strdupa(key); 01031 01032 for (i = 0; i < strlen(key); ++i) { 01033 if (!strchr(VALID_DTMF, *local_key)) { 01034 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01035 return 0; 01036 } 01037 local_key++; 01038 } 01039 return 1; 01040 }
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 3427 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().
03428 { 03429 int x; 03430 unsigned char map[MAXMSGLIMIT] = ""; 03431 DIR *msgdir; 03432 struct dirent *msgdirent; 03433 int msgdirint; 03434 03435 /* Reading the entire directory into a file map scales better than 03436 * doing a stat repeatedly on a predicted sequence. I suspect this 03437 * is partially due to stat(2) internally doing a readdir(2) itself to 03438 * find each file. */ 03439 msgdir = opendir(dir); 03440 while ((msgdirent = readdir(msgdir))) { 03441 if (sscanf(msgdirent->d_name, "msg%d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) 03442 map[msgdirint] = 1; 03443 } 03444 closedir(msgdir); 03445 03446 for (x = 0; x < vmu->maxmsg; x++) { 03447 if (map[x] == 0) 03448 break; 03449 } 03450 03451 return x - 1; 03452 }
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 4868 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_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_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(), 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(), 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.
04869 { 04870 #ifdef IMAP_STORAGE 04871 int newmsgs, oldmsgs; 04872 #else 04873 char urgdir[PATH_MAX]; 04874 #endif 04875 char txtfile[PATH_MAX]; 04876 char tmptxtfile[PATH_MAX]; 04877 struct vm_state *vms = NULL; 04878 char callerid[256]; 04879 FILE *txt; 04880 char date[256]; 04881 int txtdes; 04882 int res = 0; 04883 int msgnum; 04884 int duration = 0; 04885 int ausemacro = 0; 04886 int ousemacro = 0; 04887 int ouseexten = 0; 04888 int rtmsgid = 0; 04889 char tmpid[16]; 04890 char tmpdur[16]; 04891 char priority[16]; 04892 char origtime[16]; 04893 char dir[PATH_MAX]; 04894 char tmpdir[PATH_MAX]; 04895 char fn[PATH_MAX]; 04896 char prefile[PATH_MAX] = ""; 04897 char tempfile[PATH_MAX] = ""; 04898 char ext_context[256] = ""; 04899 char fmt[80]; 04900 char *context; 04901 char ecodes[17] = "#"; 04902 char tmp[1024] = ""; 04903 char *tmpptr; 04904 struct ast_vm_user *vmu; 04905 struct ast_vm_user svm; 04906 const char *category = NULL; 04907 const char *code; 04908 const char *alldtmf = "0123456789ABCD*#"; 04909 char flag[80]; 04910 04911 ast_copy_string(tmp, ext, sizeof(tmp)); 04912 ext = tmp; 04913 if ((context = strchr(tmp, '@'))) { 04914 *context++ = '\0'; 04915 tmpptr = strchr(context, '&'); 04916 } else { 04917 tmpptr = strchr(ext, '&'); 04918 } 04919 04920 if (tmpptr) 04921 *tmpptr++ = '\0'; 04922 04923 ast_channel_lock(chan); 04924 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 04925 category = ast_strdupa(category); 04926 } 04927 ast_channel_unlock(chan); 04928 04929 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 04930 ast_copy_string(flag, "Urgent", sizeof(flag)); 04931 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 04932 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 04933 } else { 04934 flag[0] = '\0'; 04935 } 04936 04937 ast_debug(3, "Before find_user\n"); 04938 if (!(vmu = find_user(&svm, context, ext))) { 04939 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 04940 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04941 return res; 04942 } 04943 /* Setup pre-file if appropriate */ 04944 if (strcmp(vmu->context, "default")) 04945 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 04946 else 04947 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 04948 04949 /* Set the path to the prefile. Will be one of 04950 VM_SPOOL_DIRcontext/ext/busy 04951 VM_SPOOL_DIRcontext/ext/unavail 04952 Depending on the flag set in options. 04953 */ 04954 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 04955 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 04956 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 04957 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 04958 } 04959 /* Set the path to the tmpfile as 04960 VM_SPOOL_DIR/context/ext/temp 04961 and attempt to create the folder structure. 04962 */ 04963 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 04964 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 04965 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 04966 return -1; 04967 } 04968 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 04969 if (ast_fileexists(tempfile, NULL, NULL) > 0) 04970 ast_copy_string(prefile, tempfile, sizeof(prefile)); 04971 04972 DISPOSE(tempfile, -1); 04973 /* It's easier just to try to make it than to check for its existence */ 04974 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 04975 04976 /* Check current or macro-calling context for special extensions */ 04977 if (ast_test_flag(vmu, VM_OPERATOR)) { 04978 if (!ast_strlen_zero(vmu->exit)) { 04979 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 04980 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 04981 ouseexten = 1; 04982 } 04983 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 04984 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 04985 ouseexten = 1; 04986 } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 04987 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 04988 ousemacro = 1; 04989 } 04990 } 04991 04992 if (!ast_strlen_zero(vmu->exit)) { 04993 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 04994 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 04995 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 04996 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 04997 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 04998 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 04999 ausemacro = 1; 05000 } 05001 05002 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05003 for (code = alldtmf; *code; code++) { 05004 char e[2] = ""; 05005 e[0] = *code; 05006 if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) 05007 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05008 } 05009 } 05010 05011 /* Play the beginning intro if desired */ 05012 if (!ast_strlen_zero(prefile)) { 05013 #ifdef ODBC_STORAGE 05014 int success = 05015 #endif 05016 RETRIEVE(prefile, -1, ext, context); 05017 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05018 if (ast_streamfile(chan, prefile, chan->language) > -1) 05019 res = ast_waitstream(chan, ecodes); 05020 #ifdef ODBC_STORAGE 05021 if (success == -1) { 05022 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05023 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05024 store_file(prefile, vmu->mailbox, vmu->context, -1); 05025 } 05026 #endif 05027 } else { 05028 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05029 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05030 } 05031 DISPOSE(prefile, -1); 05032 if (res < 0) { 05033 ast_debug(1, "Hang up during prefile playback\n"); 05034 free_user(vmu); 05035 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05036 return -1; 05037 } 05038 } 05039 if (res == '#') { 05040 /* On a '#' we skip the instructions */ 05041 ast_set_flag(options, OPT_SILENT); 05042 res = 0; 05043 } 05044 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05045 res = ast_stream_and_wait(chan, INTRO, ecodes); 05046 if (res == '#') { 05047 ast_set_flag(options, OPT_SILENT); 05048 res = 0; 05049 } 05050 } 05051 if (res > 0) 05052 ast_stopstream(chan); 05053 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05054 other than the operator -- an automated attendant or mailbox login for example */ 05055 if (res == '*') { 05056 chan->exten[0] = 'a'; 05057 chan->exten[1] = '\0'; 05058 if (!ast_strlen_zero(vmu->exit)) { 05059 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05060 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05061 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05062 } 05063 chan->priority = 0; 05064 free_user(vmu); 05065 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05066 return 0; 05067 } 05068 05069 /* Check for a '0' here */ 05070 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05071 transfer: 05072 if (ouseexten || ousemacro) { 05073 chan->exten[0] = 'o'; 05074 chan->exten[1] = '\0'; 05075 if (!ast_strlen_zero(vmu->exit)) { 05076 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05077 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05078 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05079 } 05080 ast_play_and_wait(chan, "transfer"); 05081 chan->priority = 0; 05082 free_user(vmu); 05083 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05084 } 05085 return 0; 05086 } 05087 05088 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05089 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05090 if (!ast_strlen_zero(options->exitcontext)) 05091 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05092 free_user(vmu); 05093 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05094 return res; 05095 } 05096 05097 if (res < 0) { 05098 free_user(vmu); 05099 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05100 return -1; 05101 } 05102 /* The meat of recording the message... All the announcements and beeps have been played*/ 05103 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05104 if (!ast_strlen_zero(fmt)) { 05105 msgnum = 0; 05106 05107 #ifdef IMAP_STORAGE 05108 /* Is ext a mailbox? */ 05109 /* must open stream for this user to get info! */ 05110 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05111 if (res < 0) { 05112 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05113 return -1; 05114 } 05115 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05116 /* It is possible under certain circumstances that inboxcount did not 05117 * create a vm_state when it was needed. This is a catchall which will 05118 * rarely be used. 05119 */ 05120 if (!(vms = create_vm_state_from_user(vmu))) { 05121 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05122 return -1; 05123 } 05124 } 05125 vms->newmessages++; 05126 05127 /* here is a big difference! We add one to it later */ 05128 msgnum = newmsgs + oldmsgs; 05129 ast_debug(3, "Messagecount set to %d\n",msgnum); 05130 snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05131 /* set variable for compatibility */ 05132 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05133 05134 /* Check if mailbox is full */ 05135 check_quota(vms, imapfolder); 05136 if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) { 05137 ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit); 05138 ast_play_and_wait(chan, "vm-mailboxfull"); 05139 return -1; 05140 } 05141 05142 /* Check if we have exceeded maxmsg */ 05143 if (msgnum >= vmu->maxmsg) { 05144 ast_log(AST_LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg); 05145 ast_play_and_wait(chan, "vm-mailboxfull"); 05146 return -1; 05147 } 05148 #else 05149 if (count_messages(vmu, dir) >= vmu->maxmsg) { 05150 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05151 if (!res) 05152 res = ast_waitstream(chan, ""); 05153 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05154 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05155 goto leave_vm_out; 05156 } 05157 05158 #endif 05159 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05160 txtdes = mkstemp(tmptxtfile); 05161 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05162 if (txtdes < 0) { 05163 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05164 if (!res) 05165 res = ast_waitstream(chan, ""); 05166 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05167 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05168 goto leave_vm_out; 05169 } 05170 05171 /* Now play the beep once we have the message number for our next message. */ 05172 if (res >= 0) { 05173 /* Unless we're *really* silent, try to send the beep */ 05174 res = ast_stream_and_wait(chan, "beep", ""); 05175 } 05176 05177 /* Store information in real-time storage */ 05178 if (ast_check_realtime("voicemail_data")) { 05179 snprintf(priority, sizeof(priority), "%d", chan->priority); 05180 snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL)); 05181 get_date(date, sizeof(date)); 05182 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); 05183 } 05184 05185 /* Store information */ 05186 txt = fdopen(txtdes, "w+"); 05187 if (txt) { 05188 get_date(date, sizeof(date)); 05189 fprintf(txt, 05190 ";\n" 05191 "; Message Information file\n" 05192 ";\n" 05193 "[message]\n" 05194 "origmailbox=%s\n" 05195 "context=%s\n" 05196 "macrocontext=%s\n" 05197 "exten=%s\n" 05198 "priority=%d\n" 05199 "callerchan=%s\n" 05200 "callerid=%s\n" 05201 "origdate=%s\n" 05202 "origtime=%ld\n" 05203 "category=%s\n", 05204 ext, 05205 chan->context, 05206 chan->macrocontext, 05207 chan->exten, 05208 chan->priority, 05209 chan->name, 05210 ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"), 05211 date, (long)time(NULL), 05212 category ? category : ""); 05213 } else 05214 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05215 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05216 05217 if (txt) { 05218 fprintf(txt, "flag=%s\n", flag); 05219 if (duration < vmminsecs) { 05220 fclose(txt); 05221 if (option_verbose > 2) 05222 ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs); 05223 ast_filedelete(tmptxtfile, NULL); 05224 unlink(tmptxtfile); 05225 if (ast_check_realtime("voicemail_data")) { 05226 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05227 ast_destroy_realtime("voicemail_data", "id", tmpid, SENTINEL); 05228 } 05229 } else { 05230 fprintf(txt, "duration=%d\n", duration); 05231 fclose(txt); 05232 if (vm_lock_path(dir)) { 05233 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05234 /* Delete files */ 05235 ast_filedelete(tmptxtfile, NULL); 05236 unlink(tmptxtfile); 05237 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05238 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05239 unlink(tmptxtfile); 05240 ast_unlock_path(dir); 05241 if (ast_check_realtime("voicemail_data")) { 05242 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05243 ast_destroy_realtime("voicemail_data", "id", tmpid, SENTINEL); 05244 } 05245 } else { 05246 #ifndef IMAP_STORAGE 05247 msgnum = last_message_index(vmu, dir) + 1; 05248 #endif 05249 make_file(fn, sizeof(fn), dir, msgnum); 05250 05251 /* assign a variable with the name of the voicemail file */ 05252 #ifndef IMAP_STORAGE 05253 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05254 #else 05255 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05256 #endif 05257 05258 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05259 ast_filerename(tmptxtfile, fn, NULL); 05260 rename(tmptxtfile, txtfile); 05261 05262 /* Properly set permissions on voicemail text descriptor file. 05263 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05264 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05265 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05266 05267 ast_unlock_path(dir); 05268 if (ast_check_realtime("voicemail_data")) { 05269 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 05270 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05271 ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, SENTINEL); 05272 } 05273 /* We must store the file first, before copying the message, because 05274 * ODBC storage does the entire copy with SQL. 05275 */ 05276 if (ast_fileexists(fn, NULL, NULL) > 0) { 05277 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05278 } 05279 05280 /* Are there to be more recipients of this message? */ 05281 while (tmpptr) { 05282 struct ast_vm_user recipu, *recip; 05283 char *exten, *cntx; 05284 05285 exten = strsep(&tmpptr, "&"); 05286 cntx = strchr(exten, '@'); 05287 if (cntx) { 05288 *cntx = '\0'; 05289 cntx++; 05290 } 05291 if ((recip = find_user(&recipu, cntx, exten))) { 05292 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05293 free_user(recip); 05294 } 05295 } 05296 #ifndef IMAP_STORAGE 05297 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05298 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05299 char sfn[PATH_MAX]; 05300 char dfn[PATH_MAX]; 05301 int x; 05302 /* It's easier just to try to make it than to check for its existence */ 05303 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05304 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n",sfn,dfn); 05305 x = last_message_index(vmu, urgdir) + 1; 05306 make_file(sfn, sizeof(sfn), dir, msgnum); 05307 make_file(dfn, sizeof(dfn), urgdir, x); 05308 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05309 } 05310 #endif 05311 /* Notification needs to happen after the copy, though. */ 05312 if (ast_fileexists(fn, NULL, NULL)) { 05313 #ifdef IMAP_STORAGE 05314 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05315 #else 05316 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05317 #endif 05318 } 05319 05320 /* Disposal needs to happen after the optional move and copy */ 05321 if (ast_fileexists(fn, NULL, NULL)) { 05322 DISPOSE(dir, msgnum); 05323 } 05324 } 05325 } 05326 } 05327 if (res == '0') { 05328 goto transfer; 05329 } else if (res > 0) 05330 res = 0; 05331 05332 if (duration < vmminsecs) 05333 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05334 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05335 else 05336 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05337 } else 05338 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 05339 leave_vm_out: 05340 free_user(vmu); 05341 05342 #ifdef IMAP_STORAGE 05343 /* expunge message - use UID Expunge if supported on IMAP server*/ 05344 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n",expungeonhangup); 05345 if (expungeonhangup == 1) { 05346 ast_mutex_lock(&vms->lock); 05347 #ifdef HAVE_IMAP_TK2006 05348 if (LEVELUIDPLUS (vms->mailstream)) { 05349 mail_expunge_full(vms->mailstream,NIL,EX_UID); 05350 } else 05351 #endif 05352 mail_expunge(vms->mailstream); 05353 ast_mutex_unlock(&vms->lock); 05354 } 05355 #endif 05356 05357 return res; 05358 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 10258 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_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, 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_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.
10259 { 10260 struct ast_vm_user *current; 10261 struct ast_config *cfg, *ucfg; 10262 char *cat; 10263 struct ast_variable *var; 10264 const char *val; 10265 char *q, *stringp; 10266 int x; 10267 int tmpadsi[4]; 10268 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 10269 10270 ast_unload_realtime("voicemail"); 10271 ast_unload_realtime("voicemail_data"); 10272 10273 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 10274 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) 10275 return 0; 10276 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10277 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 10278 } else { 10279 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10280 ucfg = ast_config_load("users.conf", config_flags); 10281 } 10282 #ifdef IMAP_STORAGE 10283 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 10284 #endif 10285 /* set audio control prompts */ 10286 strcpy(listen_control_forward_key,DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 10287 strcpy(listen_control_reverse_key,DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 10288 strcpy(listen_control_pause_key,DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 10289 strcpy(listen_control_restart_key,DEFAULT_LISTEN_CONTROL_RESTART_KEY); 10290 strcpy(listen_control_stop_key,DEFAULT_LISTEN_CONTROL_STOP_KEY); 10291 10292 /* Free all the users structure */ 10293 free_vm_users(); 10294 10295 /* Free all the zones structure */ 10296 free_vm_zones(); 10297 10298 AST_LIST_LOCK(&users); 10299 10300 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 10301 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 10302 10303 if (cfg) { 10304 /* General settings */ 10305 10306 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 10307 val = "default"; 10308 ast_copy_string(userscontext, val, sizeof(userscontext)); 10309 /* Attach voice message to mail message ? */ 10310 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 10311 val = "yes"; 10312 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 10313 10314 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 10315 val = "no"; 10316 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 10317 10318 volgain = 0.0; 10319 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 10320 sscanf(val, "%lf", &volgain); 10321 10322 #ifdef ODBC_STORAGE 10323 strcpy(odbc_database, "asterisk"); 10324 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 10325 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 10326 } 10327 strcpy(odbc_table, "voicemessages"); 10328 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 10329 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 10330 } 10331 #endif 10332 /* Mail command */ 10333 strcpy(mailcmd, SENDMAIL); 10334 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 10335 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 10336 10337 maxsilence = 0; 10338 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 10339 maxsilence = atoi(val); 10340 if (maxsilence > 0) 10341 maxsilence *= 1000; 10342 } 10343 10344 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 10345 maxmsg = MAXMSG; 10346 } else { 10347 maxmsg = atoi(val); 10348 if (maxmsg <= 0) { 10349 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 10350 maxmsg = MAXMSG; 10351 } else if (maxmsg > MAXMSGLIMIT) { 10352 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10353 maxmsg = MAXMSGLIMIT; 10354 } 10355 } 10356 10357 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 10358 maxdeletedmsg = 0; 10359 } else { 10360 if (sscanf(val, "%d", &x) == 1) 10361 maxdeletedmsg = x; 10362 else if (ast_true(val)) 10363 maxdeletedmsg = MAXMSG; 10364 else 10365 maxdeletedmsg = 0; 10366 10367 if (maxdeletedmsg < 0) { 10368 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 10369 maxdeletedmsg = MAXMSG; 10370 } else if (maxdeletedmsg > MAXMSGLIMIT) { 10371 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10372 maxdeletedmsg = MAXMSGLIMIT; 10373 } 10374 } 10375 10376 /* Load date format config for voicemail mail */ 10377 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 10378 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 10379 } 10380 10381 /* External password changing command */ 10382 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 10383 ast_copy_string(ext_pass_cmd,val,sizeof(ext_pass_cmd)); 10384 pwdchange = PWDCHANGE_EXTERNAL; 10385 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 10386 ast_copy_string(ext_pass_cmd,val,sizeof(ext_pass_cmd)); 10387 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 10388 } 10389 10390 /* External password validation command */ 10391 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 10392 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 10393 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 10394 } 10395 10396 #ifdef IMAP_STORAGE 10397 /* IMAP server address */ 10398 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 10399 ast_copy_string(imapserver, val, sizeof(imapserver)); 10400 } else { 10401 ast_copy_string(imapserver,"localhost", sizeof(imapserver)); 10402 } 10403 /* IMAP server port */ 10404 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 10405 ast_copy_string(imapport, val, sizeof(imapport)); 10406 } else { 10407 ast_copy_string(imapport,"143", sizeof(imapport)); 10408 } 10409 /* IMAP server flags */ 10410 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 10411 ast_copy_string(imapflags, val, sizeof(imapflags)); 10412 } 10413 /* IMAP server master username */ 10414 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 10415 ast_copy_string(authuser, val, sizeof(authuser)); 10416 } 10417 /* IMAP server master password */ 10418 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 10419 ast_copy_string(authpassword, val, sizeof(authpassword)); 10420 } 10421 /* Expunge on exit */ 10422 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 10423 if (ast_false(val)) 10424 expungeonhangup = 0; 10425 else 10426 expungeonhangup = 1; 10427 } else { 10428 expungeonhangup = 1; 10429 } 10430 /* IMAP voicemail folder */ 10431 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 10432 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 10433 } else { 10434 ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder)); 10435 } 10436 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 10437 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 10438 } 10439 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 10440 imapgreetings = ast_true(val); 10441 } else { 10442 imapgreetings = 0; 10443 } 10444 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 10445 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 10446 } else { 10447 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 10448 } 10449 10450 /* There is some very unorthodox casting done here. This is due 10451 * to the way c-client handles the argument passed in. It expects a 10452 * void pointer and casts the pointer directly to a long without 10453 * first dereferencing it. */ 10454 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 10455 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 10456 } else { 10457 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 10458 } 10459 10460 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 10461 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 10462 } else { 10463 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 10464 } 10465 10466 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 10467 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 10468 } else { 10469 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 10470 } 10471 10472 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 10473 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 10474 } else { 10475 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 10476 } 10477 10478 #endif 10479 /* External voicemail notify application */ 10480 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 10481 ast_copy_string(externnotify, val, sizeof(externnotify)); 10482 ast_debug(1, "found externnotify: %s\n", externnotify); 10483 } else { 10484 externnotify[0] = '\0'; 10485 } 10486 10487 /* SMDI voicemail notification */ 10488 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 10489 ast_debug(1, "Enabled SMDI voicemail notification\n"); 10490 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 10491 smdi_iface = ast_smdi_interface_find(val); 10492 } else { 10493 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 10494 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 10495 } 10496 if (!smdi_iface) { 10497 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 10498 } 10499 } 10500 10501 /* Silence treshold */ 10502 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 10503 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 10504 silencethreshold = atoi(val); 10505 10506 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 10507 val = ASTERISK_USERNAME; 10508 ast_copy_string(serveremail, val, sizeof(serveremail)); 10509 10510 vmmaxsecs = 0; 10511 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 10512 if (sscanf(val, "%d", &x) == 1) { 10513 vmmaxsecs = x; 10514 } else { 10515 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10516 } 10517 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 10518 static int maxmessage_deprecate = 0; 10519 if (maxmessage_deprecate == 0) { 10520 maxmessage_deprecate = 1; 10521 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 10522 } 10523 if (sscanf(val, "%d", &x) == 1) { 10524 vmmaxsecs = x; 10525 } else { 10526 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10527 } 10528 } 10529 10530 vmminsecs = 0; 10531 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 10532 if (sscanf(val, "%d", &x) == 1) { 10533 vmminsecs = x; 10534 if (maxsilence <= vmminsecs) 10535 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 10536 } else { 10537 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10538 } 10539 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 10540 static int maxmessage_deprecate = 0; 10541 if (maxmessage_deprecate == 0) { 10542 maxmessage_deprecate = 1; 10543 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 10544 } 10545 if (sscanf(val, "%d", &x) == 1) { 10546 vmminsecs = x; 10547 if (maxsilence <= vmminsecs) 10548 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 10549 } else { 10550 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10551 } 10552 } 10553 10554 val = ast_variable_retrieve(cfg, "general", "format"); 10555 if (!val) 10556 val = "wav"; 10557 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 10558 10559 skipms = 3000; 10560 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 10561 if (sscanf(val, "%d", &x) == 1) { 10562 maxgreet = x; 10563 } else { 10564 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 10565 } 10566 } 10567 10568 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 10569 if (sscanf(val, "%d", &x) == 1) { 10570 skipms = x; 10571 } else { 10572 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 10573 } 10574 } 10575 10576 maxlogins = 3; 10577 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 10578 if (sscanf(val, "%d", &x) == 1) { 10579 maxlogins = x; 10580 } else { 10581 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 10582 } 10583 } 10584 10585 minpassword = MINPASSWORD; 10586 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 10587 if (sscanf(val, "%d", &x) == 1) { 10588 minpassword = x; 10589 } else { 10590 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 10591 } 10592 } 10593 10594 /* Force new user to record name ? */ 10595 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 10596 val = "no"; 10597 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 10598 10599 /* Force new user to record greetings ? */ 10600 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 10601 val = "no"; 10602 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 10603 10604 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 10605 ast_debug(1, "VM_CID Internal context string: %s\n", val); 10606 stringp = ast_strdupa(val); 10607 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 10608 if (!ast_strlen_zero(stringp)) { 10609 q = strsep(&stringp, ","); 10610 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 10611 q++; 10612 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 10613 ast_debug(1,"VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 10614 } else { 10615 cidinternalcontexts[x][0] = '\0'; 10616 } 10617 } 10618 } 10619 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 10620 ast_debug(1,"VM Review Option disabled globally\n"); 10621 val = "no"; 10622 } 10623 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 10624 10625 /* Temporary greeting reminder */ 10626 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 10627 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 10628 val = "no"; 10629 } else { 10630 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 10631 } 10632 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 10633 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 10634 ast_debug(1, "VM next message wrap disabled globally\n"); 10635 val = "no"; 10636 } 10637 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 10638 10639 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 10640 ast_debug(1,"VM Operator break disabled globally\n"); 10641 val = "no"; 10642 } 10643 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 10644 10645 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 10646 ast_debug(1,"VM CID Info before msg disabled globally\n"); 10647 val = "no"; 10648 } 10649 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 10650 10651 if (!(val = ast_variable_retrieve(cfg,"general", "sendvoicemail"))){ 10652 ast_debug(1,"Send Voicemail msg disabled globally\n"); 10653 val = "no"; 10654 } 10655 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 10656 10657 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 10658 ast_debug(1,"ENVELOPE before msg enabled globally\n"); 10659 val = "yes"; 10660 } 10661 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 10662 10663 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 10664 ast_debug(1,"Move Heard enabled globally\n"); 10665 val = "yes"; 10666 } 10667 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 10668 10669 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 10670 ast_debug(1,"Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 10671 val = "no"; 10672 } 10673 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 10674 10675 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 10676 ast_debug(1,"Duration info before msg enabled globally\n"); 10677 val = "yes"; 10678 } 10679 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 10680 10681 saydurationminfo = 2; 10682 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 10683 if (sscanf(val, "%d", &x) == 1) { 10684 saydurationminfo = x; 10685 } else { 10686 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 10687 } 10688 } 10689 10690 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 10691 ast_debug(1,"We are not going to skip to the next msg after save/delete\n"); 10692 val = "no"; 10693 } 10694 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 10695 10696 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 10697 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 10698 ast_debug(1, "found dialout context: %s\n", dialcontext); 10699 } else { 10700 dialcontext[0] = '\0'; 10701 } 10702 10703 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 10704 ast_copy_string(callcontext, val, sizeof(callcontext)); 10705 ast_debug(1, "found callback context: %s\n", callcontext); 10706 } else { 10707 callcontext[0] = '\0'; 10708 } 10709 10710 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 10711 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 10712 ast_debug(1, "found operator context: %s\n", exitcontext); 10713 } else { 10714 exitcontext[0] = '\0'; 10715 } 10716 10717 /* load password sounds configuration */ 10718 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 10719 ast_copy_string(vm_password, val, sizeof(vm_password)); 10720 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 10721 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 10722 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 10723 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 10724 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 10725 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 10726 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 10727 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 10728 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 10729 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 10730 /* load configurable audio prompts */ 10731 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 10732 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 10733 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 10734 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 10735 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 10736 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 10737 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 10738 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 10739 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 10740 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 10741 10742 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 10743 val = "no"; 10744 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 10745 10746 poll_freq = DEFAULT_POLL_FREQ; 10747 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 10748 if (sscanf(val, "%u", &poll_freq) != 1) { 10749 poll_freq = DEFAULT_POLL_FREQ; 10750 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 10751 } 10752 } 10753 10754 poll_mailboxes = 0; 10755 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 10756 poll_mailboxes = ast_true(val); 10757 10758 if (ucfg) { 10759 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 10760 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 10761 continue; 10762 if ((current = find_or_create(userscontext, cat))) { 10763 populate_defaults(current); 10764 apply_options_full(current, ast_variable_browse(ucfg, cat)); 10765 ast_copy_string(current->context, userscontext, sizeof(current->context)); 10766 } 10767 } 10768 ast_config_destroy(ucfg); 10769 } 10770 cat = ast_category_browse(cfg, NULL); 10771 while (cat) { 10772 if (strcasecmp(cat, "general")) { 10773 var = ast_variable_browse(cfg, cat); 10774 if (strcasecmp(cat, "zonemessages")) { 10775 /* Process mailboxes in this context */ 10776 while (var) { 10777 append_mailbox(cat, var->name, var->value); 10778 var = var->next; 10779 } 10780 } else { 10781 /* Timezones in this context */ 10782 while (var) { 10783 struct vm_zone *z; 10784 if ((z = ast_malloc(sizeof(*z)))) { 10785 char *msg_format, *tzone; 10786 msg_format = ast_strdupa(var->value); 10787 tzone = strsep(&msg_format, "|"); 10788 if (msg_format) { 10789 ast_copy_string(z->name, var->name, sizeof(z->name)); 10790 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 10791 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 10792 AST_LIST_LOCK(&zones); 10793 AST_LIST_INSERT_HEAD(&zones, z, list); 10794 AST_LIST_UNLOCK(&zones); 10795 } else { 10796 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 10797 ast_free(z); 10798 } 10799 } else { 10800 AST_LIST_UNLOCK(&users); 10801 ast_config_destroy(cfg); 10802 return -1; 10803 } 10804 var = var->next; 10805 } 10806 } 10807 } 10808 cat = ast_category_browse(cfg, cat); 10809 } 10810 memset(fromstring, 0, sizeof(fromstring)); 10811 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 10812 strcpy(charset, "ISO-8859-1"); 10813 if (emailbody) { 10814 ast_free(emailbody); 10815 emailbody = NULL; 10816 } 10817 if (emailsubject) { 10818 ast_free(emailsubject); 10819 emailsubject = NULL; 10820 } 10821 if (pagerbody) { 10822 ast_free(pagerbody); 10823 pagerbody = NULL; 10824 } 10825 if (pagersubject) { 10826 ast_free(pagersubject); 10827 pagersubject = NULL; 10828 } 10829 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 10830 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 10831 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 10832 ast_copy_string(fromstring, val, sizeof(fromstring)); 10833 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 10834 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 10835 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 10836 ast_copy_string(charset, val, sizeof(charset)); 10837 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 10838 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 10839 for (x = 0; x < 4; x++) { 10840 memcpy(&adsifdn[x], &tmpadsi[x], 1); 10841 } 10842 } 10843 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 10844 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 10845 for (x = 0; x < 4; x++) { 10846 memcpy(&adsisec[x], &tmpadsi[x], 1); 10847 } 10848 } 10849 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 10850 if (atoi(val)) { 10851 adsiver = atoi(val); 10852 } 10853 } 10854 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 10855 ast_copy_string(zonetag, val, sizeof(zonetag)); 10856 } 10857 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 10858 emailsubject = ast_strdup(val); 10859 } 10860 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 10861 emailbody = substitute_escapes(val); 10862 } 10863 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 10864 pagersubject = ast_strdup(val); 10865 } 10866 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 10867 pagerbody = substitute_escapes(val); 10868 } 10869 AST_LIST_UNLOCK(&users); 10870 ast_config_destroy(cfg); 10871 10872 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 10873 start_poll_thread(); 10874 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 10875 stop_poll_thread();; 10876 10877 return 0; 10878 } else { 10879 AST_LIST_UNLOCK(&users); 10880 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 10881 if (ucfg) 10882 ast_config_destroy(ucfg); 10883 return 0; 10884 } 10885 }
static int load_module | ( | void | ) | [static] |
Definition at line 10931 of file app_voicemail.c.
References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_install_vm_functions(), ast_log(), ast_manager_register, ast_realtime_require_field(), ast_register_application, ast_taskprocessor_get(), cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), 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().
10932 { 10933 int res; 10934 my_umask = umask(0); 10935 umask(my_umask); 10936 10937 /* compute the location of the voicemail spool directory */ 10938 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 10939 10940 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 10941 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 10942 } 10943 10944 if ((res = load_config(0))) 10945 return res; 10946 10947 res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm); 10948 res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain); 10949 res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists); 10950 res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate); 10951 res |= ast_custom_function_register(&mailbox_exists_acf); 10952 res |= ast_manager_register("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users, "List All Voicemail User Information"); 10953 if (res) 10954 return res; 10955 10956 ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 10957 10958 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 10959 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 10960 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 10961 10962 return res; 10963 }
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 1244 of file app_voicemail.c.
01245 { 01246 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01247 }
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 3906 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, pbx_substitute_variables_helper(), prep_email_sub_vars(), ast_channel::priority, quote(), strip_control(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
03907 { 03908 char date[256]; 03909 char host[MAXHOSTNAMELEN] = ""; 03910 char who[256]; 03911 char bound[256]; 03912 char dur[256]; 03913 struct ast_tm tm; 03914 char enc_cidnum[256] = "", enc_cidname[256] = ""; 03915 char *passdata = NULL, *passdata2; 03916 size_t len_passdata = 0, len_passdata2, tmplen; 03917 char *greeting_attachment; 03918 char filename[256]; 03919 03920 #ifdef IMAP_STORAGE 03921 #define ENDL "\r\n" 03922 #else 03923 #define ENDL "\n" 03924 #endif 03925 03926 /* One alloca for multiple fields */ 03927 len_passdata2 = strlen(vmu->fullname); 03928 if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) { 03929 len_passdata2 = tmplen; 03930 } 03931 if ((tmplen = strlen(fromstring)) > len_passdata2) { 03932 len_passdata2 = tmplen; 03933 } 03934 len_passdata2 = len_passdata2 * 3 + 200; 03935 passdata2 = alloca(len_passdata2); 03936 03937 if (cidnum) { 03938 strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum)); 03939 } 03940 if (cidname) { 03941 strip_control(cidname, enc_cidname, sizeof(enc_cidname)); 03942 } 03943 gethostname(host, sizeof(host) - 1); 03944 03945 if (strchr(srcemail, '@')) 03946 ast_copy_string(who, srcemail, sizeof(who)); 03947 else 03948 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 03949 03950 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 03951 if (greeting_attachment) 03952 *greeting_attachment++ = '\0'; 03953 03954 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 03955 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 03956 fprintf(p, "Date: %s" ENDL, date); 03957 03958 /* Set date format for voicemail mail */ 03959 ast_strftime(date, sizeof(date), emaildateformat, &tm); 03960 03961 if (!ast_strlen_zero(fromstring)) { 03962 struct ast_channel *ast; 03963 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 03964 char *ptr; 03965 memset(passdata2, 0, len_passdata2); 03966 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category, flag); 03967 pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2); 03968 len_passdata = strlen(passdata2) * 3 + 300; 03969 passdata = alloca(len_passdata); 03970 if (check_mime(passdata2)) { 03971 int first_line = 1; 03972 encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3); 03973 while ((ptr = strchr(passdata, ' '))) { 03974 *ptr = '\0'; 03975 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata); 03976 first_line = 0; 03977 passdata = ptr + 1; 03978 } 03979 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who); 03980 } else { 03981 fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who); 03982 } 03983 ast_channel_free(ast); 03984 } else { 03985 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 03986 } 03987 } else { 03988 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 03989 } 03990 03991 if (check_mime(vmu->fullname)) { 03992 int first_line = 1; 03993 char *ptr; 03994 encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3); 03995 while ((ptr = strchr(passdata2, ' '))) { 03996 *ptr = '\0'; 03997 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2); 03998 first_line = 0; 03999 passdata2 = ptr + 1; 04000 } 04001 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email); 04002 } else { 04003 fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email); 04004 } 04005 if (!ast_strlen_zero(emailsubject)) { 04006 struct ast_channel *ast; 04007 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04008 int vmlen = strlen(emailsubject) * 3 + 200; 04009 /* Only allocate more space if the previous was not large enough */ 04010 if (vmlen > len_passdata) { 04011 passdata = alloca(vmlen); 04012 len_passdata = vmlen; 04013 } 04014 04015 memset(passdata, 0, len_passdata); 04016 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category, flag); 04017 pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata); 04018 if (check_mime(passdata)) { 04019 int first_line = 1; 04020 char *ptr; 04021 encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0); 04022 while ((ptr = strchr(passdata2, ' '))) { 04023 *ptr = '\0'; 04024 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 04025 first_line = 0; 04026 passdata2 = ptr + 1; 04027 } 04028 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 04029 } else { 04030 fprintf(p, "Subject: %s" ENDL, passdata); 04031 } 04032 ast_channel_free(ast); 04033 } else { 04034 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04035 } 04036 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04037 if (ast_strlen_zero(flag)) { 04038 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04039 } else { 04040 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04041 } 04042 } else { 04043 if (ast_strlen_zero(flag)) { 04044 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04045 } else { 04046 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04047 } 04048 } 04049 04050 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host); 04051 if (imap) { 04052 /* additional information needed for IMAP searching */ 04053 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04054 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04055 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04056 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04057 #ifdef IMAP_STORAGE 04058 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04059 #else 04060 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04061 #endif 04062 /* flag added for Urgent */ 04063 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04064 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04065 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04066 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04067 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04068 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04069 if (!ast_strlen_zero(category)) { 04070 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04071 } else { 04072 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04073 } 04074 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04075 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04076 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL)); 04077 } 04078 if (!ast_strlen_zero(cidnum)) { 04079 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04080 } 04081 if (!ast_strlen_zero(cidname)) { 04082 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04083 } 04084 fprintf(p, "MIME-Version: 1.0" ENDL); 04085 if (attach_user_voicemail) { 04086 /* Something unique. */ 04087 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random()); 04088 04089 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04090 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04091 fprintf(p, "--%s" ENDL, bound); 04092 } 04093 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04094 if (emailbody) { 04095 struct ast_channel *ast; 04096 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04097 char *passdata; 04098 int vmlen = strlen(emailbody)*3 + 200; 04099 passdata = alloca(vmlen); 04100 memset(passdata, 0, vmlen); 04101 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04102 pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen); 04103 fprintf(p, "%s" ENDL, passdata); 04104 ast_channel_free(ast); 04105 } else 04106 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04107 } else if (msgnum > -1) { 04108 if (strcmp(vmu->mailbox, mailbox)) { 04109 /* Forwarded type */ 04110 struct ast_config *msg_cfg; 04111 const char *v; 04112 int inttime; 04113 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04114 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04115 /* Retrieve info from VM attribute file */ 04116 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04117 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04118 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04119 strcat(fromfile, ".txt"); 04120 } 04121 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04122 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04123 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04124 } 04125 04126 /* You might be tempted to do origdate, except that a) it's in the wrong 04127 * format, and b) it's missing for IMAP recordings. */ 04128 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%d", &inttime) == 1) { 04129 struct timeval tv = { inttime, }; 04130 struct ast_tm tm; 04131 ast_localtime(&tv, &tm, NULL); 04132 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 04133 } 04134 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04135 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04136 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04137 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04138 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04139 date, origcallerid, origdate); 04140 ast_config_destroy(msg_cfg); 04141 } else { 04142 goto plain_message; 04143 } 04144 } else { 04145 plain_message: 04146 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04147 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04148 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04149 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04150 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04151 } 04152 } else { 04153 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04154 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04155 } 04156 04157 if (imap || attach_user_voicemail) { 04158 if (!ast_strlen_zero(attach2)) { 04159 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04160 ast_debug(5, "creating second attachment filename %s\n", filename); 04161 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04162 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04163 ast_debug(5, "creating attachment filename %s\n", filename); 04164 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04165 } else { 04166 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04167 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04168 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04169 } 04170 } 04171 }
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 1259 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_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 10091 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().
10092 { 10093 struct ast_vm_user *vmu = NULL; 10094 const char *id = astman_get_header(m, "ActionID"); 10095 char actionid[128] = ""; 10096 10097 if (!ast_strlen_zero(id)) 10098 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 10099 10100 AST_LIST_LOCK(&users); 10101 10102 if (AST_LIST_EMPTY(&users)) { 10103 astman_send_ack(s, m, "There are no voicemail users currently defined."); 10104 AST_LIST_UNLOCK(&users); 10105 return RESULT_SUCCESS; 10106 } 10107 10108 astman_send_ack(s, m, "Voicemail user list will follow"); 10109 10110 AST_LIST_TRAVERSE(&users, vmu, list) { 10111 char dirname[256]; 10112 10113 #ifdef IMAP_STORAGE 10114 int new, old; 10115 inboxcount(vmu->mailbox, &new, &old); 10116 #endif 10117 10118 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 10119 astman_append(s, 10120 "%s" 10121 "Event: VoicemailUserEntry\r\n" 10122 "VMContext: %s\r\n" 10123 "VoiceMailbox: %s\r\n" 10124 "Fullname: %s\r\n" 10125 "Email: %s\r\n" 10126 "Pager: %s\r\n" 10127 "ServerEmail: %s\r\n" 10128 "MailCommand: %s\r\n" 10129 "Language: %s\r\n" 10130 "TimeZone: %s\r\n" 10131 "Callback: %s\r\n" 10132 "Dialout: %s\r\n" 10133 "UniqueID: %s\r\n" 10134 "ExitContext: %s\r\n" 10135 "SayDurationMinimum: %d\r\n" 10136 "SayEnvelope: %s\r\n" 10137 "SayCID: %s\r\n" 10138 "AttachMessage: %s\r\n" 10139 "AttachmentFormat: %s\r\n" 10140 "DeleteMessage: %s\r\n" 10141 "VolumeGain: %.2f\r\n" 10142 "CanReview: %s\r\n" 10143 "CallOperator: %s\r\n" 10144 "MaxMessageCount: %d\r\n" 10145 "MaxMessageLength: %d\r\n" 10146 "NewMessageCount: %d\r\n" 10147 #ifdef IMAP_STORAGE 10148 "OldMessageCount: %d\r\n" 10149 "IMAPUser: %s\r\n" 10150 #endif 10151 "\r\n", 10152 actionid, 10153 vmu->context, 10154 vmu->mailbox, 10155 vmu->fullname, 10156 vmu->email, 10157 vmu->pager, 10158 vmu->serveremail, 10159 vmu->mailcmd, 10160 vmu->language, 10161 vmu->zonetag, 10162 vmu->callback, 10163 vmu->dialout, 10164 vmu->uniqueid, 10165 vmu->exit, 10166 vmu->saydurationm, 10167 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 10168 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 10169 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 10170 vmu->attachfmt, 10171 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 10172 vmu->volgain, 10173 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 10174 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 10175 vmu->maxmsg, 10176 vmu->maxsecs, 10177 #ifdef IMAP_STORAGE 10178 new, old, vmu->imapuser 10179 #else 10180 count_messages(vmu, dirname) 10181 #endif 10182 ); 10183 } 10184 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 10185 10186 AST_LIST_UNLOCK(&users); 10187 10188 return RESULT_SUCCESS; 10189 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 9926 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().
09927 { 09928 while (poll_thread_run) { 09929 struct timespec ts = { 0, }; 09930 struct timeval wait; 09931 09932 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 09933 ts.tv_sec = wait.tv_sec; 09934 ts.tv_nsec = wait.tv_usec * 1000; 09935 09936 ast_mutex_lock(&poll_lock); 09937 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 09938 ast_mutex_unlock(&poll_lock); 09939 09940 if (!poll_thread_run) 09941 break; 09942 09943 poll_subscribed_mailboxes(); 09944 } 09945 09946 return NULL; 09947 }
static const char* mbox | ( | int | id | ) | [static] |
Definition at line 1301 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().
01302 { 01303 static const char *msgs[] = { 01304 #ifdef IMAP_STORAGE 01305 imapfolder, 01306 #else 01307 "INBOX", 01308 #endif 01309 "Old", 01310 "Work", 01311 "Family", 01312 "Friends", 01313 "Cust1", 01314 "Cust2", 01315 "Cust3", 01316 "Cust4", 01317 "Cust5", 01318 "Deleted", 01319 "Urgent" 01320 }; 01321 return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown"; 01322 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 4669 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
04670 { 04671 return __has_voicemail(context, mailbox, folder, 0); 04672 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 9949 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
09950 { 09951 ast_free(mwi_sub); 09952 }
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 10026 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().
10027 { 10028 struct mwi_sub_task *mwist; 10029 10030 if (ast_event_get_type(event) != AST_EVENT_SUB) 10031 return; 10032 10033 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10034 return; 10035 10036 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 10037 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 10038 return; 10039 } 10040 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 10041 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 10042 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10043 10044 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 10045 ast_free(mwist); 10046 } 10047 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 10010 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().
10011 { 10012 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 10013 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 10014 return; 10015 10016 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10017 return; 10018 10019 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10020 *uniqueid = u; 10021 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 10022 ast_free(uniqueid); 10023 } 10024 }
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 6174 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, globalflags, 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.
06175 { 06176 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06177 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06178 const char *category; 06179 char *myserveremail = serveremail; 06180 06181 ast_channel_lock(chan); 06182 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06183 category = ast_strdupa(category); 06184 } 06185 ast_channel_unlock(chan); 06186 06187 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); 06188 make_file(fn, sizeof(fn), todir, msgnum); 06189 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06190 06191 if (!ast_strlen_zero(vmu->attachfmt)) { 06192 if (strstr(fmt, vmu->attachfmt)) 06193 fmt = vmu->attachfmt; 06194 else 06195 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); 06196 } 06197 06198 /* Attach only the first format */ 06199 fmt = ast_strdupa(fmt); 06200 stringp = fmt; 06201 strsep(&stringp, "|"); 06202 06203 if (!ast_strlen_zero(vmu->serveremail)) 06204 myserveremail = vmu->serveremail; 06205 06206 if (!ast_strlen_zero(vmu->email)) { 06207 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 06208 if (!attach_user_voicemail) 06209 attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH); 06210 06211 if (attach_user_voicemail) 06212 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 06213 06214 /* XXX possible imap issue, should category be NULL XXX */ 06215 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 06216 06217 if (attach_user_voicemail) 06218 DISPOSE(todir, msgnum); 06219 } 06220 06221 if (!ast_strlen_zero(vmu->pager)) { 06222 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category, flag); 06223 } 06224 06225 if (ast_test_flag(vmu, VM_DELETE)) 06226 DELETE(todir, msgnum, fn, vmu); 06227 06228 /* Leave voicemail for someone */ 06229 if (ast_app_has_voicemail(ext_context, NULL)) 06230 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 06231 06232 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 06233 06234 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); 06235 run_externnotify(vmu->context, vmu->mailbox, flag); 06236 06237 #ifdef IMAP_STORAGE 06238 vm_delete(fn); /* Delete the file, but not the IMAP message */ 06239 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 06240 vm_imap_delete(vms->curmsg, vmu); 06241 vms->newmessages--; /* Fix new message count */ 06242 } 06243 #endif 06244 06245 return 0; 06246 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 3635 of file app_voicemail.c.
References BASELINELEN, eol, and baseio::linelength.
Referenced by base_encode().
03636 { 03637 if (bio->linelength >= BASELINELEN) { 03638 if (fputs(eol,so) == EOF) 03639 return -1; 03640 03641 bio->linelength= 0; 03642 } 03643 03644 if (putc(((unsigned char)c),so) == EOF) 03645 return -1; 03646 03647 bio->linelength++; 03648 03649 return 1; 03650 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 6930 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().
06931 { 06932 int count_msg, last_msg; 06933 06934 ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox)); 06935 06936 /* Rename the member vmbox HERE so that we don't try to return before 06937 * we know what's going on. 06938 */ 06939 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 06940 06941 /* Faster to make the directory than to check if it exists. */ 06942 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 06943 06944 count_msg = count_messages(vmu, vms->curdir); 06945 if (count_msg < 0) 06946 return count_msg; 06947 else 06948 vms->lastmsg = count_msg - 1; 06949 06950 /* 06951 The following test is needed in case sequencing gets messed up. 06952 There appears to be more than one way to mess up sequence, so 06953 we will not try to find all of the root causes--just fix it when 06954 detected. 06955 */ 06956 06957 if (vm_lock_path(vms->curdir)) { 06958 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 06959 return -1; 06960 } 06961 06962 last_msg = last_message_index(vmu, vms->curdir); 06963 ast_unlock_path(vms->curdir); 06964 06965 if (last_msg < 0) 06966 return last_msg; 06967 06968 return 0; 06969 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 6728 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_tw(), and vm_execmain().
06729 { 06730 int res = 0; 06731 char filename[256], *cid; 06732 const char *origtime, *context, *category, *duration, *flag; 06733 struct ast_config *msg_cfg; 06734 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06735 06736 vms->starting = 0; 06737 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06738 adsi_message(chan, vms); 06739 if (!vms->curmsg) 06740 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 06741 else if (vms->curmsg == vms->lastmsg) 06742 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 06743 06744 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 06745 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 06746 msg_cfg = ast_config_load(filename, config_flags); 06747 if (!msg_cfg) { 06748 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 06749 return 0; 06750 } 06751 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 06752 06753 /* Play the word urgent if we are listening to urgent messages */ 06754 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 06755 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 06756 } 06757 06758 if (!res) { 06759 /* POLISH syntax */ 06760 if (!strcasecmp(chan->language, "pl")) { 06761 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 06762 int ten, one; 06763 char nextmsg[256]; 06764 ten = (vms->curmsg + 1) / 10; 06765 one = (vms->curmsg + 1) % 10; 06766 06767 if (vms->curmsg < 20) { 06768 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 06769 res = wait_file2(chan, vms, nextmsg); 06770 } else { 06771 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 06772 res = wait_file2(chan, vms, nextmsg); 06773 if (one > 0) { 06774 if (!res) { 06775 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 06776 res = wait_file2(chan, vms, nextmsg); 06777 } 06778 } 06779 } 06780 } 06781 if (!res) 06782 res = wait_file2(chan, vms, "vm-message"); 06783 /* HEBREW syntax */ 06784 } else if (!strcasecmp(chan->language, "he")) { 06785 if (!vms->curmsg) { 06786 res = wait_file2(chan, vms, "vm-message"); 06787 res = wait_file2(chan, vms, "vm-first"); 06788 } else if (vms->curmsg == vms->lastmsg) { 06789 res = wait_file2(chan, vms, "vm-message"); 06790 res = wait_file2(chan, vms, "vm-last"); 06791 } else { 06792 res = wait_file2(chan, vms, "vm-message"); 06793 res = wait_file2(chan, vms, "vm-number"); 06794 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 06795 } 06796 } else { 06797 if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */ 06798 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 06799 else /* DEFAULT syntax */ { 06800 res = wait_file2(chan, vms, "vm-message"); 06801 } 06802 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 06803 if (!res) { 06804 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 06805 } 06806 } 06807 } 06808 } 06809 06810 if (!msg_cfg) { 06811 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 06812 return 0; 06813 } 06814 06815 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 06816 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 06817 DISPOSE(vms->curdir, vms->curmsg); 06818 ast_config_destroy(msg_cfg); 06819 return 0; 06820 } 06821 06822 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 06823 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 06824 category = ast_variable_retrieve(msg_cfg, "message", "category"); 06825 06826 context = ast_variable_retrieve(msg_cfg, "message", "context"); 06827 if (!strncasecmp("macro",context,5)) /* Macro names in contexts are useless for our needs */ 06828 context = ast_variable_retrieve(msg_cfg, "message","macrocontext"); 06829 if (!res) { 06830 res = play_message_category(chan, category); 06831 } 06832 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 06833 res = play_message_datetime(chan, vmu, origtime, filename); 06834 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 06835 res = play_message_callerid(chan, vms, cid, context, 0); 06836 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 06837 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 06838 /* Allow pressing '1' to skip envelope / callerid */ 06839 if (res == '1') 06840 res = 0; 06841 ast_config_destroy(msg_cfg); 06842 06843 if (!res) { 06844 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06845 vms->heard[vms->curmsg] = 1; 06846 #ifdef IMAP_STORAGE 06847 /*IMAP storage stores any prepended message from a forward 06848 * as a separate file from the rest of the message 06849 */ 06850 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 06851 wait_file(chan, vms, vms->introfn); 06852 } 06853 #endif 06854 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 06855 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 06856 res = 0; 06857 } 06858 } 06859 DISPOSE(vms->curdir, vms->curmsg); 06860 return res; 06861 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 6614 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().
06615 { 06616 int res = 0; 06617 int i; 06618 char *callerid, *name; 06619 char prefile[PATH_MAX] = ""; 06620 06621 06622 /* If voicemail cid is not enabled, or we didn't get cid or context from 06623 * the attribute file, leave now. 06624 * 06625 * TODO Still need to change this so that if this function is called by the 06626 * message envelope (and someone is explicitly requesting to hear the CID), 06627 * it does not check to see if CID is enabled in the config file. 06628 */ 06629 if ((cid == NULL)||(context == NULL)) 06630 return res; 06631 06632 /* Strip off caller ID number from name */ 06633 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 06634 ast_callerid_parse(cid, &name, &callerid); 06635 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 06636 /* Check for internal contexts and only */ 06637 /* say extension when the call didn't come from an internal context in the list */ 06638 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 06639 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 06640 if ((strcmp(cidinternalcontexts[i], context) == 0)) 06641 break; 06642 } 06643 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 06644 if (!res) { 06645 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 06646 if (!ast_strlen_zero(prefile)) { 06647 /* See if we can find a recorded name for this person instead of their extension number */ 06648 if (ast_fileexists(prefile, NULL, NULL) > 0) { 06649 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 06650 if (!callback) 06651 res = wait_file2(chan, vms, "vm-from"); 06652 res = ast_stream_and_wait(chan, prefile, ""); 06653 } else { 06654 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 06655 /* Say "from extension" as one saying to sound smoother */ 06656 if (!callback) 06657 res = wait_file2(chan, vms, "vm-from-extension"); 06658 res = ast_say_digit_str(chan, callerid, "", chan->language); 06659 } 06660 } 06661 } 06662 } else if (!res) { 06663 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 06664 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 06665 if (!callback) 06666 res = wait_file2(chan, vms, "vm-from-phonenumber"); 06667 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 06668 } 06669 } else { 06670 /* Number unknown */ 06671 ast_debug(1, "VM-CID: From an unknown number\n"); 06672 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 06673 res = wait_file2(chan, vms, "vm-unknown-caller"); 06674 } 06675 return res; 06676 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 6526 of file app_voicemail.c.
References ast_log(), ast_play_and_wait(), ast_strlen_zero(), and chan.
Referenced by play_message().
06527 { 06528 int res = 0; 06529 06530 if (!ast_strlen_zero(category)) 06531 res = ast_play_and_wait(chan, category); 06532 06533 if (res) { 06534 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 06535 res = 0; 06536 } 06537 06538 return res; 06539 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 6541 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().
06542 { 06543 int res = 0; 06544 struct vm_zone *the_zone = NULL; 06545 time_t t; 06546 06547 if (ast_get_time_t(origtime, &t, 0, NULL)) { 06548 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 06549 return 0; 06550 } 06551 06552 /* Does this user have a timezone specified? */ 06553 if (!ast_strlen_zero(vmu->zonetag)) { 06554 /* Find the zone in the list */ 06555 struct vm_zone *z; 06556 AST_LIST_LOCK(&zones); 06557 AST_LIST_TRAVERSE(&zones, z, list) { 06558 if (!strcmp(z->name, vmu->zonetag)) { 06559 the_zone = z; 06560 break; 06561 } 06562 } 06563 AST_LIST_UNLOCK(&zones); 06564 } 06565 06566 /* No internal variable parsing for now, so we'll comment it out for the time being */ 06567 #if 0 06568 /* Set the DIFF_* variables */ 06569 ast_localtime(&t, &time_now, NULL); 06570 tv_now = ast_tvnow(); 06571 ast_localtime(&tv_now, &time_then, NULL); 06572 06573 /* Day difference */ 06574 if (time_now.tm_year == time_then.tm_year) 06575 snprintf(temp,sizeof(temp),"%d",time_now.tm_yday); 06576 else 06577 snprintf(temp,sizeof(temp),"%d",(time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 06578 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 06579 06580 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 06581 #endif 06582 if (the_zone) { 06583 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 06584 } 06585 else if (!strcasecmp(chan->language,"pl")) /* POLISH syntax */ 06586 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 06587 else if (!strcasecmp(chan->language,"se")) /* SWEDISH syntax */ 06588 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 06589 else if (!strcasecmp(chan->language,"no")) /* NORWEGIAN syntax */ 06590 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 06591 else if (!strcasecmp(chan->language,"de")) /* GERMAN syntax */ 06592 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 06593 else if (!strcasecmp(chan->language,"nl")) /* DUTCH syntax */ 06594 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 06595 else if (!strcasecmp(chan->language,"it")) /* ITALIAN syntax */ 06596 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); 06597 else if (!strcasecmp(chan->language,"gr")) 06598 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 06599 else if (!strcasecmp(chan->language,"pt_BR")) 06600 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); 06601 else if (!strcasecmp(chan->language,"tw")) /* CHINESE (Taiwan) syntax */ 06602 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 06603 else { 06604 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 06605 } 06606 #if 0 06607 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 06608 #endif 06609 return res; 06610 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 6678 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().
06679 { 06680 int res = 0; 06681 int durationm; 06682 int durations; 06683 /* Verify that we have a duration for the message */ 06684 if (duration == NULL) 06685 return res; 06686 06687 /* Convert from seconds to minutes */ 06688 durations=atoi(duration); 06689 durationm=(durations / 60); 06690 06691 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 06692 06693 if ((!res) && (durationm >= minduration)) { 06694 res = wait_file2(chan, vms, "vm-duration"); 06695 06696 /* POLISH syntax */ 06697 if (!strcasecmp(chan->language, "pl")) { 06698 div_t num = div(durationm, 10); 06699 06700 if (durationm == 1) { 06701 res = ast_play_and_wait(chan, "digits/1z"); 06702 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 06703 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 06704 if (num.rem == 2) { 06705 if (!num.quot) { 06706 res = ast_play_and_wait(chan, "digits/2-ie"); 06707 } else { 06708 res = say_and_wait(chan, durationm - 2 , chan->language); 06709 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 06710 } 06711 } else { 06712 res = say_and_wait(chan, durationm, chan->language); 06713 } 06714 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 06715 } else { 06716 res = say_and_wait(chan, durationm, chan->language); 06717 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 06718 } 06719 /* DEFAULT syntax */ 06720 } else { 06721 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 06722 res = wait_file2(chan, vms, "vm-minutes"); 06723 } 06724 } 06725 return res; 06726 }
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 11225 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.
11228 { 11229 /* Record message & let caller review or re-record it, or set options if applicable */ 11230 int res = 0; 11231 int cmd = 0; 11232 int max_attempts = 3; 11233 int attempts = 0; 11234 int recorded = 0; 11235 int msg_exists = 0; 11236 signed char zero_gain = 0; 11237 char tempfile[PATH_MAX]; 11238 char *acceptdtmf = "#"; 11239 char *canceldtmf = ""; 11240 11241 /* Note that urgent and private are for flagging messages as such in the future */ 11242 11243 /* barf if no pointer passed to store duration in */ 11244 if (duration == NULL) { 11245 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 11246 return -1; 11247 } 11248 11249 if (!outsidecaller) 11250 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 11251 else 11252 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 11253 11254 cmd = '3'; /* Want to start by recording */ 11255 11256 while ((cmd >= 0) && (cmd != 't')) { 11257 switch (cmd) { 11258 case '1': 11259 if (!msg_exists) { 11260 /* In this case, 1 is to record a message */ 11261 cmd = '3'; 11262 break; 11263 } else { 11264 /* Otherwise 1 is to save the existing message */ 11265 ast_verb(3, "Saving message as is\n"); 11266 if (!outsidecaller) 11267 ast_filerename(tempfile, recordfile, NULL); 11268 ast_stream_and_wait(chan, "vm-msgsaved", ""); 11269 if (!outsidecaller) { 11270 /* Saves to IMAP server - but SHOULD save to filesystem ONLY if recording greetings! */ 11271 #ifndef IMAP_STORAGE 11272 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 11273 DISPOSE(recordfile, -1); 11274 #endif 11275 } 11276 cmd = 't'; 11277 return res; 11278 } 11279 case '2': 11280 /* Review */ 11281 ast_verb(3, "Reviewing the message\n"); 11282 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 11283 break; 11284 case '3': 11285 msg_exists = 0; 11286 /* Record */ 11287 if (recorded == 1) 11288 ast_verb(3, "Re-recording the message\n"); 11289 else 11290 ast_verb(3, "Recording the message\n"); 11291 11292 if (recorded && outsidecaller) { 11293 cmd = ast_play_and_wait(chan, INTRO); 11294 cmd = ast_play_and_wait(chan, "beep"); 11295 } 11296 recorded = 1; 11297 /* 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 */ 11298 if (record_gain) 11299 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 11300 if (ast_test_flag(vmu, VM_OPERATOR)) 11301 canceldtmf = "0"; 11302 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 11303 if (record_gain) 11304 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 11305 if (cmd == -1) { 11306 /* User has hung up, no options to give */ 11307 if (!outsidecaller) { 11308 /* user was recording a greeting and they hung up, so let's delete the recording. */ 11309 ast_filedelete(tempfile, NULL); 11310 } 11311 return cmd; 11312 } 11313 if (cmd == '0') { 11314 break; 11315 } else if (cmd == '*') { 11316 break; 11317 #if 0 11318 } else if (vmu->review && (*duration < 5)) { 11319 /* Message is too short */ 11320 ast_verb(3, "Message too short\n"); 11321 cmd = ast_play_and_wait(chan, "vm-tooshort"); 11322 cmd = ast_filedelete(tempfile, NULL); 11323 break; 11324 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 11325 /* Message is all silence */ 11326 ast_verb(3, "Nothing recorded\n"); 11327 cmd = ast_filedelete(tempfile, NULL); 11328 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 11329 if (!cmd) 11330 cmd = ast_play_and_wait(chan, "vm-speakup"); 11331 break; 11332 #endif 11333 } else { 11334 /* If all is well, a message exists */ 11335 msg_exists = 1; 11336 cmd = 0; 11337 } 11338 break; 11339 case '4': 11340 if (outsidecaller) { /* only mark vm messages */ 11341 /* Mark Urgent */ 11342 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 11343 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 11344 ast_debug(1000, "This message is too urgent!\n"); 11345 res = ast_play_and_wait(chan, "vm-marked-urgent"); 11346 strcpy(flag, "Urgent"); 11347 } else if (flag) { 11348 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 11349 res = ast_play_and_wait(chan, "vm-urgent-removed"); 11350 strcpy(flag, ""); 11351 } else { 11352 ast_play_and_wait(chan, "vm-sorry"); 11353 } 11354 cmd = 0; 11355 } else { 11356 cmd = ast_play_and_wait(chan, "vm-sorry"); 11357 } 11358 break; 11359 case '5': 11360 case '6': 11361 case '7': 11362 case '8': 11363 case '9': 11364 case '*': 11365 case '#': 11366 cmd = ast_play_and_wait(chan, "vm-sorry"); 11367 break; 11368 #if 0 11369 /* XXX Commented out for the moment because of the dangers of deleting 11370 a message while recording (can put the message numbers out of sync) */ 11371 case '*': 11372 /* Cancel recording, delete message, offer to take another message*/ 11373 cmd = ast_play_and_wait(chan, "vm-deleted"); 11374 cmd = ast_filedelete(tempfile, NULL); 11375 if (outsidecaller) { 11376 res = vm_exec(chan, NULL); 11377 return res; 11378 } 11379 else 11380 return 1; 11381 #endif 11382 case '0': 11383 if (!ast_test_flag(vmu, VM_OPERATOR)) { 11384 cmd = ast_play_and_wait(chan, "vm-sorry"); 11385 break; 11386 } 11387 if (msg_exists || recorded) { 11388 cmd = ast_play_and_wait(chan, "vm-saveoper"); 11389 if (!cmd) 11390 cmd = ast_waitfordigit(chan, 3000); 11391 if (cmd == '1') { 11392 ast_play_and_wait(chan, "vm-msgsaved"); 11393 cmd = '0'; 11394 } else if (cmd == '4') { 11395 if (flag) { 11396 ast_play_and_wait(chan, "vm-marked-urgent"); 11397 strcpy(flag, "Urgent"); 11398 } 11399 ast_play_and_wait(chan, "vm-msgsaved"); 11400 cmd = '0'; 11401 } else { 11402 ast_play_and_wait(chan, "vm-deleted"); 11403 DELETE(recordfile, -1, recordfile, vmu); 11404 cmd = '0'; 11405 } 11406 } 11407 return cmd; 11408 default: 11409 /* If the caller is an ouside caller, and the review option is enabled, 11410 allow them to review the message, but let the owner of the box review 11411 their OGM's */ 11412 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 11413 return cmd; 11414 if (msg_exists) { 11415 cmd = ast_play_and_wait(chan, "vm-review"); 11416 if (!cmd && outsidecaller) { 11417 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 11418 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 11419 } else if (flag) { 11420 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 11421 } 11422 } 11423 } else { 11424 cmd = ast_play_and_wait(chan, "vm-torerecord"); 11425 if (!cmd) 11426 cmd = ast_waitfordigit(chan, 600); 11427 } 11428 11429 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 11430 cmd = ast_play_and_wait(chan, "vm-reachoper"); 11431 if (!cmd) 11432 cmd = ast_waitfordigit(chan, 600); 11433 } 11434 #if 0 11435 if (!cmd) 11436 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 11437 #endif 11438 if (!cmd) 11439 cmd = ast_waitfordigit(chan, 6000); 11440 if (!cmd) { 11441 attempts++; 11442 } 11443 if (attempts > max_attempts) { 11444 cmd = 't'; 11445 } 11446 } 11447 } 11448 if (outsidecaller) 11449 ast_play_and_wait(chan, "vm-goodbye"); 11450 if (cmd == 't') 11451 cmd = 0; 11452 return cmd; 11453 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 9903 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, inboxcount2(), mwi_sub::mailbox, mwi_sub::old_new, mwi_sub::old_old, mwi_sub::old_urgent, and queue_mwi_event().
Referenced by mb_poll_thread().
09904 { 09905 struct mwi_sub *mwi_sub; 09906 09907 AST_RWLIST_RDLOCK(&mwi_subs); 09908 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 09909 int new = 0, old = 0, urgent = 0; 09910 09911 if (ast_strlen_zero(mwi_sub->mailbox)) 09912 continue; 09913 09914 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 09915 09916 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 09917 mwi_sub->old_urgent = urgent; 09918 mwi_sub->old_new = new; 09919 mwi_sub->old_old = old; 09920 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 09921 } 09922 } 09923 AST_RWLIST_UNLOCK(&mwi_subs); 09924 }
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 731 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.
00732 { 00733 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00734 if (saydurationminfo) 00735 vmu->saydurationm = saydurationminfo; 00736 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 00737 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 00738 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 00739 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 00740 if (vmmaxsecs) 00741 vmu->maxsecs = vmmaxsecs; 00742 if (maxmsg) 00743 vmu->maxmsg = maxmsg; 00744 if (maxdeletedmsg) 00745 vmu->maxdeletedmsg = maxdeletedmsg; 00746 vmu->volgain = volgain; 00747 }
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 3720 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().
03721 { 03722 char callerid[256]; 03723 char fromdir[256], fromfile[256]; 03724 struct ast_config *msg_cfg; 03725 const char *origcallerid, *origtime; 03726 char origcidname[80], origcidnum[80], origdate[80]; 03727 int inttime; 03728 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 03729 03730 /* Prepare variables for substitution in email body and subject */ 03731 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 03732 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 03733 snprintf(passdata, passdatasize, "%d", msgnum); 03734 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata); 03735 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 03736 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 03737 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 03738 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 03739 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 03740 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 03741 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 03742 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 03743 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 03744 03745 /* Retrieve info from VM attribute file */ 03746 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 03747 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 03748 if (strlen(fromfile) < sizeof(fromfile) - 5) { 03749 strcat(fromfile, ".txt"); 03750 } 03751 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 03752 if (option_debug > 0) { 03753 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 03754 } 03755 return; 03756 } 03757 03758 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 03759 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 03760 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 03761 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 03762 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 03763 } 03764 03765 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%d", &inttime) == 1) { 03766 struct timeval tv = { inttime, }; 03767 struct ast_tm tm; 03768 ast_localtime(&tv, &tm, NULL); 03769 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 03770 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 03771 } 03772 ast_config_destroy(msg_cfg); 03773 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6138 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_mailboxes(), and vm_execmain().
06139 { 06140 struct ast_event *event; 06141 char *mailbox, *context; 06142 06143 /* Strip off @default */ 06144 context = mailbox = ast_strdupa(box); 06145 strsep(&context, "@"); 06146 if (ast_strlen_zero(context)) 06147 context = "default"; 06148 06149 if (!(event = ast_event_new(AST_EVENT_MWI, 06150 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06151 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06152 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06153 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06154 AST_EVENT_IE_END))) { 06155 return; 06156 } 06157 06158 ast_event_queue_and_cache(event); 06159 }
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 3782 of file app_voicemail.c.
03783 { 03784 char *ptr = to; 03785 *ptr++ = '"'; 03786 for (; ptr < to + len - 1; from++) { 03787 if (*from == '"') 03788 *ptr++ = '\\'; 03789 else if (*from == '\0') 03790 break; 03791 *ptr++ = *from; 03792 } 03793 if (ptr < to + len - 1) 03794 *ptr++ = '"'; 03795 *ptr = '\0'; 03796 return to; 03797 }
static int reload | ( | void | ) | [static] |
Definition at line 10901 of file app_voicemail.c.
References load_config().
10902 { 10903 return load_config(1); 10904 }
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 3403 of file app_voicemail.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03404 { 03405 char stxt[PATH_MAX]; 03406 char dtxt[PATH_MAX]; 03407 ast_filerename(sfn,dfn,NULL); 03408 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03409 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03410 if (ast_check_realtime("voicemail_data")) { 03411 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 03412 } 03413 rename(stxt, dtxt); 03414 }
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 1127 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().
01128 { 01129 /* This function could be made to generate one from a database, too */ 01130 struct ast_vm_user *cur; 01131 int res = -1; 01132 AST_LIST_LOCK(&users); 01133 AST_LIST_TRAVERSE(&users, cur, list) { 01134 if ((!context || !strcasecmp(context, cur->context)) && 01135 (!strcasecmp(mailbox, cur->mailbox))) 01136 break; 01137 } 01138 if (cur) { 01139 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01140 res = 0; 01141 } 01142 AST_LIST_UNLOCK(&users); 01143 return res; 01144 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 4805 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.
04806 { 04807 char arguments[255]; 04808 char ext_context[256] = ""; 04809 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 04810 struct ast_smdi_mwi_message *mwi_msg; 04811 04812 if (!ast_strlen_zero(context)) 04813 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 04814 else 04815 ast_copy_string(ext_context, extension, sizeof(ext_context)); 04816 04817 if (smdi_iface) { 04818 if (ast_app_has_voicemail(ext_context, NULL)) 04819 ast_smdi_mwi_set(smdi_iface, extension); 04820 else 04821 ast_smdi_mwi_unset(smdi_iface, extension); 04822 04823 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 04824 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 04825 if (!strncmp(mwi_msg->cause, "INV", 3)) 04826 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 04827 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 04828 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 04829 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 04830 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 04831 } else { 04832 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 04833 } 04834 } 04835 04836 if (!ast_strlen_zero(externnotify)) { 04837 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 04838 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 04839 } else { 04840 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 04841 ast_debug(1, "Executing %s\n", arguments); 04842 ast_safe_system(arguments); 04843 } 04844 } 04845 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 5367 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().
05368 { 05369 #ifdef IMAP_STORAGE 05370 /* we must use mbox(x) folder names, and copy the message there */ 05371 /* simple. huh? */ 05372 char sequence[10]; 05373 char mailbox[256]; 05374 int res; 05375 05376 /* get the real IMAP message number for this message */ 05377 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 05378 05379 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(box)); 05380 ast_mutex_lock(&vms->lock); 05381 /* if save to Old folder, put in INBOX as read */ 05382 if (box == OLD_FOLDER) { 05383 mail_setflag(vms->mailstream, sequence, "\\Seen"); 05384 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 05385 } else if (box == NEW_FOLDER) { 05386 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 05387 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 05388 } 05389 if (!strcasecmp(mbox(NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 05390 ast_mutex_unlock(&vms->lock); 05391 return 0; 05392 } 05393 /* Create the folder if it don't exist */ 05394 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 05395 ast_debug(5, "Checking if folder exists: %s\n",mailbox); 05396 if (mail_create(vms->mailstream, mailbox) == NIL) 05397 ast_debug(5, "Folder exists.\n"); 05398 else 05399 ast_log(AST_LOG_NOTICE, "Folder %s created!\n",mbox(box)); 05400 res = !mail_copy(vms->mailstream, sequence, (char *)mbox(box)); 05401 ast_mutex_unlock(&vms->lock); 05402 return res; 05403 #else 05404 char *dir = vms->curdir; 05405 char *username = vms->username; 05406 char *context = vmu->context; 05407 char sfn[PATH_MAX]; 05408 char dfn[PATH_MAX]; 05409 char ddir[PATH_MAX]; 05410 const char *dbox = mbox(box); 05411 int x, i; 05412 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 05413 05414 if (vm_lock_path(ddir)) 05415 return ERROR_LOCK_PATH; 05416 05417 x = last_message_index(vmu, ddir) + 1; 05418 05419 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 05420 x--; 05421 for (i = 1; i <= x; i++) { 05422 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 05423 make_file(sfn, sizeof(sfn), ddir, i); 05424 make_file(dfn, sizeof(dfn), ddir, i - 1); 05425 if (EXISTS(ddir, i, sfn, NULL)) { 05426 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 05427 } else 05428 break; 05429 } 05430 } else { 05431 if (x >= vmu->maxmsg) { 05432 ast_unlock_path(ddir); 05433 return -1; 05434 } 05435 } 05436 make_file(sfn, sizeof(sfn), dir, msg); 05437 make_file(dfn, sizeof(dfn), ddir, x); 05438 if (strcmp(sfn, dfn)) { 05439 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 05440 } 05441 ast_unlock_path(ddir); 05442 #endif 05443 return 0; 05444 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 5360 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_say_number(), and chan.
Referenced by play_message_duration(), vm_execmain(), vm_intro_cz(), 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_tw().
05361 { 05362 int d; 05363 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 05364 return d; 05365 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 10887 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().
10888 { 10889 int res = -1; 10890 char dir[PATH_MAX]; 10891 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 10892 ast_debug(2, "About to try retrieving name file %s\n", dir); 10893 RETRIEVE(dir, -1, mailbox, context); 10894 if (ast_fileexists(dir, NULL, NULL)) { 10895 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 10896 } 10897 DISPOSE(dir, -1); 10898 return res; 10899 }
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 4226 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().
04227 { 04228 FILE *p=NULL; 04229 char tmp[80] = "/tmp/astmail-XXXXXX"; 04230 char tmp2[256]; 04231 04232 if (vmu && ast_strlen_zero(vmu->email)) { 04233 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04234 return(0); 04235 } 04236 if (!strcmp(format, "wav49")) 04237 format = "WAV"; 04238 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)); 04239 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04240 command hangs */ 04241 if ((p = vm_mkftemp(tmp)) == NULL) { 04242 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04243 return -1; 04244 } else { 04245 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04246 fclose(p); 04247 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04248 ast_safe_system(tmp2); 04249 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04250 } 04251 return 0; 04252 }
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 4254 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().
04255 { 04256 char date[256]; 04257 char host[MAXHOSTNAMELEN] = ""; 04258 char who[256]; 04259 char dur[PATH_MAX]; 04260 char tmp[80] = "/tmp/astmail-XXXXXX"; 04261 char tmp2[PATH_MAX]; 04262 struct ast_tm tm; 04263 FILE *p; 04264 04265 if ((p = vm_mkftemp(tmp)) == NULL) { 04266 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04267 return -1; 04268 } 04269 gethostname(host, sizeof(host)-1); 04270 if (strchr(srcemail, '@')) 04271 ast_copy_string(who, srcemail, sizeof(who)); 04272 else 04273 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04274 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04275 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04276 fprintf(p, "Date: %s\n", date); 04277 04278 if (*pagerfromstring) { 04279 struct ast_channel *ast; 04280 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04281 char *passdata; 04282 int vmlen = strlen(fromstring)*3 + 200; 04283 passdata = alloca(vmlen); 04284 memset(passdata, 0, vmlen); 04285 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04286 pbx_substitute_variables_helper(ast, pagerfromstring, passdata, vmlen); 04287 fprintf(p, "From: %s <%s>\n", passdata, who); 04288 ast_channel_free(ast); 04289 } else 04290 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04291 } else 04292 fprintf(p, "From: Asterisk PBX <%s>\n", who); 04293 fprintf(p, "To: %s\n", pager); 04294 if (pagersubject) { 04295 struct ast_channel *ast; 04296 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04297 char *passdata; 04298 int vmlen = strlen(pagersubject) * 3 + 200; 04299 passdata = alloca(vmlen); 04300 memset(passdata, 0, vmlen); 04301 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04302 pbx_substitute_variables_helper(ast, pagersubject, passdata, vmlen); 04303 fprintf(p, "Subject: %s\n\n", passdata); 04304 ast_channel_free(ast); 04305 } else 04306 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04307 } else { 04308 if (ast_strlen_zero(flag)) { 04309 fprintf(p, "Subject: New VM\n\n"); 04310 } else { 04311 fprintf(p, "Subject: New %s VM\n\n", flag); 04312 } 04313 } 04314 04315 ast_strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); 04316 if (pagerbody) { 04317 struct ast_channel *ast; 04318 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 04319 char *passdata; 04320 int vmlen = strlen(pagerbody) * 3 + 200; 04321 passdata = alloca(vmlen); 04322 memset(passdata, 0, vmlen); 04323 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category, flag); 04324 pbx_substitute_variables_helper(ast, pagerbody, passdata, vmlen); 04325 fprintf(p, "%s\n", passdata); 04326 ast_channel_free(ast); 04327 } else 04328 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04329 } else { 04330 fprintf(p, "New %s long %s msg in box %s\n" 04331 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04332 } 04333 fclose(p); 04334 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04335 ast_safe_system(tmp2); 04336 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04337 return 0; 04338 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 9701 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().
09702 { 09703 struct ast_config *cfg; 09704 const char *cat = NULL; 09705 09706 if (!(cfg = ast_load_realtime_multientry("voicemail", 09707 "context", context, SENTINEL))) { 09708 return CLI_FAILURE; 09709 } 09710 09711 ast_cli(fd, 09712 "\n" 09713 "=============================================================\n" 09714 "=== Configured Voicemail Users ==============================\n" 09715 "=============================================================\n" 09716 "===\n"); 09717 09718 while ((cat = ast_category_browse(cfg, cat))) { 09719 struct ast_variable *var = NULL; 09720 ast_cli(fd, 09721 "=== Mailbox ...\n" 09722 "===\n"); 09723 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 09724 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 09725 ast_cli(fd, 09726 "===\n" 09727 "=== ---------------------------------------------------------\n" 09728 "===\n"); 09729 } 09730 09731 ast_cli(fd, 09732 "=============================================================\n" 09733 "\n"); 09734 09735 ast_config_destroy(cfg); 09736 09737 return CLI_SUCCESS; 09738 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 10049 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().
10050 { 10051 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, NULL, 10052 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 10053 AST_EVENT_IE_END); 10054 10055 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, NULL, 10056 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 10057 AST_EVENT_IE_END); 10058 10059 if (mwi_sub_sub) 10060 ast_event_report_subs(mwi_sub_sub); 10061 10062 poll_thread_run = 1; 10063 10064 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 10065 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 10067 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().
10068 { 10069 poll_thread_run = 0; 10070 10071 if (mwi_sub_sub) { 10072 ast_event_unsubscribe(mwi_sub_sub); 10073 mwi_sub_sub = NULL; 10074 } 10075 10076 if (mwi_unsub_sub) { 10077 ast_event_unsubscribe(mwi_unsub_sub); 10078 mwi_unsub_sub = NULL; 10079 } 10080 10081 ast_mutex_lock(&poll_lock); 10082 ast_cond_signal(&poll_cond); 10083 ast_mutex_unlock(&poll_lock); 10084 10085 pthread_join(poll_thread, NULL); 10086 10087 poll_thread = AST_PTHREADT_NULL; 10088 }
static char* strip_control | ( | const char * | input, | |
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 702 of file app_voicemail.c.
Referenced by make_email_file().
00703 { 00704 char *bufptr = buf; 00705 for (; *input; input++) { 00706 if (*input < 32) { 00707 continue; 00708 } 00709 *bufptr++ = *input; 00710 if (bufptr == buf + buflen - 1) { 00711 break; 00712 } 00713 } 00714 *bufptr = '\0'; 00715 return buf; 00716 }
static char* substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 10213 of file app_voicemail.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_create(), and str.
Referenced by load_config().
10214 { 10215 char *current, *result; 10216 10217 /* Add 16 for fudge factor */ 10218 struct ast_str *str = ast_str_create(strlen(value) + 16); 10219 10220 /* Substitute strings \r, \n, and \t into the appropriate characters */ 10221 for (current = (char *) value; *current; current++) { 10222 if (*current == '\\') { 10223 current++; 10224 if (!*current) { 10225 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 10226 break; 10227 } 10228 switch (*current) { 10229 case 'r': 10230 ast_str_append(&str, 0, "\r"); 10231 break; 10232 case 'n': 10233 #ifdef IMAP_STORAGE 10234 if (!str->used || str->str[str->used - 1] != '\r') { 10235 ast_str_append(&str, 0, "\r"); 10236 } 10237 #endif 10238 ast_str_append(&str, 0, "\n"); 10239 break; 10240 case 't': 10241 ast_str_append(&str, 0, "\t"); 10242 break; 10243 default: 10244 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 10245 break; 10246 } 10247 } else { 10248 ast_str_append(&str, 0, "%c", *current); 10249 } 10250 } 10251 10252 result = ast_strdup(str->str); 10253 ast_free(str); 10254 10255 return result; 10256 }
static int unload_module | ( | void | ) | [static] |
Definition at line 10906 of file app_voicemail.c.
References 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(), mailbox_exists_acf, mwi_subscription_tps, and stop_poll_thread().
10907 { 10908 int res; 10909 10910 res = ast_unregister_application(app); 10911 res |= ast_unregister_application(app2); 10912 res |= ast_unregister_application(app3); 10913 res |= ast_unregister_application(app4); 10914 res |= ast_custom_function_unregister(&mailbox_exists_acf); 10915 res |= ast_manager_unregister("VoicemailUsersList"); 10916 ast_cli_unregister_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 10917 ast_uninstall_vm_functions(); 10918 10919 if (poll_thread != AST_PTHREADT_NULL) 10920 stop_poll_thread(); 10921 10922 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 10923 ast_unload_realtime("voicemail"); 10924 ast_unload_realtime("voicemail_data"); 10925 10926 free_vm_users(); 10927 free_vm_zones(); 10928 return res; 10929 }
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 8659 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().
08662 { 08663 int useadsi=0, valid=0, logretries=0; 08664 char password[AST_MAX_EXTENSION]="", *passptr; 08665 struct ast_vm_user vmus, *vmu = NULL; 08666 08667 /* If ADSI is supported, setup login screen */ 08668 adsi_begin(chan, &useadsi); 08669 if (!skipuser && useadsi) 08670 adsi_login(chan); 08671 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 08672 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 08673 return -1; 08674 } 08675 08676 /* Authenticate them and get their mailbox/password */ 08677 08678 while (!valid && (logretries < max_logins)) { 08679 /* Prompt for, and read in the username */ 08680 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 08681 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 08682 return -1; 08683 } 08684 if (ast_strlen_zero(mailbox)) { 08685 if (chan->cid.cid_num) { 08686 ast_copy_string(mailbox, chan->cid.cid_num, mailbox_size); 08687 } else { 08688 ast_verb(3,"Username not entered\n"); 08689 return -1; 08690 } 08691 } 08692 if (useadsi) 08693 adsi_password(chan); 08694 08695 if (!ast_strlen_zero(prefix)) { 08696 char fullusername[80] = ""; 08697 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 08698 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 08699 ast_copy_string(mailbox, fullusername, mailbox_size); 08700 } 08701 08702 ast_debug(1, "Before find user for mailbox %s\n",mailbox); 08703 vmu = find_user(&vmus, context, mailbox); 08704 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 08705 /* saved password is blank, so don't bother asking */ 08706 password[0] = '\0'; 08707 } else { 08708 if (ast_streamfile(chan, vm_password, chan->language)) { 08709 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 08710 return -1; 08711 } 08712 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 08713 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 08714 return -1; 08715 } 08716 } 08717 08718 if (vmu) { 08719 passptr = vmu->password; 08720 if (passptr[0] == '-') passptr++; 08721 } 08722 if (vmu && !strcmp(passptr, password)) 08723 valid++; 08724 else { 08725 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 08726 if (!ast_strlen_zero(prefix)) 08727 mailbox[0] = '\0'; 08728 } 08729 logretries++; 08730 if (!valid) { 08731 if (skipuser || logretries >= max_logins) { 08732 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 08733 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 08734 return -1; 08735 } 08736 } else { 08737 if (useadsi) 08738 adsi_login(chan); 08739 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 08740 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 08741 return -1; 08742 } 08743 } 08744 if (ast_waitstream(chan, "")) /* Channel is hung up */ 08745 return -1; 08746 } 08747 } 08748 if (!valid && (logretries >= max_logins)) { 08749 ast_stopstream(chan); 08750 ast_play_and_wait(chan, "vm-goodbye"); 08751 return -1; 08752 } 08753 if (vmu && !skipuser) { 08754 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 08755 } 08756 return 0; 08757 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9596 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().
09597 { 09598 struct ast_vm_user svm; 09599 char *context, *box; 09600 AST_DECLARE_APP_ARGS(args, 09601 AST_APP_ARG(mbox); 09602 AST_APP_ARG(options); 09603 ); 09604 static int dep_warning = 0; 09605 09606 if (ast_strlen_zero(data)) { 09607 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 09608 return -1; 09609 } 09610 09611 if (!dep_warning) { 09612 dep_warning = 1; 09613 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *)data); 09614 } 09615 09616 box = ast_strdupa(data); 09617 09618 AST_STANDARD_APP_ARGS(args, box); 09619 09620 if (args.options) { 09621 } 09622 09623 if ((context = strchr(args.mbox, '@'))) { 09624 *context = '\0'; 09625 context++; 09626 } 09627 09628 if (find_user(&svm, context, args.mbox)) { 09629 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 09630 } else 09631 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 09632 09633 return 0; 09634 }
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 8640 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_tw().
Referenced by vm_execmain().
08641 { 08642 if (!strcasecmp(chan->language, "es")) { /* SPANISH */ 08643 return vm_browse_messages_es(chan, vms, vmu); 08644 } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN */ 08645 return vm_browse_messages_it(chan, vms, vmu); 08646 } else if (!strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* PORTUGUESE */ 08647 return vm_browse_messages_pt(chan, vms, vmu); 08648 } else if (!strcasecmp(chan->language, "gr")){ 08649 return vm_browse_messages_gr(chan, vms, vmu); /* GREEK */ 08650 } else if (!strcasecmp(chan->language, "tw")){ 08651 return vm_browse_messages_tw(chan, vms, vmu); /* CHINESE (Taiwan) */ 08652 } else if (!strcasecmp(chan->language, "he")) { 08653 return vm_browse_messages_he(chan, vms, vmu); /* HEBREW */ 08654 } else { /* Default to English syntax */ 08655 return vm_browse_messages_en(chan, vms, vmu); 08656 } 08657 }
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 8503 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().
08504 { 08505 int cmd=0; 08506 08507 if (vms->lastmsg > -1) { 08508 cmd = play_message(chan, vmu, vms); 08509 } else { 08510 cmd = ast_play_and_wait(chan, "vm-youhave"); 08511 if (!cmd) 08512 cmd = ast_play_and_wait(chan, "vm-no"); 08513 if (!cmd) { 08514 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08515 cmd = ast_play_and_wait(chan, vms->fn); 08516 } 08517 if (!cmd) 08518 cmd = ast_play_and_wait(chan, "vm-messages"); 08519 } 08520 return cmd; 08521 }
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 8557 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().
08558 { 08559 int cmd=0; 08560 08561 if (vms->lastmsg > -1) { 08562 cmd = play_message(chan, vmu, vms); 08563 } else { 08564 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 08565 if (!cmd) 08566 cmd = ast_play_and_wait(chan, "vm-messages"); 08567 if (!cmd) { 08568 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08569 cmd = ast_play_and_wait(chan, vms->fn); 08570 } 08571 } 08572 return cmd; 08573 }
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 8451 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().
08452 { 08453 int cmd=0; 08454 08455 if (vms->lastmsg > -1) { 08456 cmd = play_message(chan, vmu, vms); 08457 } else { 08458 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 08459 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 08460 if (!cmd) { 08461 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 08462 cmd = ast_play_and_wait(chan, vms->fn); 08463 } 08464 if (!cmd) 08465 cmd = ast_play_and_wait(chan, "vm-messages"); 08466 } else { 08467 if (!cmd) 08468 cmd = ast_play_and_wait(chan, "vm-messages"); 08469 if (!cmd) { 08470 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08471 cmd = ast_play_and_wait(chan, vms->fn); 08472 } 08473 } 08474 } 08475 return cmd; 08476 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 8479 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().
08480 { 08481 int cmd = 0; 08482 08483 if (vms->lastmsg > -1) { 08484 cmd = play_message(chan, vmu, vms); 08485 } else { 08486 if (!strcasecmp(vms->fn, "INBOX")) { 08487 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 08488 } else { 08489 cmd = ast_play_and_wait(chan, "vm-nomessages"); 08490 } 08491 } 08492 return cmd; 08493 }
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 8531 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().
08532 { 08533 int cmd=0; 08534 08535 if (vms->lastmsg > -1) { 08536 cmd = play_message(chan, vmu, vms); 08537 } else { 08538 cmd = ast_play_and_wait(chan, "vm-no"); 08539 if (!cmd) 08540 cmd = ast_play_and_wait(chan, "vm-message"); 08541 if (!cmd) { 08542 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08543 cmd = ast_play_and_wait(chan, vms->fn); 08544 } 08545 } 08546 return cmd; 08547 }
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 8583 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().
08584 { 08585 int cmd=0; 08586 08587 if (vms->lastmsg > -1) { 08588 cmd = play_message(chan, vmu, vms); 08589 } else { 08590 cmd = ast_play_and_wait(chan, "vm-no"); 08591 if (!cmd) { 08592 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08593 cmd = ast_play_and_wait(chan, vms->fn); 08594 } 08595 if (!cmd) 08596 cmd = ast_play_and_wait(chan, "vm-messages"); 08597 } 08598 return cmd; 08599 }
static int vm_browse_messages_tw | ( | 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 8609 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().
08610 { 08611 int cmd=0; 08612 08613 if (vms->lastmsg > -1) { 08614 cmd = play_message(chan, vmu, vms); 08615 } else { 08616 cmd = ast_play_and_wait(chan, "vm-you"); 08617 if (!cmd) 08618 cmd = ast_play_and_wait(chan, "vm-haveno"); 08619 if (!cmd) 08620 cmd = ast_play_and_wait(chan, "vm-messages"); 08621 if (!cmd) { 08622 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 08623 cmd = ast_play_and_wait(chan, vms->fn); 08624 } 08625 } 08626 return cmd; 08627 }
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 1153 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().
01154 { 01155 struct ast_config *cfg=NULL; 01156 struct ast_variable *var=NULL; 01157 struct ast_category *cat=NULL; 01158 char *category=NULL, *value=NULL, *new=NULL; 01159 const char *tmp=NULL; 01160 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01161 if (!change_password_realtime(vmu, newpassword)) 01162 return; 01163 01164 /* check voicemail.conf */ 01165 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags))) { 01166 while ((category = ast_category_browse(cfg, category))) { 01167 if (!strcasecmp(category, vmu->context)) { 01168 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01169 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01170 break; 01171 } 01172 value = strstr(tmp,","); 01173 if (!value) { 01174 ast_log(AST_LOG_WARNING, "variable has bad format.\n"); 01175 break; 01176 } 01177 new = alloca((strlen(value)+strlen(newpassword)+1)); 01178 sprintf(new,"%s%s", newpassword, value); 01179 if (!(cat = ast_category_get(cfg, category))) { 01180 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01181 break; 01182 } 01183 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01184 } 01185 } 01186 /* save the results */ 01187 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01188 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01189 config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01190 } 01191 category = NULL; 01192 var = NULL; 01193 /* check users.conf and update the password stored for the mailbox*/ 01194 /* if no vmsecret entry exists create one. */ 01195 if ((cfg = ast_config_load("users.conf", config_flags))) { 01196 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01197 while ((category = ast_category_browse(cfg, category))) { 01198 ast_debug(4, "users.conf: %s\n", category); 01199 if (!strcasecmp(category, vmu->mailbox)) { 01200 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01201 ast_debug(3, "looks like we need to make vmsecret!\n"); 01202 var = ast_variable_new("vmsecret", newpassword, ""); 01203 } 01204 new = alloca(strlen(newpassword)+1); 01205 sprintf(new, "%s", newpassword); 01206 if (!(cat = ast_category_get(cfg, category))) { 01207 ast_debug(4, "failed to get category!\n"); 01208 break; 01209 } 01210 if (!var) 01211 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01212 else 01213 ast_variable_append(cat, var); 01214 } 01215 } 01216 /* save the results and clean things up */ 01217 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01218 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01219 config_text_file_save("users.conf", cfg, "AppVoicemail"); 01220 } 01221 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1223 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().
01224 { 01225 char buf[255]; 01226 snprintf(buf,255,"%s %s %s %s",ext_pass_cmd,vmu->context,vmu->mailbox,newpassword); 01227 if (!ast_safe_system(buf)) { 01228 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01229 /* Reset the password in memory, too */ 01230 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01231 } 01232 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 854 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().
00855 { 00856 int fds[2], pid = 0; 00857 00858 memset(buf, 0, len); 00859 00860 if (pipe(fds)) { 00861 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 00862 } else { 00863 /* good to go*/ 00864 pid = ast_safe_fork(0); 00865 00866 if (pid < 0) { 00867 /* ok maybe not */ 00868 close(fds[0]); 00869 close(fds[1]); 00870 snprintf(buf, len, "FAILURE: Fork failed"); 00871 } else if (pid) { 00872 /* parent */ 00873 close(fds[1]); 00874 if (read(fds[0], buf, len) < 0) { 00875 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 00876 } 00877 close(fds[0]); 00878 } else { 00879 /* child */ 00880 AST_DECLARE_APP_ARGS(arg, 00881 AST_APP_ARG(v)[20]; 00882 ); 00883 char *mycmd = ast_strdupa(command); 00884 00885 close(fds[0]); 00886 dup2(fds[1], STDOUT_FILENO); 00887 close(fds[1]); 00888 ast_close_fds_above_n(STDOUT_FILENO); 00889 00890 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 00891 00892 execv(arg.v[0], arg.v); 00893 printf("FAILURE: %s", strerror(errno)); 00894 _exit(0); 00895 } 00896 } 00897 return buf; 00898 }
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 3577 of file app_voicemail.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
03578 { 03579 char *txt; 03580 int txtsize = 0; 03581 03582 txtsize = (strlen(file) + 5)*sizeof(char); 03583 txt = alloca(txtsize); 03584 /* Sprintf here would safe because we alloca'd exactly the right length, 03585 * but trying to eliminate all sprintf's anyhow 03586 */ 03587 if (ast_check_realtime("voicemail_data")) { 03588 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 03589 } 03590 snprintf(txt, txtsize, "%s.txt", file); 03591 unlink(txt); 03592 return ast_filedelete(file, NULL); 03593 }
static int vm_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9464 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(), 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().
09465 { 09466 int res = 0; 09467 char *tmp; 09468 struct leave_vm_options leave_options; 09469 struct ast_flags flags = { 0 }; 09470 char *opts[OPT_ARG_ARRAY_SIZE]; 09471 AST_DECLARE_APP_ARGS(args, 09472 AST_APP_ARG(argv0); 09473 AST_APP_ARG(argv1); 09474 ); 09475 09476 memset(&leave_options, 0, sizeof(leave_options)); 09477 09478 if (chan->_state != AST_STATE_UP) 09479 ast_answer(chan); 09480 09481 if (!ast_strlen_zero(data)) { 09482 tmp = ast_strdupa(data); 09483 AST_STANDARD_APP_ARGS(args, tmp); 09484 if (args.argc == 2) { 09485 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09486 return -1; 09487 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 09488 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09489 int gain; 09490 09491 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) { 09492 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09493 return -1; 09494 } else { 09495 leave_options.record_gain = (signed char) gain; 09496 } 09497 } 09498 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 09499 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 09500 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 09501 } 09502 } 09503 } else { 09504 char temp[256]; 09505 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 09506 if (res < 0) 09507 return res; 09508 if (ast_strlen_zero(temp)) 09509 return 0; 09510 args.argv0 = ast_strdupa(temp); 09511 } 09512 09513 res = leave_voicemail(chan, args.argv0, &leave_options); 09514 09515 if (res == ERROR_LOCK_PATH) { 09516 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 09517 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 09518 res = 0; 09519 } 09520 09521 return res; 09522 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 8759 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(), 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().
08760 { 08761 /* XXX This is, admittedly, some pretty horrendous code. For some 08762 reason it just seemed a lot easier to do with GOTO's. I feel 08763 like I'm back in my GWBASIC days. XXX */ 08764 int res=-1; 08765 int cmd=0; 08766 int valid = 0; 08767 char prefixstr[80] =""; 08768 char ext_context[256]=""; 08769 int box; 08770 int useadsi = 0; 08771 int skipuser = 0; 08772 struct vm_state vms; 08773 struct ast_vm_user *vmu = NULL, vmus; 08774 char *context=NULL; 08775 int silentexit = 0; 08776 struct ast_flags flags = { 0 }; 08777 signed char record_gain = 0; 08778 int play_auto = 0; 08779 int play_folder = 0; 08780 int in_urgent = 0; 08781 #ifdef IMAP_STORAGE 08782 int deleted = 0; 08783 #endif 08784 08785 /* Add the vm_state to the active list and keep it active */ 08786 memset(&vms, 0, sizeof(vms)); 08787 08788 vms.lastmsg = -1; 08789 08790 memset(&vmus, 0, sizeof(vmus)); 08791 08792 if (chan->_state != AST_STATE_UP) { 08793 ast_debug(1, "Before ast_answer\n"); 08794 ast_answer(chan); 08795 } 08796 08797 if (!ast_strlen_zero(data)) { 08798 char *opts[OPT_ARG_ARRAY_SIZE]; 08799 char *parse; 08800 AST_DECLARE_APP_ARGS(args, 08801 AST_APP_ARG(argv0); 08802 AST_APP_ARG(argv1); 08803 ); 08804 08805 parse = ast_strdupa(data); 08806 08807 AST_STANDARD_APP_ARGS(args, parse); 08808 08809 if (args.argc == 2) { 08810 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 08811 return -1; 08812 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 08813 int gain; 08814 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 08815 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%d", &gain) != 1) { 08816 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 08817 return -1; 08818 } else { 08819 record_gain = (signed char) gain; 08820 } 08821 } else { 08822 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 08823 } 08824 } 08825 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 08826 play_auto = 1; 08827 if (opts[OPT_ARG_PLAYFOLDER]) { 08828 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%d", &play_folder) != 1) { 08829 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for folder autoplay option\n", opts[OPT_ARG_PLAYFOLDER]); 08830 } 08831 } else { 08832 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 08833 } 08834 if ( play_folder > 9 || play_folder < 0) { 08835 ast_log(AST_LOG_WARNING, "Invalid value '%d' provided for folder autoplay option\n", play_folder); 08836 play_folder = 0; 08837 } 08838 } 08839 } else { 08840 /* old style options parsing */ 08841 while (*(args.argv0)) { 08842 if (*(args.argv0) == 's') 08843 ast_set_flag(&flags, OPT_SILENT); 08844 else if (*(args.argv0) == 'p') 08845 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 08846 else 08847 break; 08848 (args.argv0)++; 08849 } 08850 08851 } 08852 08853 valid = ast_test_flag(&flags, OPT_SILENT); 08854 08855 if ((context = strchr(args.argv0, '@'))) 08856 *context++ = '\0'; 08857 08858 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 08859 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 08860 else 08861 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 08862 08863 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 08864 skipuser++; 08865 else 08866 valid = 0; 08867 } 08868 08869 if (!valid) 08870 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 08871 08872 ast_debug(1, "After vm_authenticate\n"); 08873 if (!res) { 08874 valid = 1; 08875 if (!skipuser) 08876 vmu = &vmus; 08877 } else { 08878 res = 0; 08879 } 08880 08881 /* If ADSI is supported, setup login screen */ 08882 adsi_begin(chan, &useadsi); 08883 08884 #ifdef IMAP_STORAGE 08885 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 08886 pthread_setspecific(ts_vmstate.key, &vms); 08887 08888 vms.interactive = 1; 08889 vms.updated = 1; 08890 if (vmu) 08891 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 08892 vmstate_insert(&vms); 08893 init_vm_state(&vms); 08894 #endif 08895 if (!valid) 08896 goto out; 08897 08898 if (!(vms.deleted = ast_calloc(vmu->maxmsg, sizeof(int)))) { 08899 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 08900 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 08901 return -1; 08902 } 08903 if (!(vms.heard = ast_calloc(vmu->maxmsg, sizeof(int)))) { 08904 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 08905 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 08906 return -1; 08907 } 08908 08909 /* Set language from config to override channel language */ 08910 if (!ast_strlen_zero(vmu->language)) 08911 ast_string_field_set(chan, language, vmu->language); 08912 08913 /* Retrieve urgent, old and new message counts */ 08914 ast_debug(1, "Before open_mailbox\n"); 08915 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 08916 if (res == ERROR_LOCK_PATH) 08917 goto out; 08918 vms.oldmessages = vms.lastmsg + 1; 08919 ast_debug(1, "Number of old messages: %d\n",vms.oldmessages); 08920 /* check INBOX */ 08921 res = open_mailbox(&vms, vmu, NEW_FOLDER); 08922 if (res == ERROR_LOCK_PATH) 08923 goto out; 08924 vms.newmessages = vms.lastmsg + 1; 08925 ast_debug(1, "Number of new messages: %d\n",vms.newmessages); 08926 /* Start in Urgent */ 08927 in_urgent = 1; 08928 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 08929 if (res == ERROR_LOCK_PATH) 08930 goto out; 08931 vms.urgentmessages = vms.lastmsg + 1; 08932 ast_debug(1, "Number of urgent messages: %d\n",vms.urgentmessages); 08933 08934 /* Select proper mailbox FIRST!! */ 08935 if (play_auto) { 08936 if (vms.urgentmessages) { 08937 in_urgent = 1; 08938 res = open_mailbox(&vms, vmu, 11); 08939 } else { 08940 in_urgent = 0; 08941 res = open_mailbox(&vms, vmu, play_folder); 08942 } 08943 if (res == ERROR_LOCK_PATH) 08944 goto out; 08945 08946 /* If there are no new messages, inform the user and hangup */ 08947 if (vms.lastmsg == -1) { 08948 in_urgent = 0; 08949 cmd = vm_browse_messages(chan, &vms, vmu); 08950 res = 0; 08951 goto out; 08952 } 08953 } else { 08954 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 08955 /* If we only have old messages start here */ 08956 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 08957 in_urgent = 0; 08958 play_folder = 1; 08959 if (res == ERROR_LOCK_PATH) 08960 goto out; 08961 } else if (!vms.urgentmessages && vms.newmessages) { 08962 /* If we have new messages but none are urgent */ 08963 in_urgent = 0; 08964 res = open_mailbox(&vms, vmu, NEW_FOLDER); 08965 if (res == ERROR_LOCK_PATH) 08966 goto out; 08967 } 08968 } 08969 08970 if (useadsi) 08971 adsi_status(chan, &vms); 08972 res = 0; 08973 08974 /* Check to see if this is a new user */ 08975 if (!strcasecmp(vmu->mailbox, vmu->password) && 08976 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 08977 if (ast_play_and_wait(chan, "vm-newuser") == -1) 08978 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 08979 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 08980 if ((cmd == 't') || (cmd == '#')) { 08981 /* Timeout */ 08982 res = 0; 08983 goto out; 08984 } else if (cmd < 0) { 08985 /* Hangup */ 08986 res = -1; 08987 goto out; 08988 } 08989 } 08990 #ifdef IMAP_STORAGE 08991 ast_debug(3, "Checking quotas: comparing %u to %u\n",vms.quota_usage,vms.quota_limit); 08992 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 08993 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 08994 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 08995 } 08996 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n",(vms.newmessages + vms.oldmessages),vmu->maxmsg); 08997 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 08998 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 08999 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09000 } 09001 #endif 09002 if (play_auto) { 09003 cmd = '1'; 09004 } else { 09005 cmd = vm_intro(chan, vmu, &vms); 09006 } 09007 09008 vms.repeats = 0; 09009 vms.starting = 1; 09010 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09011 /* Run main menu */ 09012 switch (cmd) { 09013 case '1': /* First message */ 09014 vms.curmsg = 0; 09015 /* Fall through */ 09016 case '5': /* Play current message */ 09017 cmd = vm_browse_messages(chan, &vms, vmu); 09018 break; 09019 case '2': /* Change folders */ 09020 if (useadsi) 09021 adsi_folders(chan, 0, "Change to folder..."); 09022 cmd = get_folder2(chan, "vm-changeto", 0); 09023 if (cmd == '#') { 09024 cmd = 0; 09025 } else if (cmd > 0) { 09026 cmd = cmd - '0'; 09027 res = close_mailbox(&vms, vmu); 09028 if (res == ERROR_LOCK_PATH) 09029 goto out; 09030 /* If folder is not urgent, set in_urgent to zero! */ 09031 if (cmd != 11) in_urgent = 0; 09032 res = open_mailbox(&vms, vmu, cmd); 09033 if (res == ERROR_LOCK_PATH) 09034 goto out; 09035 play_folder = cmd; 09036 cmd = 0; 09037 } 09038 if (useadsi) 09039 adsi_status2(chan, &vms); 09040 09041 if (!cmd) 09042 cmd = vm_play_folder_name(chan, vms.vmbox); 09043 09044 vms.starting = 1; 09045 break; 09046 case '3': /* Advanced options */ 09047 cmd = 0; 09048 vms.repeats = 0; 09049 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09050 switch (cmd) { 09051 case '1': /* Reply */ 09052 if (vms.lastmsg > -1 && !vms.starting) { 09053 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 09054 if (cmd == ERROR_LOCK_PATH) { 09055 res = cmd; 09056 goto out; 09057 } 09058 } else 09059 cmd = ast_play_and_wait(chan, "vm-sorry"); 09060 cmd = 't'; 09061 break; 09062 case '2': /* Callback */ 09063 if (!vms.starting) 09064 ast_verb(3, "Callback Requested\n"); 09065 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 09066 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 09067 if (cmd == 9) { 09068 silentexit = 1; 09069 goto out; 09070 } else if (cmd == ERROR_LOCK_PATH) { 09071 res = cmd; 09072 goto out; 09073 } 09074 } else 09075 cmd = ast_play_and_wait(chan, "vm-sorry"); 09076 cmd = 't'; 09077 break; 09078 case '3': /* Envelope */ 09079 if (vms.lastmsg > -1 && !vms.starting) { 09080 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 09081 if (cmd == ERROR_LOCK_PATH) { 09082 res = cmd; 09083 goto out; 09084 } 09085 } else 09086 cmd = ast_play_and_wait(chan, "vm-sorry"); 09087 cmd = 't'; 09088 break; 09089 case '4': /* Dialout */ 09090 if (!ast_strlen_zero(vmu->dialout)) { 09091 cmd = dialout(chan, vmu, NULL, vmu->dialout); 09092 if (cmd == 9) { 09093 silentexit = 1; 09094 goto out; 09095 } 09096 } else 09097 cmd = ast_play_and_wait(chan, "vm-sorry"); 09098 cmd = 't'; 09099 break; 09100 09101 case '5': /* Leave VoiceMail */ 09102 if (ast_test_flag(vmu, VM_SVMAIL)) { 09103 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 09104 if (cmd == ERROR_LOCK_PATH) { 09105 res = cmd; 09106 ast_log(AST_LOG_WARNING, "forward_message failed to lock path.\n"); 09107 goto out; 09108 } 09109 } else 09110 cmd = ast_play_and_wait(chan,"vm-sorry"); 09111 cmd='t'; 09112 break; 09113 09114 case '*': /* Return to main menu */ 09115 cmd = 't'; 09116 break; 09117 09118 default: 09119 cmd = 0; 09120 if (!vms.starting) { 09121 cmd = ast_play_and_wait(chan, "vm-toreply"); 09122 } 09123 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 09124 cmd = ast_play_and_wait(chan, "vm-tocallback"); 09125 } 09126 if (!cmd && !vms.starting) { 09127 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 09128 } 09129 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 09130 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 09131 } 09132 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) 09133 cmd=ast_play_and_wait(chan, "vm-leavemsg"); 09134 if (!cmd) 09135 cmd = ast_play_and_wait(chan, "vm-starmain"); 09136 if (!cmd) 09137 cmd = ast_waitfordigit(chan,6000); 09138 if (!cmd) 09139 vms.repeats++; 09140 if (vms.repeats > 3) 09141 cmd = 't'; 09142 } 09143 } 09144 if (cmd == 't') { 09145 cmd = 0; 09146 vms.repeats = 0; 09147 } 09148 break; 09149 case '4': /* Go to the previous message */ 09150 if (vms.curmsg > 0) { 09151 vms.curmsg--; 09152 cmd = play_message(chan, vmu, &vms); 09153 } else { 09154 /* Check if we were listening to new 09155 messages. If so, go to Urgent messages 09156 instead of saying "no more messages" 09157 */ 09158 if (in_urgent == 0 && vms.urgentmessages > 0) { 09159 /* Check for Urgent messages */ 09160 in_urgent = 1; 09161 res = close_mailbox(&vms, vmu); 09162 if (res == ERROR_LOCK_PATH) 09163 goto out; 09164 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 09165 if (res == ERROR_LOCK_PATH) 09166 goto out; 09167 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n",vms.lastmsg + 1); 09168 vms.curmsg = vms.lastmsg; 09169 if (vms.lastmsg < 0) 09170 cmd = ast_play_and_wait(chan, "vm-nomore"); 09171 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09172 vms.curmsg = vms.lastmsg; 09173 cmd = play_message(chan, vmu, &vms); 09174 } else { 09175 cmd = ast_play_and_wait(chan, "vm-nomore"); 09176 } 09177 } 09178 break; 09179 case '6': /* Go to the next message */ 09180 if (vms.curmsg < vms.lastmsg) { 09181 vms.curmsg++; 09182 cmd = play_message(chan, vmu, &vms); 09183 } else { 09184 if (in_urgent && vms.newmessages > 0) { 09185 /* Check if we were listening to urgent 09186 * messages. If so, go to regular new messages 09187 * instead of saying "no more messages" 09188 */ 09189 in_urgent = 0; 09190 res = close_mailbox(&vms, vmu); 09191 if (res == ERROR_LOCK_PATH) 09192 goto out; 09193 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09194 if (res == ERROR_LOCK_PATH) 09195 goto out; 09196 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09197 vms.curmsg = -1; 09198 if (vms.lastmsg < 0) { 09199 cmd = ast_play_and_wait(chan, "vm-nomore"); 09200 } 09201 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09202 vms.curmsg = 0; 09203 cmd = play_message(chan, vmu, &vms); 09204 } else { 09205 cmd = ast_play_and_wait(chan, "vm-nomore"); 09206 } 09207 } 09208 break; 09209 case '7': /* Delete the current message */ 09210 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 09211 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 09212 if (useadsi) 09213 adsi_delete(chan, &vms); 09214 if (vms.deleted[vms.curmsg]) { 09215 if (play_folder == 0) { 09216 if (in_urgent) { 09217 vms.urgentmessages--; 09218 } else { 09219 vms.newmessages--; 09220 } 09221 } 09222 else if (play_folder == 1) 09223 vms.oldmessages--; 09224 cmd = ast_play_and_wait(chan, "vm-deleted"); 09225 } else { 09226 if (play_folder == 0) { 09227 if (in_urgent) { 09228 vms.urgentmessages++; 09229 } else { 09230 vms.newmessages++; 09231 } 09232 } 09233 else if (play_folder == 1) 09234 vms.oldmessages++; 09235 cmd = ast_play_and_wait(chan, "vm-undeleted"); 09236 } 09237 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 09238 if (vms.curmsg < vms.lastmsg) { 09239 vms.curmsg++; 09240 cmd = play_message(chan, vmu, &vms); 09241 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09242 vms.curmsg = 0; 09243 cmd = play_message(chan, vmu, &vms); 09244 } else { 09245 /* Check if we were listening to urgent 09246 messages. If so, go to regular new messages 09247 instead of saying "no more messages" 09248 */ 09249 if (in_urgent == 1) { 09250 /* Check for new messages */ 09251 in_urgent = 0; 09252 res = close_mailbox(&vms, vmu); 09253 if (res == ERROR_LOCK_PATH) 09254 goto out; 09255 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09256 if (res == ERROR_LOCK_PATH) 09257 goto out; 09258 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09259 vms.curmsg = -1; 09260 if (vms.lastmsg < 0) 09261 cmd = ast_play_and_wait(chan, "vm-nomore"); 09262 } else { 09263 cmd = ast_play_and_wait(chan, "vm-nomore"); 09264 } 09265 } 09266 } 09267 } else /* Delete not valid if we haven't selected a message */ 09268 cmd = 0; 09269 #ifdef IMAP_STORAGE 09270 deleted = 1; 09271 #endif 09272 break; 09273 09274 case '8': /* Forward the current messgae */ 09275 if (vms.lastmsg > -1) { 09276 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 09277 if (cmd == ERROR_LOCK_PATH) { 09278 res = cmd; 09279 goto out; 09280 } 09281 } else { 09282 /* Check if we were listening to urgent 09283 messages. If so, go to regular new messages 09284 instead of saying "no more messages" 09285 */ 09286 if (in_urgent == 1 && vms.newmessages > 0) { 09287 /* Check for new messages */ 09288 in_urgent = 0; 09289 res = close_mailbox(&vms, vmu); 09290 if (res == ERROR_LOCK_PATH) 09291 goto out; 09292 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09293 if (res == ERROR_LOCK_PATH) 09294 goto out; 09295 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09296 vms.curmsg = -1; 09297 if (vms.lastmsg < 0) 09298 cmd = ast_play_and_wait(chan, "vm-nomore"); 09299 } else { 09300 cmd = ast_play_and_wait(chan, "vm-nomore"); 09301 } 09302 } 09303 break; 09304 case '9': /* Save message to folder */ 09305 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 09306 /* No message selected */ 09307 cmd = 0; 09308 break; 09309 } 09310 if (useadsi) 09311 adsi_folders(chan, 1, "Save to folder..."); 09312 cmd = get_folder2(chan, "vm-savefolder", 1); 09313 box = 0; /* Shut up compiler */ 09314 if (cmd == '#') { 09315 cmd = 0; 09316 break; 09317 } else if (cmd > 0) { 09318 box = cmd = cmd - '0'; 09319 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 09320 if (cmd == ERROR_LOCK_PATH) { 09321 res = cmd; 09322 goto out; 09323 #ifndef IMAP_STORAGE 09324 } else if (!cmd) { 09325 vms.deleted[vms.curmsg] = 1; 09326 #endif 09327 } else { 09328 vms.deleted[vms.curmsg] = 0; 09329 vms.heard[vms.curmsg] = 0; 09330 } 09331 } 09332 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 09333 if (useadsi) 09334 adsi_message(chan, &vms); 09335 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(box)); 09336 if (!cmd) { 09337 cmd = ast_play_and_wait(chan, "vm-message"); 09338 if (!cmd) 09339 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 09340 if (!cmd) 09341 cmd = ast_play_and_wait(chan, "vm-savedto"); 09342 if (!cmd) 09343 cmd = vm_play_folder_name(chan, vms.fn); 09344 } else { 09345 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09346 } 09347 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 09348 if (vms.curmsg < vms.lastmsg) { 09349 vms.curmsg++; 09350 cmd = play_message(chan, vmu, &vms); 09351 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 09352 vms.curmsg = 0; 09353 cmd = play_message(chan, vmu, &vms); 09354 } else { 09355 /* Check if we were listening to urgent 09356 messages. If so, go to regular new messages 09357 instead of saying "no more messages" 09358 */ 09359 if (in_urgent == 1 && vms.newmessages > 0) { 09360 /* Check for new messages */ 09361 in_urgent = 0; 09362 res = close_mailbox(&vms, vmu); 09363 if (res == ERROR_LOCK_PATH) 09364 goto out; 09365 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09366 if (res == ERROR_LOCK_PATH) 09367 goto out; 09368 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n",vms.lastmsg + 1); 09369 vms.curmsg = -1; 09370 if (vms.lastmsg < 0) 09371 cmd = ast_play_and_wait(chan, "vm-nomore"); 09372 } else { 09373 cmd = ast_play_and_wait(chan, "vm-nomore"); 09374 } 09375 } 09376 } 09377 break; 09378 case '*': /* Help */ 09379 if (!vms.starting) { 09380 cmd = ast_play_and_wait(chan, "vm-onefor"); 09381 if (!cmd) 09382 cmd = vm_play_folder_name(chan, vms.vmbox); 09383 if (!cmd) 09384 cmd = ast_play_and_wait(chan, "vm-opts"); 09385 if (!cmd) 09386 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 09387 } else 09388 cmd = 0; 09389 break; 09390 case '0': /* Mailbox options */ 09391 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 09392 if (useadsi) 09393 adsi_status(chan, &vms); 09394 break; 09395 default: /* Nothing */ 09396 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 09397 break; 09398 } 09399 } 09400 if ((cmd == 't') || (cmd == '#')) { 09401 /* Timeout */ 09402 res = 0; 09403 } else { 09404 /* Hangup */ 09405 res = -1; 09406 } 09407 09408 out: 09409 if (res > -1) { 09410 ast_stopstream(chan); 09411 adsi_goodbye(chan); 09412 if (valid) { 09413 if (silentexit) 09414 res = ast_play_and_wait(chan, "vm-dialout"); 09415 else 09416 res = ast_play_and_wait(chan, "vm-goodbye"); 09417 if (res > 0) 09418 res = 0; 09419 } 09420 if (useadsi) 09421 ast_adsi_unload_session(chan); 09422 } 09423 if (vmu) 09424 close_mailbox(&vms, vmu); 09425 if (valid) { 09426 int new = 0, old = 0, urgent = 0; 09427 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 09428 manager_event(EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 09429 /* Urgent flag not passwd to externnotify here */ 09430 run_externnotify(vmu->context, vmu->mailbox, NULL); 09431 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 09432 queue_mwi_event(ext_context, urgent, new, old); 09433 } 09434 #ifdef IMAP_STORAGE 09435 /* expunge message - use UID Expunge if supported on IMAP server*/ 09436 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n",deleted,expungeonhangup); 09437 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 09438 ast_mutex_lock(&vms.lock); 09439 #ifdef HAVE_IMAP_TK2006 09440 if (LEVELUIDPLUS (vms.mailstream)) { 09441 mail_expunge_full(vms.mailstream,NIL,EX_UID); 09442 } else 09443 #endif 09444 mail_expunge(vms.mailstream); 09445 ast_mutex_unlock(&vms.lock); 09446 } 09447 /* before we delete the state, we should copy pertinent info 09448 * back to the persistent model */ 09449 vmstate_delete(&vms); 09450 #endif 09451 if (vmu) 09452 free_user(vmu); 09453 if (vms.deleted) 09454 ast_free(vms.deleted); 09455 if (vms.heard) 09456 ast_free(vms.heard); 09457 09458 #ifdef IMAP_STORAGE 09459 pthread_setspecific(ts_vmstate.key, NULL); 09460 #endif 09461 return res; 09462 }
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 6009 of file app_voicemail.c.
References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_filecopy(), ast_filedelete(), 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(), INTRO, make_file(), ast_vm_user::maxsecs, and play_record_review().
Referenced by forward_message().
06011 { 06012 #ifdef IMAP_STORAGE 06013 int res; 06014 #endif 06015 int cmd = 0; 06016 int retries = 0, prepend_duration = 0, already_recorded = 0; 06017 char msgfile[PATH_MAX], backup[PATH_MAX]; 06018 char textfile[PATH_MAX]; 06019 struct ast_config *msg_cfg; 06020 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06021 #ifndef IMAP_STORAGE 06022 signed char zero_gain = 0; 06023 #endif 06024 const char *duration_str; 06025 06026 /* Must always populate duration correctly */ 06027 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06028 strcpy(textfile, msgfile); 06029 strcpy(backup, msgfile); 06030 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06031 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06032 06033 if ((msg_cfg = ast_config_load(textfile, config_flags)) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06034 *duration = atoi(duration_str); 06035 } else { 06036 *duration = 0; 06037 } 06038 06039 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06040 if (cmd) 06041 retries = 0; 06042 switch (cmd) { 06043 case '1': 06044 06045 #ifdef IMAP_STORAGE 06046 /* Record new intro file */ 06047 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06048 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06049 res = ast_play_and_wait(chan, INTRO); 06050 res = ast_play_and_wait(chan, "beep"); 06051 res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *)duration, NULL, record_gain, vms, flag); 06052 cmd = 't'; 06053 #else 06054 06055 /* prepend a message to the current message, update the metadata and return */ 06056 06057 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06058 strcpy(textfile, msgfile); 06059 strncat(textfile, ".txt", sizeof(textfile) - 1); 06060 *duration = 0; 06061 06062 /* if we can't read the message metadata, stop now */ 06063 if (!msg_cfg) { 06064 cmd = 0; 06065 break; 06066 } 06067 06068 /* Back up the original file, so we can retry the prepend */ 06069 if (already_recorded) 06070 ast_filecopy(backup, msgfile, NULL); 06071 else 06072 ast_filecopy(msgfile, backup, NULL); 06073 already_recorded = 1; 06074 06075 if (record_gain) 06076 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06077 06078 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence); 06079 if (record_gain) 06080 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06081 06082 06083 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06084 *duration = atoi(duration_str); 06085 06086 if (prepend_duration) { 06087 struct ast_category *msg_cat; 06088 /* need enough space for a maximum-length message duration */ 06089 char duration_buf[12]; 06090 06091 *duration += prepend_duration; 06092 msg_cat = ast_category_get(msg_cfg, "message"); 06093 snprintf(duration_buf, 11, "%ld", *duration); 06094 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06095 config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06096 } 06097 } 06098 06099 #endif 06100 break; 06101 case '2': 06102 /* NULL out introfile so we know there is no intro! */ 06103 #ifdef IMAP_STORAGE 06104 *vms->introfn = '\0'; 06105 #endif 06106 cmd = 't'; 06107 break; 06108 case '*': 06109 cmd = '*'; 06110 break; 06111 default: 06112 cmd = ast_play_and_wait(chan,"vm-forwardoptions"); 06113 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06114 if (!cmd) 06115 cmd = ast_play_and_wait(chan,"vm-starmain"); 06116 /* "press star to return to the main menu" */ 06117 if (!cmd) 06118 cmd = ast_waitfordigit(chan,6000); 06119 if (!cmd) 06120 retries++; 06121 if (retries > 3) 06122 cmd = 't'; 06123 } 06124 } 06125 06126 if (msg_cfg) 06127 ast_config_destroy(msg_cfg); 06128 if (already_recorded) 06129 ast_filedelete(backup, NULL); 06130 if (prepend_duration) 06131 *duration = prepend_duration; 06132 06133 if (cmd == 't' || cmd == 'S') 06134 cmd = 0; 06135 return cmd; 06136 }
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 8152 of file app_voicemail.c.
References chan, ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_tw().
Referenced by vm_execmain().
08153 { 08154 if (vms->starting && !strcasecmp(chan->language, "tw")) { /* CHINESE (Taiwan) syntax */ 08155 return vm_instructions_tw(chan, vmu, vms, skipadvanced, in_urgent); 08156 } else { /* Default to ENGLISH */ 08157 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08158 } 08159 }
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 8048 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_tw().
08049 { 08050 int res = 0; 08051 /* Play instructions and wait for new command */ 08052 while (!res) { 08053 if (vms->starting) { 08054 if (vms->lastmsg > -1) { 08055 if (skipadvanced) 08056 res = ast_play_and_wait(chan, "vm-onefor-full"); 08057 else 08058 res = ast_play_and_wait(chan, "vm-onefor"); 08059 if (!res) 08060 res = vm_play_folder_name(chan, vms->vmbox); 08061 } 08062 if (!res) { 08063 if (skipadvanced) 08064 res = ast_play_and_wait(chan, "vm-opts-full"); 08065 else 08066 res = ast_play_and_wait(chan, "vm-opts"); 08067 } 08068 } else { 08069 /* Added for additional help */ 08070 if (skipadvanced) { 08071 res = ast_play_and_wait(chan, "vm-onefor-full"); 08072 if (!res) 08073 res = vm_play_folder_name(chan, vms->vmbox); 08074 res = ast_play_and_wait(chan, "vm-opts-full"); 08075 } 08076 /* Logic: 08077 * If the current message is not the first OR 08078 * if we're listening to the first new message and there are 08079 * also urgent messages, then prompt for navigation to the 08080 * previous message 08081 */ 08082 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 08083 res = ast_play_and_wait(chan, "vm-prev"); 08084 } 08085 if (!res && !skipadvanced) 08086 res = ast_play_and_wait(chan, "vm-advopts"); 08087 if (!res) 08088 res = ast_play_and_wait(chan, "vm-repeat"); 08089 /* Logic: 08090 * If we're not listening to the last message OR 08091 * we're listening to the last urgent message and there are 08092 * also new non-urgent messages, then prompt for navigation 08093 * to the next message 08094 */ 08095 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 08096 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 08097 res = ast_play_and_wait(chan, "vm-next"); 08098 } 08099 if (!res) { 08100 if (!vms->deleted[vms->curmsg]) 08101 res = ast_play_and_wait(chan, "vm-delete"); 08102 else 08103 res = ast_play_and_wait(chan, "vm-undelete"); 08104 if (!res) 08105 res = ast_play_and_wait(chan, "vm-toforward"); 08106 if (!res) 08107 res = ast_play_and_wait(chan, "vm-savemessage"); 08108 } 08109 } 08110 if (!res) { 08111 if (skipadvanced) 08112 res = ast_play_and_wait(chan, "vm-helpexit-full"); 08113 else 08114 res = ast_play_and_wait(chan, "vm-helpexit"); 08115 } 08116 if (!res) 08117 res = ast_waitfordigit(chan, 6000); 08118 if (!res) { 08119 vms->repeats++; 08120 if (vms->repeats > 2) { 08121 res = 't'; 08122 } 08123 } 08124 } 08125 return res; 08126 }
static int vm_instructions_tw | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms, | |||
int | skipadvanced, | |||
int | in_urgent | |||
) | [static] |
Definition at line 8128 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().
08129 { 08130 int res = 0; 08131 /* Play instructions and wait for new command */ 08132 while (!res) { 08133 if (vms->lastmsg > -1) { 08134 res = ast_play_and_wait(chan, "vm-listen"); 08135 if (!res) 08136 res = vm_play_folder_name(chan, vms->vmbox); 08137 if (!res) 08138 res = ast_play_and_wait(chan, "press"); 08139 if (!res) 08140 res = ast_play_and_wait(chan, "digits/1"); 08141 } 08142 if (!res) 08143 res = ast_play_and_wait(chan, "vm-opts"); 08144 if (!res) { 08145 vms->starting = 0; 08146 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08147 } 08148 } 08149 return res; 08150 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7996 of file app_voicemail.c.
References ast_fileexists(), ast_play_and_wait(), ast_test_flag, chan, ast_vm_user::context, DISPOSE, ast_channel::language, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cz(), 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_tw(), and VM_TEMPGREETWARN.
Referenced by vm_execmain().
07997 { 07998 char prefile[256]; 07999 08000 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08001 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08002 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08003 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08004 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08005 ast_play_and_wait(chan, "vm-tempgreetactive"); 08006 } 08007 DISPOSE(prefile, -1); 08008 } 08009 08010 /* Play voicemail intro - syntax is different for different languages */ 08011 if (!strcasecmp(chan->language, "de")) { /* GERMAN syntax */ 08012 return vm_intro_de(chan, vms); 08013 } else if (!strcasecmp(chan->language, "es")) { /* SPANISH syntax */ 08014 return vm_intro_es(chan, vms); 08015 } else if (!strcasecmp(chan->language, "it")) { /* ITALIAN syntax */ 08016 return vm_intro_it(chan, vms); 08017 } else if (!strcasecmp(chan->language, "fr")) { /* FRENCH syntax */ 08018 return vm_intro_fr(chan, vms); 08019 } else if (!strcasecmp(chan->language, "nl")) { /* DUTCH syntax */ 08020 return vm_intro_nl(chan, vms); 08021 } else if (!strcasecmp(chan->language, "pt")) { /* PORTUGUESE syntax */ 08022 return vm_intro_pt(chan, vms); 08023 } else if (!strcasecmp(chan->language, "pt_BR")) { /* BRAZILIAN PORTUGUESE syntax */ 08024 return vm_intro_pt_BR(chan, vms); 08025 } else if (!strcasecmp(chan->language, "cz")) { /* CZECH syntax */ 08026 return vm_intro_cz(chan, vms); 08027 } else if (!strcasecmp(chan->language, "gr")) { /* GREEK syntax */ 08028 return vm_intro_gr(chan, vms); 08029 } else if (!strcasecmp(chan->language, "pl")) { /* POLISH syntax */ 08030 return vm_intro_pl(chan, vms); 08031 } else if (!strcasecmp(chan->language, "se")) { /* SWEDISH syntax */ 08032 return vm_intro_se(chan, vms); 08033 } else if (!strcasecmp(chan->language, "no")) { /* NORWEGIAN syntax */ 08034 return vm_intro_no(chan, vms); 08035 } else if (!strcasecmp(chan->language, "ru")) { /* RUSSIAN syntax */ 08036 return vm_intro_multilang(chan, vms, "n"); 08037 } else if (!strcasecmp(chan->language, "tw")) { /* CHINESE (Taiwan) syntax */ 08038 return vm_intro_tw(chan, vms); 08039 } else if (!strcasecmp(chan->language, "ua")) { /* UKRAINIAN syntax */ 08040 return vm_intro_multilang(chan, vms, "n"); 08041 } else if (!strcasecmp(chan->language, "he")) { /* HEBREW syntax */ 08042 return vm_intro_he(chan, vms); 08043 } else { /* Default to ENGLISH */ 08044 return vm_intro_en(chan, vms); 08045 } 08046 }
static int vm_intro_cz | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7897 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().
07898 { 07899 int res; 07900 res = ast_play_and_wait(chan, "vm-youhave"); 07901 if (!res) { 07902 if (vms->newmessages) { 07903 if (vms->newmessages == 1) { 07904 res = ast_play_and_wait(chan, "digits/jednu"); 07905 } else { 07906 res = say_and_wait(chan, vms->newmessages, chan->language); 07907 } 07908 if (!res) { 07909 if ((vms->newmessages == 1)) 07910 res = ast_play_and_wait(chan, "vm-novou"); 07911 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 07912 res = ast_play_and_wait(chan, "vm-nove"); 07913 if (vms->newmessages > 4) 07914 res = ast_play_and_wait(chan, "vm-novych"); 07915 } 07916 if (vms->oldmessages && !res) 07917 res = ast_play_and_wait(chan, "vm-and"); 07918 else if (!res) { 07919 if ((vms->newmessages == 1)) 07920 res = ast_play_and_wait(chan, "vm-zpravu"); 07921 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 07922 res = ast_play_and_wait(chan, "vm-zpravy"); 07923 if (vms->newmessages > 4) 07924 res = ast_play_and_wait(chan, "vm-zprav"); 07925 } 07926 } 07927 if (!res && vms->oldmessages) { 07928 res = say_and_wait(chan, vms->oldmessages, chan->language); 07929 if (!res) { 07930 if ((vms->oldmessages == 1)) 07931 res = ast_play_and_wait(chan, "vm-starou"); 07932 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 07933 res = ast_play_and_wait(chan, "vm-stare"); 07934 if (vms->oldmessages > 4) 07935 res = ast_play_and_wait(chan, "vm-starych"); 07936 } 07937 if (!res) { 07938 if ((vms->oldmessages == 1)) 07939 res = ast_play_and_wait(chan, "vm-zpravu"); 07940 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 07941 res = ast_play_and_wait(chan, "vm-zpravy"); 07942 if (vms->oldmessages > 4) 07943 res = ast_play_and_wait(chan, "vm-zprav"); 07944 } 07945 } 07946 if (!res) { 07947 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07948 res = ast_play_and_wait(chan, "vm-no"); 07949 if (!res) 07950 res = ast_play_and_wait(chan, "vm-zpravy"); 07951 } 07952 } 07953 } 07954 return res; 07955 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7593 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().
07594 { 07595 /* Introduce messages they have */ 07596 int res; 07597 res = ast_play_and_wait(chan, "vm-youhave"); 07598 if (!res) { 07599 if (vms->newmessages) { 07600 if ((vms->newmessages == 1)) 07601 res = ast_play_and_wait(chan, "digits/1F"); 07602 else 07603 res = say_and_wait(chan, vms->newmessages, chan->language); 07604 if (!res) 07605 res = ast_play_and_wait(chan, "vm-INBOX"); 07606 if (vms->oldmessages && !res) 07607 res = ast_play_and_wait(chan, "vm-and"); 07608 else if (!res) { 07609 if ((vms->newmessages == 1)) 07610 res = ast_play_and_wait(chan, "vm-message"); 07611 else 07612 res = ast_play_and_wait(chan, "vm-messages"); 07613 } 07614 07615 } 07616 if (!res && vms->oldmessages) { 07617 if (vms->oldmessages == 1) 07618 res = ast_play_and_wait(chan, "digits/1F"); 07619 else 07620 res = say_and_wait(chan, vms->oldmessages, chan->language); 07621 if (!res) 07622 res = ast_play_and_wait(chan, "vm-Old"); 07623 if (!res) { 07624 if (vms->oldmessages == 1) 07625 res = ast_play_and_wait(chan, "vm-message"); 07626 else 07627 res = ast_play_and_wait(chan, "vm-messages"); 07628 } 07629 } 07630 if (!res) { 07631 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07632 res = ast_play_and_wait(chan, "vm-no"); 07633 if (!res) 07634 res = ast_play_and_wait(chan, "vm-messages"); 07635 } 07636 } 07637 } 07638 return res; 07639 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7342 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().
07343 { 07344 int res; 07345 07346 /* Introduce messages they have */ 07347 res = ast_play_and_wait(chan, "vm-youhave"); 07348 if (!res) { 07349 if (vms->urgentmessages) { 07350 res = say_and_wait(chan, vms->urgentmessages, chan->language); 07351 if (!res) 07352 res = ast_play_and_wait(chan, "vm-Urgent"); 07353 if ((vms->oldmessages || vms->newmessages) && !res) { 07354 res = ast_play_and_wait(chan, "vm-and"); 07355 } else if (!res) { 07356 if ((vms->urgentmessages == 1)) 07357 res = ast_play_and_wait(chan, "vm-message"); 07358 else 07359 res = ast_play_and_wait(chan, "vm-messages"); 07360 } 07361 } 07362 if (vms->newmessages) { 07363 res = say_and_wait(chan, vms->newmessages, chan->language); 07364 if (!res) 07365 res = ast_play_and_wait(chan, "vm-INBOX"); 07366 if (vms->oldmessages && !res) 07367 res = ast_play_and_wait(chan, "vm-and"); 07368 else if (!res) { 07369 if ((vms->newmessages == 1)) 07370 res = ast_play_and_wait(chan, "vm-message"); 07371 else 07372 res = ast_play_and_wait(chan, "vm-messages"); 07373 } 07374 07375 } 07376 if (!res && vms->oldmessages) { 07377 res = say_and_wait(chan, vms->oldmessages, chan->language); 07378 if (!res) 07379 res = ast_play_and_wait(chan, "vm-Old"); 07380 if (!res) { 07381 if (vms->oldmessages == 1) 07382 res = ast_play_and_wait(chan, "vm-message"); 07383 else 07384 res = ast_play_and_wait(chan, "vm-messages"); 07385 } 07386 } 07387 if (!res) { 07388 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 07389 res = ast_play_and_wait(chan, "vm-no"); 07390 if (!res) 07391 res = ast_play_and_wait(chan, "vm-messages"); 07392 } 07393 } 07394 } 07395 return res; 07396 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7642 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().
07643 { 07644 /* Introduce messages they have */ 07645 int res; 07646 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07647 res = ast_play_and_wait(chan, "vm-youhaveno"); 07648 if (!res) 07649 res = ast_play_and_wait(chan, "vm-messages"); 07650 } else { 07651 res = ast_play_and_wait(chan, "vm-youhave"); 07652 } 07653 if (!res) { 07654 if (vms->newmessages) { 07655 if (!res) { 07656 if ((vms->newmessages == 1)) { 07657 res = ast_play_and_wait(chan, "digits/1M"); 07658 if (!res) 07659 res = ast_play_and_wait(chan, "vm-message"); 07660 if (!res) 07661 res = ast_play_and_wait(chan, "vm-INBOXs"); 07662 } else { 07663 res = say_and_wait(chan, vms->newmessages, chan->language); 07664 if (!res) 07665 res = ast_play_and_wait(chan, "vm-messages"); 07666 if (!res) 07667 res = ast_play_and_wait(chan, "vm-INBOX"); 07668 } 07669 } 07670 if (vms->oldmessages && !res) 07671 res = ast_play_and_wait(chan, "vm-and"); 07672 } 07673 if (vms->oldmessages) { 07674 if (!res) { 07675 if (vms->oldmessages == 1) { 07676 res = ast_play_and_wait(chan, "digits/1M"); 07677 if (!res) 07678 res = ast_play_and_wait(chan, "vm-message"); 07679 if (!res) 07680 res = ast_play_and_wait(chan, "vm-Olds"); 07681 } else { 07682 res = say_and_wait(chan, vms->oldmessages, chan->language); 07683 if (!res) 07684 res = ast_play_and_wait(chan, "vm-messages"); 07685 if (!res) 07686 res = ast_play_and_wait(chan, "vm-Old"); 07687 } 07688 } 07689 } 07690 } 07691 return res; 07692 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7740 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().
07741 { 07742 /* Introduce messages they have */ 07743 int res; 07744 res = ast_play_and_wait(chan, "vm-youhave"); 07745 if (!res) { 07746 if (vms->newmessages) { 07747 res = say_and_wait(chan, vms->newmessages, chan->language); 07748 if (!res) 07749 res = ast_play_and_wait(chan, "vm-INBOX"); 07750 if (vms->oldmessages && !res) 07751 res = ast_play_and_wait(chan, "vm-and"); 07752 else if (!res) { 07753 if ((vms->newmessages == 1)) 07754 res = ast_play_and_wait(chan, "vm-message"); 07755 else 07756 res = ast_play_and_wait(chan, "vm-messages"); 07757 } 07758 07759 } 07760 if (!res && vms->oldmessages) { 07761 res = say_and_wait(chan, vms->oldmessages, chan->language); 07762 if (!res) 07763 res = ast_play_and_wait(chan, "vm-Old"); 07764 if (!res) { 07765 if (vms->oldmessages == 1) 07766 res = ast_play_and_wait(chan, "vm-message"); 07767 else 07768 res = ast_play_and_wait(chan, "vm-messages"); 07769 } 07770 } 07771 if (!res) { 07772 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07773 res = ast_play_and_wait(chan, "vm-no"); 07774 if (!res) 07775 res = ast_play_and_wait(chan, "vm-messages"); 07776 } 07777 } 07778 } 07779 return res; 07780 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7141 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().
07142 { 07143 int res = 0; 07144 07145 if (vms->newmessages) { 07146 res = ast_play_and_wait(chan, "vm-youhave"); 07147 if (!res) 07148 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 07149 if (!res) { 07150 if ((vms->newmessages == 1)) { 07151 res = ast_play_and_wait(chan, "vm-INBOX"); 07152 if (!res) 07153 res = ast_play_and_wait(chan, "vm-message"); 07154 } else { 07155 res = ast_play_and_wait(chan, "vm-INBOXs"); 07156 if (!res) 07157 res = ast_play_and_wait(chan, "vm-messages"); 07158 } 07159 } 07160 } else if (vms->oldmessages){ 07161 res = ast_play_and_wait(chan, "vm-youhave"); 07162 if (!res) 07163 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 07164 if ((vms->oldmessages == 1)){ 07165 res = ast_play_and_wait(chan, "vm-Old"); 07166 if (!res) 07167 res = ast_play_and_wait(chan, "vm-message"); 07168 } else { 07169 res = ast_play_and_wait(chan, "vm-Olds"); 07170 if (!res) 07171 res = ast_play_and_wait(chan, "vm-messages"); 07172 } 07173 } else if (!vms->oldmessages && !vms->newmessages) 07174 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 07175 return res; 07176 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7275 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().
07276 { 07277 int res = 0; 07278 07279 /* Introduce messages they have */ 07280 if (!res) { 07281 if ((vms->newmessages) || (vms->oldmessages)) { 07282 res = ast_play_and_wait(chan, "vm-youhave"); 07283 } 07284 /* 07285 * The word "shtei" refers to the number 2 in hebrew when performing a count 07286 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 07287 * an element, this is one of them. 07288 */ 07289 if (vms->newmessages) { 07290 if (!res) { 07291 if (vms->newmessages == 1) { 07292 res = ast_play_and_wait(chan, "vm-INBOX1"); 07293 } else { 07294 if (vms->newmessages == 2) { 07295 res = ast_play_and_wait(chan, "vm-shtei"); 07296 } else { 07297 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07298 } 07299 res = ast_play_and_wait(chan, "vm-INBOX"); 07300 } 07301 } 07302 if (vms->oldmessages && !res) { 07303 res = ast_play_and_wait(chan, "vm-and"); 07304 if (vms->oldmessages == 1) { 07305 res = ast_play_and_wait(chan, "vm-Old1"); 07306 } else { 07307 if (vms->oldmessages == 2) { 07308 res = ast_play_and_wait(chan, "vm-shtei"); 07309 } else { 07310 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07311 } 07312 res = ast_play_and_wait(chan, "vm-Old"); 07313 } 07314 } 07315 } 07316 if (!res && vms->oldmessages && !vms->newmessages) { 07317 if (!res) { 07318 if (vms->oldmessages == 1) { 07319 res = ast_play_and_wait(chan, "vm-Old1"); 07320 } else { 07321 if (vms->oldmessages == 2) { 07322 res = ast_play_and_wait(chan, "vm-shtei"); 07323 } else { 07324 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07325 } 07326 res = ast_play_and_wait(chan, "vm-Old"); 07327 } 07328 } 07329 } 07330 if (!res) { 07331 if (!vms->oldmessages && !vms->newmessages) { 07332 if (!res) { 07333 res = ast_play_and_wait(chan, "vm-nomessages"); 07334 } 07335 } 07336 } 07337 } 07338 return res; 07339 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7399 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().
07400 { 07401 /* Introduce messages they have */ 07402 int res; 07403 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 07404 res = ast_play_and_wait(chan, "vm-no") || 07405 ast_play_and_wait(chan, "vm-message"); 07406 else 07407 res = ast_play_and_wait(chan, "vm-youhave"); 07408 if (!res && vms->newmessages) { 07409 res = (vms->newmessages == 1) ? 07410 ast_play_and_wait(chan, "digits/un") || 07411 ast_play_and_wait(chan, "vm-nuovo") || 07412 ast_play_and_wait(chan, "vm-message") : 07413 /* 2 or more new messages */ 07414 say_and_wait(chan, vms->newmessages, chan->language) || 07415 ast_play_and_wait(chan, "vm-nuovi") || 07416 ast_play_and_wait(chan, "vm-messages"); 07417 if (!res && vms->oldmessages) 07418 res = ast_play_and_wait(chan, "vm-and"); 07419 } 07420 if (!res && vms->oldmessages) { 07421 res = (vms->oldmessages == 1) ? 07422 ast_play_and_wait(chan, "digits/un") || 07423 ast_play_and_wait(chan, "vm-vecchio") || 07424 ast_play_and_wait(chan, "vm-message") : 07425 /* 2 or more old messages */ 07426 say_and_wait(chan, vms->oldmessages, chan->language) || 07427 ast_play_and_wait(chan, "vm-vecchi") || 07428 ast_play_and_wait(chan, "vm-messages"); 07429 } 07430 return res; 07431 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 7235 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().
07236 { 07237 int res; 07238 int lastnum = 0; 07239 07240 res = ast_play_and_wait(chan, "vm-youhave"); 07241 07242 if (!res && vms->newmessages) { 07243 lastnum = vms->newmessages; 07244 07245 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 07246 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 07247 } 07248 07249 if (!res && vms->oldmessages) { 07250 res = ast_play_and_wait(chan, "vm-and"); 07251 } 07252 } 07253 07254 if (!res && vms->oldmessages) { 07255 lastnum = vms->oldmessages; 07256 07257 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 07258 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 07259 } 07260 } 07261 07262 if (!res) { 07263 if (lastnum == 0) { 07264 res = ast_play_and_wait(chan, "vm-no"); 07265 } 07266 if (!res) { 07267 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 07268 } 07269 } 07270 07271 return res; 07272 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7783 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().
07784 { 07785 /* Introduce messages they have */ 07786 int res; 07787 res = ast_play_and_wait(chan, "vm-youhave"); 07788 if (!res) { 07789 if (vms->newmessages) { 07790 res = say_and_wait(chan, vms->newmessages, chan->language); 07791 if (!res) { 07792 if (vms->newmessages == 1) 07793 res = ast_play_and_wait(chan, "vm-INBOXs"); 07794 else 07795 res = ast_play_and_wait(chan, "vm-INBOX"); 07796 } 07797 if (vms->oldmessages && !res) 07798 res = ast_play_and_wait(chan, "vm-and"); 07799 else if (!res) { 07800 if ((vms->newmessages == 1)) 07801 res = ast_play_and_wait(chan, "vm-message"); 07802 else 07803 res = ast_play_and_wait(chan, "vm-messages"); 07804 } 07805 07806 } 07807 if (!res && vms->oldmessages) { 07808 res = say_and_wait(chan, vms->oldmessages, chan->language); 07809 if (!res) { 07810 if (vms->oldmessages == 1) 07811 res = ast_play_and_wait(chan, "vm-Olds"); 07812 else 07813 res = ast_play_and_wait(chan, "vm-Old"); 07814 } 07815 if (!res) { 07816 if (vms->oldmessages == 1) 07817 res = ast_play_and_wait(chan, "vm-message"); 07818 else 07819 res = ast_play_and_wait(chan, "vm-messages"); 07820 } 07821 } 07822 if (!res) { 07823 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07824 res = ast_play_and_wait(chan, "vm-no"); 07825 if (!res) 07826 res = ast_play_and_wait(chan, "vm-messages"); 07827 } 07828 } 07829 } 07830 return res; 07831 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7549 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().
07550 { 07551 /* Introduce messages they have */ 07552 int res; 07553 07554 res = ast_play_and_wait(chan, "vm-youhave"); 07555 if (res) 07556 return res; 07557 07558 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07559 res = ast_play_and_wait(chan, "vm-no"); 07560 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07561 return res; 07562 } 07563 07564 if (vms->newmessages) { 07565 if ((vms->newmessages == 1)) { 07566 res = ast_play_and_wait(chan, "digits/1"); 07567 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 07568 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07569 } else { 07570 res = say_and_wait(chan, vms->newmessages, chan->language); 07571 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 07572 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07573 } 07574 if (!res && vms->oldmessages) 07575 res = ast_play_and_wait(chan, "vm-and"); 07576 } 07577 if (!res && vms->oldmessages) { 07578 if (vms->oldmessages == 1) { 07579 res = ast_play_and_wait(chan, "digits/1"); 07580 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 07581 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07582 } else { 07583 res = say_and_wait(chan, vms->oldmessages, chan->language); 07584 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 07585 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07586 } 07587 } 07588 07589 return res; 07590 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7434 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().
07435 { 07436 /* Introduce messages they have */ 07437 int res; 07438 div_t num; 07439 07440 if (!vms->oldmessages && !vms->newmessages) { 07441 res = ast_play_and_wait(chan, "vm-no"); 07442 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07443 return res; 07444 } else { 07445 res = ast_play_and_wait(chan, "vm-youhave"); 07446 } 07447 07448 if (vms->newmessages) { 07449 num = div(vms->newmessages, 10); 07450 if (vms->newmessages == 1) { 07451 res = ast_play_and_wait(chan, "digits/1-a"); 07452 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 07453 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07454 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07455 if (num.rem == 2) { 07456 if (!num.quot) { 07457 res = ast_play_and_wait(chan, "digits/2-ie"); 07458 } else { 07459 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 07460 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07461 } 07462 } else { 07463 res = say_and_wait(chan, vms->newmessages, chan->language); 07464 } 07465 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 07466 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07467 } else { 07468 res = say_and_wait(chan, vms->newmessages, chan->language); 07469 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 07470 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07471 } 07472 if (!res && vms->oldmessages) 07473 res = ast_play_and_wait(chan, "vm-and"); 07474 } 07475 if (!res && vms->oldmessages) { 07476 num = div(vms->oldmessages, 10); 07477 if (vms->oldmessages == 1) { 07478 res = ast_play_and_wait(chan, "digits/1-a"); 07479 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 07480 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07481 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07482 if (num.rem == 2) { 07483 if (!num.quot) { 07484 res = ast_play_and_wait(chan, "digits/2-ie"); 07485 } else { 07486 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 07487 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07488 } 07489 } else { 07490 res = say_and_wait(chan, vms->oldmessages, chan->language); 07491 } 07492 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 07493 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07494 } else { 07495 res = say_and_wait(chan, vms->oldmessages, chan->language); 07496 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 07497 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07498 } 07499 } 07500 07501 return res; 07502 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7834 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().
07835 { 07836 /* Introduce messages they have */ 07837 int res; 07838 res = ast_play_and_wait(chan, "vm-youhave"); 07839 if (!res) { 07840 if (vms->newmessages) { 07841 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07842 if (!res) { 07843 if ((vms->newmessages == 1)) { 07844 res = ast_play_and_wait(chan, "vm-message"); 07845 if (!res) 07846 res = ast_play_and_wait(chan, "vm-INBOXs"); 07847 } else { 07848 res = ast_play_and_wait(chan, "vm-messages"); 07849 if (!res) 07850 res = ast_play_and_wait(chan, "vm-INBOX"); 07851 } 07852 } 07853 if (vms->oldmessages && !res) 07854 res = ast_play_and_wait(chan, "vm-and"); 07855 } 07856 if (!res && vms->oldmessages) { 07857 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07858 if (!res) { 07859 if (vms->oldmessages == 1) { 07860 res = ast_play_and_wait(chan, "vm-message"); 07861 if (!res) 07862 res = ast_play_and_wait(chan, "vm-Olds"); 07863 } else { 07864 res = ast_play_and_wait(chan, "vm-messages"); 07865 if (!res) 07866 res = ast_play_and_wait(chan, "vm-Old"); 07867 } 07868 } 07869 } 07870 if (!res) { 07871 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07872 res = ast_play_and_wait(chan, "vm-no"); 07873 if (!res) 07874 res = ast_play_and_wait(chan, "vm-messages"); 07875 } 07876 } 07877 } 07878 return res; 07879 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7695 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().
07695 { 07696 /* Introduce messages they have */ 07697 int res; 07698 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07699 res = ast_play_and_wait(chan, "vm-nomessages"); 07700 return res; 07701 } else { 07702 res = ast_play_and_wait(chan, "vm-youhave"); 07703 } 07704 if (vms->newmessages) { 07705 if (!res) 07706 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 07707 if ((vms->newmessages == 1)) { 07708 if (!res) 07709 res = ast_play_and_wait(chan, "vm-message"); 07710 if (!res) 07711 res = ast_play_and_wait(chan, "vm-INBOXs"); 07712 } else { 07713 if (!res) 07714 res = ast_play_and_wait(chan, "vm-messages"); 07715 if (!res) 07716 res = ast_play_and_wait(chan, "vm-INBOX"); 07717 } 07718 if (vms->oldmessages && !res) 07719 res = ast_play_and_wait(chan, "vm-and"); 07720 } 07721 if (vms->oldmessages) { 07722 if (!res) 07723 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 07724 if (vms->oldmessages == 1) { 07725 if (!res) 07726 res = ast_play_and_wait(chan, "vm-message"); 07727 if (!res) 07728 res = ast_play_and_wait(chan, "vm-Olds"); 07729 } else { 07730 if (!res) 07731 res = ast_play_and_wait(chan, "vm-messages"); 07732 if (!res) 07733 res = ast_play_and_wait(chan, "vm-Old"); 07734 } 07735 } 07736 return res; 07737 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7505 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().
07506 { 07507 /* Introduce messages they have */ 07508 int res; 07509 07510 res = ast_play_and_wait(chan, "vm-youhave"); 07511 if (res) 07512 return res; 07513 07514 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 07515 res = ast_play_and_wait(chan, "vm-no"); 07516 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07517 return res; 07518 } 07519 07520 if (vms->newmessages) { 07521 if ((vms->newmessages == 1)) { 07522 res = ast_play_and_wait(chan, "digits/ett"); 07523 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 07524 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07525 } else { 07526 res = say_and_wait(chan, vms->newmessages, chan->language); 07527 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 07528 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07529 } 07530 if (!res && vms->oldmessages) 07531 res = ast_play_and_wait(chan, "vm-and"); 07532 } 07533 if (!res && vms->oldmessages) { 07534 if (vms->oldmessages == 1) { 07535 res = ast_play_and_wait(chan, "digits/ett"); 07536 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 07537 res = res ? res : ast_play_and_wait(chan, "vm-message"); 07538 } else { 07539 res = say_and_wait(chan, vms->oldmessages, chan->language); 07540 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 07541 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 07542 } 07543 } 07544 07545 return res; 07546 }
static int vm_intro_tw | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7958 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().
07959 { 07960 int res; 07961 /* Introduce messages they have */ 07962 res = ast_play_and_wait(chan, "vm-you"); 07963 07964 if (!res && vms->newmessages) { 07965 res = ast_play_and_wait(chan, "vm-have"); 07966 if (!res) 07967 res = say_and_wait(chan, vms->newmessages, chan->language); 07968 if (!res) 07969 res = ast_play_and_wait(chan, "vm-tong"); 07970 if (!res) 07971 res = ast_play_and_wait(chan, "vm-INBOX"); 07972 if (vms->oldmessages && !res) 07973 res = ast_play_and_wait(chan, "vm-and"); 07974 else if (!res) 07975 res = ast_play_and_wait(chan, "vm-messages"); 07976 } 07977 if (!res && vms->oldmessages) { 07978 res = ast_play_and_wait(chan, "vm-have"); 07979 if (!res) 07980 res = say_and_wait(chan, vms->oldmessages, chan->language); 07981 if (!res) 07982 res = ast_play_and_wait(chan, "vm-tong"); 07983 if (!res) 07984 res = ast_play_and_wait(chan, "vm-Old"); 07985 if (!res) 07986 res = ast_play_and_wait(chan, "vm-messages"); 07987 } 07988 if (!res && !vms->oldmessages && !vms->newmessages) { 07989 res = ast_play_and_wait(chan, "vm-haveno"); 07990 if (!res) 07991 res = ast_play_and_wait(chan, "vm-messages"); 07992 } 07993 return res; 07994 }
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 2715 of file app_voicemail.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
02716 { 02717 switch (ast_lock_path(path)) { 02718 case AST_LOCK_TIMEOUT: 02719 return -1; 02720 default: 02721 return 0; 02722 } 02723 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1265 of file app_voicemail.c.
References VOICEMAIL_FILE_MODE.
Referenced by sendmail(), and sendpage().
01266 { 01267 FILE *p = NULL; 01268 int pfd = mkstemp(template); 01269 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01270 if (pfd > -1) { 01271 p = fdopen(pfd, "w+"); 01272 if (!p) { 01273 close(pfd); 01274 pfd = -1; 01275 } 01276 } 01277 return p; 01278 }
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 8162 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, and vm_reenterpassword.
Referenced by vm_execmain().
08163 { 08164 int cmd = 0; 08165 int duration = 0; 08166 int tries = 0; 08167 char newpassword[80] = ""; 08168 char newpassword2[80] = ""; 08169 char prefile[PATH_MAX] = ""; 08170 unsigned char buf[256]; 08171 int bytes=0; 08172 08173 if (ast_adsi_available(chan)) { 08174 bytes += adsi_logo(buf + bytes); 08175 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 08176 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08177 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08178 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08179 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08180 } 08181 08182 /* First, have the user change their password 08183 so they won't get here again */ 08184 for (;;) { 08185 newpassword[1] = '\0'; 08186 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08187 if (cmd == '#') 08188 newpassword[0] = '\0'; 08189 if (cmd < 0 || cmd == 't' || cmd == '#') 08190 return cmd; 08191 cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#"); 08192 if (cmd < 0 || cmd == 't' || cmd == '#') 08193 return cmd; 08194 cmd = check_password(vmu, newpassword); /* perform password validation */ 08195 if (cmd != 0) { 08196 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 08197 cmd = ast_play_and_wait(chan, vm_invalid_password); 08198 } else { 08199 newpassword2[1] = '\0'; 08200 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 08201 if (cmd == '#') 08202 newpassword2[0] = '\0'; 08203 if (cmd < 0 || cmd == 't' || cmd == '#') 08204 return cmd; 08205 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 08206 if (cmd < 0 || cmd == 't' || cmd == '#') 08207 return cmd; 08208 if (!strcmp(newpassword, newpassword2)) 08209 break; 08210 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 08211 cmd = ast_play_and_wait(chan, vm_mismatch); 08212 } 08213 if (++tries == 3) 08214 return -1; 08215 } 08216 if (pwdchange & PWDCHANGE_INTERNAL) 08217 vm_change_password(vmu, newpassword); 08218 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 08219 vm_change_password_shell(vmu, newpassword); 08220 08221 ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword)); 08222 cmd = ast_play_and_wait(chan, vm_passchanged); 08223 08224 /* If forcename is set, have the user record their name */ 08225 if (ast_test_flag(vmu, VM_FORCENAME)) { 08226 snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 08227 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08228 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08229 if (cmd < 0 || cmd == 't' || cmd == '#') 08230 return cmd; 08231 } 08232 } 08233 08234 /* If forcegreetings is set, have the user record their greetings */ 08235 if (ast_test_flag(vmu, VM_FORCEGREET)) { 08236 snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 08237 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08238 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08239 if (cmd < 0 || cmd == 't' || cmd == '#') 08240 return cmd; 08241 } 08242 08243 snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 08244 if (ast_fileexists(prefile, NULL, NULL) < 1) { 08245 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08246 if (cmd < 0 || cmd == 't' || cmd == '#') 08247 return cmd; 08248 } 08249 } 08250 08251 return cmd; 08252 }
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 8254 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_reenterpassword, and vm_tempgreeting().
Referenced by vm_execmain().
08255 { 08256 int cmd = 0; 08257 int retries = 0; 08258 int duration = 0; 08259 char newpassword[80] = ""; 08260 char newpassword2[80] = ""; 08261 char prefile[PATH_MAX] = ""; 08262 unsigned char buf[256]; 08263 int bytes=0; 08264 08265 if (ast_adsi_available(chan)) { 08266 bytes += adsi_logo(buf + bytes); 08267 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 08268 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08269 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08270 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08271 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08272 } 08273 while ((cmd >= 0) && (cmd != 't')) { 08274 if (cmd) 08275 retries = 0; 08276 switch (cmd) { 08277 case '1': /* Record your unavailable message */ 08278 snprintf(prefile,sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 08279 cmd = play_record_review(chan,"vm-rec-unv",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08280 break; 08281 case '2': /* Record your busy message */ 08282 snprintf(prefile,sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 08283 cmd = play_record_review(chan,"vm-rec-busy",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08284 break; 08285 case '3': /* Record greeting */ 08286 snprintf(prefile,sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 08287 cmd = play_record_review(chan,"vm-rec-name",prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08288 break; 08289 case '4': /* manage the temporary greeting */ 08290 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 08291 break; 08292 case '5': /* change password */ 08293 if (vmu->password[0] == '-') { 08294 cmd = ast_play_and_wait(chan, "vm-no"); 08295 break; 08296 } 08297 newpassword[1] = '\0'; 08298 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 08299 if (cmd == '#') 08300 newpassword[0] = '\0'; 08301 else { 08302 if (cmd < 0) 08303 break; 08304 if ((cmd = ast_readstring(chan,newpassword + strlen(newpassword),sizeof(newpassword)-1,2000,10000,"#")) < 0) { 08305 break; 08306 } 08307 } 08308 cmd = check_password(vmu, newpassword); /* perform password validation */ 08309 if (cmd != 0) { 08310 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 08311 cmd = ast_play_and_wait(chan, vm_invalid_password); 08312 break; 08313 } 08314 newpassword2[1] = '\0'; 08315 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 08316 if (cmd == '#') 08317 newpassword2[0] = '\0'; 08318 else { 08319 if (cmd < 0) 08320 break; 08321 08322 if ((cmd = ast_readstring(chan,newpassword2 + strlen(newpassword2),sizeof(newpassword2)-1,2000,10000,"#")) < 0) { 08323 break; 08324 } 08325 } 08326 if (strcmp(newpassword, newpassword2)) { 08327 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 08328 cmd = ast_play_and_wait(chan, vm_mismatch); 08329 break; 08330 } 08331 if (pwdchange & PWDCHANGE_INTERNAL) 08332 vm_change_password(vmu, newpassword); 08333 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 08334 vm_change_password_shell(vmu, newpassword); 08335 08336 ast_debug(1,"User %s set password to %s of length %d\n",vms->username,newpassword,(int)strlen(newpassword)); 08337 cmd = ast_play_and_wait(chan, vm_passchanged); 08338 break; 08339 case '*': 08340 cmd = 't'; 08341 break; 08342 default: 08343 cmd = 0; 08344 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08345 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08346 if (ast_fileexists(prefile, NULL, NULL)) { 08347 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 08348 } 08349 DISPOSE(prefile, -1); 08350 if (!cmd) { 08351 cmd = ast_play_and_wait(chan, "vm-options"); 08352 } 08353 if (!cmd) { 08354 cmd = ast_waitfordigit(chan,6000); 08355 } 08356 if (!cmd) { 08357 retries++; 08358 } 08359 if (retries > 3) { 08360 cmd = 't'; 08361 } 08362 } 08363 } 08364 if (cmd == 't') 08365 cmd = 0; 08366 return cmd; 08367 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 7110 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_tw().
07111 { 07112 int cmd; 07113 07114 if (!strcasecmp(chan->language, "it") || !strcasecmp(chan->language, "es") || !strcasecmp(chan->language, "pt") || !strcasecmp(chan->language, "pt_BR")) { /* Italian, Spanish, French or Portuguese syntax */ 07115 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07116 return cmd ? cmd : ast_play_and_wait(chan, box); 07117 } else if (!strcasecmp(chan->language, "gr")){ 07118 return vm_play_folder_name_gr(chan, box); 07119 } else if (!strcasecmp(chan->language, "pl")){ 07120 return vm_play_folder_name_pl(chan, box); 07121 } else if (!strcasecmp(chan->language, "ua")){ /* Ukrainian syntax */ 07122 return vm_play_folder_name_ua(chan, box); 07123 } else { /* Default English */ 07124 cmd = ast_play_and_wait(chan, box); 07125 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07126 } 07127 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7063 of file app_voicemail.c.
References ast_play_and_wait(), and chan.
Referenced by vm_play_folder_name().
07064 { 07065 int cmd; 07066 char *buf; 07067 07068 buf = alloca(strlen(box)+2); 07069 strcpy(buf, box); 07070 strcat(buf,"s"); 07071 07072 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 07073 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 07074 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07075 } else { 07076 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07077 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 07078 } 07079 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7081 of file app_voicemail.c.
References ast_play_and_wait(), and chan.
Referenced by vm_play_folder_name().
07082 { 07083 int cmd; 07084 07085 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 07086 if (!strcasecmp(box, "vm-INBOX")) 07087 cmd = ast_play_and_wait(chan, "vm-new-e"); 07088 else 07089 cmd = ast_play_and_wait(chan, "vm-old-e"); 07090 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07091 } else { 07092 cmd = ast_play_and_wait(chan, "vm-messages"); 07093 return cmd ? cmd : ast_play_and_wait(chan, box); 07094 } 07095 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7097 of file app_voicemail.c.
References ast_play_and_wait(), and chan.
Referenced by vm_play_folder_name().
07098 { 07099 int cmd; 07100 07101 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 07102 cmd = ast_play_and_wait(chan, "vm-messages"); 07103 return cmd ? cmd : ast_play_and_wait(chan, box); 07104 } else { 07105 cmd = ast_play_and_wait(chan, box); 07106 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07107 } 07108 }
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 8385 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().
08386 { 08387 int cmd = 0; 08388 int retries = 0; 08389 int duration = 0; 08390 char prefile[PATH_MAX] = ""; 08391 unsigned char buf[256]; 08392 int bytes = 0; 08393 08394 if (ast_adsi_available(chan)) { 08395 bytes += adsi_logo(buf + bytes); 08396 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 08397 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 08398 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 08399 bytes += ast_adsi_voice_mode(buf + bytes, 0); 08400 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 08401 } 08402 08403 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08404 while ((cmd >= 0) && (cmd != 't')) { 08405 if (cmd) 08406 retries = 0; 08407 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08408 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 08409 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08410 cmd = 't'; 08411 } else { 08412 switch (cmd) { 08413 case '1': 08414 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 08415 break; 08416 case '2': 08417 DELETE(prefile, -1, prefile, vmu); 08418 ast_play_and_wait(chan, "vm-tempremoved"); 08419 cmd = 't'; 08420 break; 08421 case '*': 08422 cmd = 't'; 08423 break; 08424 default: 08425 cmd = ast_play_and_wait(chan, 08426 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 08427 "vm-tempgreeting2" : "vm-tempgreeting"); 08428 if (!cmd) 08429 cmd = ast_waitfordigit(chan,6000); 08430 if (!cmd) 08431 retries++; 08432 if (retries > 3) 08433 cmd = 't'; 08434 } 08435 } 08436 DISPOSE(prefile, -1); 08437 } 08438 if (cmd == 't') 08439 cmd = 0; 08440 return cmd; 08441 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 9665 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().
09666 { 09667 char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = ""; 09668 struct ast_vm_user vmus; 09669 char *options = NULL; 09670 int silent = 0, skipuser = 0; 09671 int res = -1; 09672 09673 if (s) { 09674 s = ast_strdupa(s); 09675 user = strsep(&s, ","); 09676 options = strsep(&s, ","); 09677 if (user) { 09678 s = user; 09679 user = strsep(&s, "@"); 09680 context = strsep(&s, ""); 09681 if (!ast_strlen_zero(user)) 09682 skipuser++; 09683 ast_copy_string(mailbox, user, sizeof(mailbox)); 09684 } 09685 } 09686 09687 if (options) { 09688 silent = (strchr(options, 's')) != NULL; 09689 } 09690 09691 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 09692 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 09693 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 09694 ast_play_and_wait(chan, "auth-thankyou"); 09695 res = 0; 09696 } 09697 09698 return res; 09699 }
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 3803 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().
03804 { 03805 const struct vm_zone *z = NULL; 03806 struct timeval t = ast_tvnow(); 03807 03808 /* Does this user have a timezone specified? */ 03809 if (!ast_strlen_zero(vmu->zonetag)) { 03810 /* Find the zone in the list */ 03811 AST_LIST_LOCK(&zones); 03812 AST_LIST_TRAVERSE(&zones, z, list) { 03813 if (!strcmp(z->name, vmu->zonetag)) 03814 break; 03815 } 03816 AST_LIST_UNLOCK(&zones); 03817 } 03818 ast_localtime(&t, tm, z ? z->timezone : NULL); 03819 return tm; 03820 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 6521 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.
06522 { 06523 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); 06524 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 6513 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().
06514 { 06515 int res; 06516 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 06517 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 06518 return res; 06519 }
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 11463 of file app_voicemail.c.
char* addesc = "Comedian Mail" [static] |
Definition at line 497 of file app_voicemail.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 678 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 680 of file app_voicemail.c.
Referenced by adsi_begin(), adsi_load_vmail(), and load_config().
char* app = "VoiceMail" [static] |
Definition at line 571 of file app_voicemail.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 574 of file app_voicemail.c.
char* app3 = "MailboxExists" [static] |
Definition at line 576 of file app_voicemail.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 577 of file app_voicemail.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 11463 of file app_voicemail.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 664 of file app_voicemail.c.
Referenced by load_config(), and populate_defaults().
char charset[32] = "ISO-8859-1" [static] |
Definition at line 676 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 667 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 9897 of file app_voicemail.c.
Referenced by load_module(), and unload_module().
char* descrip_vm [static] |
Definition at line 501 of file app_voicemail.c.
char* descrip_vm_box_exists [static] |
Definition at line 548 of file app_voicemail.c.
char* descrip_vmain [static] |
Definition at line 530 of file app_voicemail.c.
char* descrip_vmauthenticate [static] |
Definition at line 560 of file app_voicemail.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 663 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 670 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 681 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 665 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 477 of file app_voicemail.c.
char ext_pass_cmd[128] [static] |
Definition at line 476 of file app_voicemail.c.
char externnotify[160] [static] |
Definition at line 588 of file app_voicemail.c.
char fromstring[100] [static] |
Definition at line 674 of file app_voicemail.c.
Referenced by load_config(), make_email_file(), and sendpage().
struct ast_flags globalflags = {0} [static] |
Definition at line 659 of file app_voicemail.c.
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 587 of file app_voicemail.c.
int maxdeletedmsg [static] |
Definition at line 584 of file app_voicemail.c.
int maxgreet [static] |
Definition at line 594 of file app_voicemail.c.
int maxlogins [static] |
Definition at line 596 of file app_voicemail.c.
int maxmsg [static] |
Definition at line 583 of file app_voicemail.c.
int maxsilence [static] |
int minpassword [static] |
Definition at line 597 of file app_voicemail.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 614 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 640 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 616 of file app_voicemail.c.
Referenced by start_poll_thread(), and stop_poll_thread().
int my_umask [static] |
Definition at line 479 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 609 of file app_voicemail.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 604 of file app_voicemail.c.
ast_mutex_t poll_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 608 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 601 of file app_voicemail.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 610 of file app_voicemail.c.
unsigned char poll_thread_run [static] |
Definition at line 611 of file app_voicemail.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 483 of file app_voicemail.c.
int saydurationminfo [static] |
Definition at line 661 of file app_voicemail.c.
Referenced by load_config(), and populate_defaults().
char serveremail[80] [static] |
Definition at line 586 of file app_voicemail.c.
int silencethreshold = 128 [static] |
Definition at line 585 of file app_voicemail.c.
int skipms [static] |
Definition at line 595 of file app_voicemail.c.
Referenced by controlplayback_exec(), and handle_controlstreamfile().
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 589 of file app_voicemail.c.
Referenced by load_config(), and run_externnotify().
char* synopsis_vm = "Leave a Voicemail message" [static] |
Definition at line 499 of file app_voicemail.c.
char* synopsis_vm_box_exists [static] |
Initial value:
"Check to see if Voicemail mailbox exists"
Definition at line 545 of file app_voicemail.c.
char* synopsis_vmain = "Check Voicemail messages" [static] |
Definition at line 528 of file app_voicemail.c.
char* synopsis_vmauthenticate = "Authenticate with Voicemail passwords" [static] |
Definition at line 558 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 657 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 656 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 653 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 654 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char vm_password[80] = "vm-password" [static] |
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 655 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 474 of file app_voicemail.c.
char vmfmts[80] [static] |
Definition at line 590 of file app_voicemail.c.
int vmmaxsecs [static] |
Definition at line 593 of file app_voicemail.c.
int vmminsecs [static] |
Definition at line 592 of file app_voicemail.c.
double volgain [static] |
Definition at line 591 of file app_voicemail.c.
char zonetag[80] [static] |