#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"

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_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 | ERROR_MAILBOX_FULL -200 |
| #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 | 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) |
| #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_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 | 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) } |
| enum | { OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3 } |
Functions | |
| static void | __fini_mwi_subs (void) |
| static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
| static void | __init_mwi_subs (void) |
| 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 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) |
| static int | append_mailbox (const char *context, const char *mbox, const char *data) |
| static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
| static void | apply_options (struct ast_vm_user *vmu, const char *options) |
| static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
| static int | base_encode (char *filename, FILE *so) |
| static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
| 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 | 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) |
| 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) |
| static void | copy_plain_file (char *frompath, char *topath) |
| static int | count_messages (struct ast_vm_user *vmu, char *dir) |
| 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 *mbox) |
| static struct ast_vm_user * | find_user (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
| static struct ast_vm_user * | find_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox) |
| static int | forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int flag, signed char record_gain) |
| 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) |
| 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) |
| 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) |
| static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
| static int | inbuf (struct baseio *bio, FILE *fi) |
| static int | inchar (struct baseio *bio, FILE *fi) |
| static int | invent_message (struct ast_channel *chan, struct ast_vm_user *vmu, char *ext, int busy, char *ecodes) |
| static int | is_valid_dtmf (const char *key) |
| static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
| A negative return value indicates an error. | |
| static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
| 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) |
| 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 *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap) |
| 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) |
| static int | ochar (struct baseio *bio, int c, FILE *so) |
| static int | open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box) |
| static int | play_greeting (struct ast_channel *chan, struct ast_vm_user *vmu, char *filename, char *ecodes) |
| 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) |
| static void | poll_subscribed_mailboxes (void) |
| static void | populate_defaults (struct ast_vm_user *vmu) |
| 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) |
| static void | queue_mwi_event (const char *mbox, int new, int old) |
| static char * | quote (const char *from, char *to, size_t len) |
| static int | reload (void) |
| static void | rename_file (char *sfn, char *dfn) |
| static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir) |
| static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
| static void | run_externnotify (char *context, char *extension) |
| 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 | sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category) |
| 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) |
| 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 maxlogins, 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) |
| static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| static int | vm_browse_messages_gr (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) |
| static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
| static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
| 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 *vmfmts, char *context, signed char record_gain, long *duration, struct vm_state *vms) |
| static int | vm_instructions (struct ast_channel *chan, struct vm_state *vms, int skipadvanced) |
| static int | vm_instructions_en (struct ast_channel *chan, struct vm_state *vms, int skipadvanced) |
| static int | vm_instructions_zh (struct ast_channel *chan, struct vm_state *vms, int skipadvanced) |
| 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_it (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
| static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_lock_path (const char *path) |
| Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
| static FILE * | vm_mkftemp (char *template) |
| static int | vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
| static int | vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
| static int | vm_play_folder_name (struct ast_channel *chan, char *mbox) |
| static int | vm_play_folder_name_gr (struct ast_channel *chan, char *mbox) |
| static int | vm_play_folder_name_pl (struct ast_channel *chan, char *mbox) |
| static int | vm_play_folder_name_ua (struct ast_channel *chan, char *mbox) |
| static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
| 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 = AST_BUILDOPT_SUM, .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 const 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_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 struct ast_event_sub * | mwi_sub_sub |
| 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_MUTEX_INITIALIZER ) |
| 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 },} |
| enum { ... } | vm_box |
| static char | vm_mismatch [80] = "vm-mismatch" |
| static char | vm_newpassword [80] = "vm-newpassword" |
| enum { ... } | vm_option_args |
| enum { ... } | vm_option_flags |
| static char | vm_passchanged [80] = "vm-passchanged" |
| static char | vm_password [80] = "vm-password" |
| static char | vm_pls_try_again [80] = "vm-pls-try-again" |
| static char | vm_reenterpassword [80] = "vm-reenterpassword" |
| static char | VM_SPOOL_DIR [PATH_MAX] |
| static char | vmfmts [80] |
| static int | vmmaxsecs |
| static int | vmminsecs |
| static double | volgain |
| static char | zonetag [80] |
This module requires res_adsi to load. This needs to be optional during compilation.
This file is now almost impossible to work with, due to all #ifdefs. Feels like the database code before realtime. Someone - please come up with a plan to clean this up.
Definition in file app_voicemail.c.
| #define ASTERISK_USERNAME "asterisk" |
Definition at line 189 of file app_voicemail.c.
| #define BASELINELEN 72 |
| #define BASEMAXINLINE 256 |
| #define CHUNKSIZE 65536 |
Definition at line 186 of file app_voicemail.c.
| #define COMMAND_TIMEOUT 5000 |
Definition at line 182 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 609 of file app_voicemail.c.
Referenced by load_config().
| #define DELETE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (vm_delete(c)) |
Definition at line 466 of file app_voicemail.c.
Referenced by close_mailbox(), notify_new_message(), play_record_review(), and vm_tempgreeting().
| #define DISPOSE | ( | a, | |||
| b | ) |
Definition at line 461 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), leave_voicemail(), notify_new_message(), play_greeting(), play_message(), play_record_review(), vm_intro(), vm_options(), and vm_tempgreeting().
| #define ENDL "\n" |
Referenced by make_email_file().
| #define eol "\r\n" |
| #define ERROR_LOCK_PATH -100 |
Definition at line 234 of file app_voicemail.c.
| #define ERROR_MAILBOX_FULL -200 |
Definition at line 235 of file app_voicemail.c.
Referenced by close_mailbox(), and save_to_folder().
| #define EXISTS | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (ast_fileexists(c, NULL, d) > 0) |
Definition at line 463 of file app_voicemail.c.
Referenced by close_mailbox(), resequence_mailbox(), and save_to_folder().
| #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
Referenced by handle_voicemail_show_users().
| #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_voicemail_show_zones().
| #define INTRO "vm-intro" |
Definition at line 205 of file app_voicemail.c.
Referenced by leave_voicemail(), and play_record_review().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 214 of file app_voicemail.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 215 of file app_voicemail.c.
| #define MAXMSG 100 |
| #define MAXMSGLIMIT 9999 |
Definition at line 208 of file app_voicemail.c.
Referenced by apply_option(), last_message_index(), and load_config().
| #define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 477 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
| #define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 476 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 464 of file app_voicemail.c.
Referenced by close_mailbox(), resequence_mailbox(), and save_to_folder().
| #define RETRIEVE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) |
Definition at line 460 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), leave_voicemail(), notify_new_message(), play_greeting(), play_message(), vm_intro(), vm_options(), and vm_tempgreeting().
| #define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 203 of file app_voicemail.c.
| #define SMDI_MWI_WAIT_TIMEOUT 1000 |
| #define STORE | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h, | |||||
| i | ) |
Definition at line 462 of file app_voicemail.c.
Referenced by forward_message(), leave_voicemail(), play_record_review(), and vm_forwardoptions().
| #define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 486 of file app_voicemail.c.
| #define VALID_DTMF "1234567890*#" |
| #define VM_ALLOCED (1 << 13) |
Definition at line 230 of file app_voicemail.c.
Referenced by find_user(), find_user_realtime(), free_user(), and free_vm_users().
| #define VM_ATTACH (1 << 11) |
Definition at line 228 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) |
Definition at line 229 of file app_voicemail.c.
Referenced by apply_option(), manager_list_voicemail_users(), and notify_new_message().
| #define VM_DIRECFORWARD (1 << 10) |
directory_forward
Definition at line 227 of file app_voicemail.c.
Referenced by forward_message(), and load_config().
| #define VM_ENVELOPE (1 << 4) |
Definition at line 221 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 225 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 224 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().
| #define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 233 of file app_voicemail.c.
Referenced by apply_option(), close_mailbox(), and load_config().
| #define VM_OPERATOR (1 << 1) |
Definition at line 218 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) |
| #define VM_REVIEW (1 << 0) |
Definition at line 217 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_record_review().
| #define VM_SAYCID (1 << 2) |
Definition at line 219 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_message().
| #define VM_SAYDURATION (1 << 5) |
Definition at line 222 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and play_message().
| #define VM_SEARCH (1 << 14) |
Definition at line 231 of file app_voicemail.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), and load_config().
| #define VM_SKIPAFTERCMD (1 << 6) |
| #define VM_SVMAIL (1 << 3) |
Definition at line 220 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 232 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_intro().
| #define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 188 of file app_voicemail.c.
| #define VOICEMAIL_DIR_MODE 0777 |
Definition at line 184 of file app_voicemail.c.
| #define VOICEMAIL_FILE_MODE 0666 |
Definition at line 185 of file app_voicemail.c.
Referenced by copy(), leave_voicemail(), make_email_file(), and vm_mkftemp().
| anonymous enum |
Definition at line 238 of file app_voicemail.c.
00238 { 00239 NEW_FOLDER, 00240 OLD_FOLDER, 00241 WORK_FOLDER, 00242 FAMILY_FOLDER, 00243 FRIENDS_FOLDER, 00244 GREETINGS_FOLDER 00245 } vm_box;
| anonymous enum |
| OPT_SILENT | |
| OPT_BUSY_GREETING | |
| OPT_UNAVAIL_GREETING | |
| OPT_RECORDGAIN | |
| OPT_PREPEND_MAILBOX | |
| OPT_AUTOPLAY | |
| OPT_DTMFEXIT |
Definition at line 247 of file app_voicemail.c.
00247 { 00248 OPT_SILENT = (1 << 0), 00249 OPT_BUSY_GREETING = (1 << 1), 00250 OPT_UNAVAIL_GREETING = (1 << 2), 00251 OPT_RECORDGAIN = (1 << 3), 00252 OPT_PREPEND_MAILBOX = (1 << 4), 00253 OPT_AUTOPLAY = (1 << 6), 00254 OPT_DTMFEXIT = (1 << 7), 00255 } vm_option_flags;
| anonymous enum |
Definition at line 257 of file app_voicemail.c.
00257 { 00258 OPT_ARG_RECORDGAIN = 0, 00259 OPT_ARG_PLAYFOLDER = 1, 00260 OPT_ARG_DTMFEXIT = 2, 00261 /* This *must* be the last value in this enum! */ 00262 OPT_ARG_ARRAY_SIZE = 3, 00263 } vm_option_args;
| static void __fini_mwi_subs | ( | void | ) | [static] |
| static int __has_voicemail | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder, | |||
| int | shortcircuit | |||
| ) | [static] |
Definition at line 4190 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount(), and messagecount().
04191 { 04192 DIR *dir; 04193 struct dirent *de; 04194 char fn[256]; 04195 int ret = 0; 04196 04197 /* If no mailbox, return immediately */ 04198 if (ast_strlen_zero(mailbox)) 04199 return 0; 04200 04201 if (ast_strlen_zero(folder)) 04202 folder = "INBOX"; 04203 if (ast_strlen_zero(context)) 04204 context = "default"; 04205 04206 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 04207 04208 if (!(dir = opendir(fn))) 04209 return 0; 04210 04211 while ((de = readdir(dir))) { 04212 if (!strncasecmp(de->d_name, "msg", 3)) { 04213 if (shortcircuit) { 04214 ret = 1; 04215 break; 04216 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) 04217 ret++; 04218 } 04219 } 04220 04221 closedir(dir); 04222 04223 return ret; 04224 }
| static void __init_mwi_subs | ( | void | ) | [static] |
| static void __reg_module | ( | void | ) | [static] |
Definition at line 10302 of file app_voicemail.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 10302 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 8594 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(), and LOG_ERROR.
08595 { 08596 struct ast_vm_user svm; 08597 AST_DECLARE_APP_ARGS(arg, 08598 AST_APP_ARG(mbox); 08599 AST_APP_ARG(context); 08600 ); 08601 08602 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 08603 08604 if (ast_strlen_zero(arg.mbox)) { 08605 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 08606 return -1; 08607 } 08608 08609 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 08610 return 0; 08611 }
| static void adsi_begin | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 5034 of file app_voicemail.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available, ast_adsi_load_session, ast_log(), and LOG_WARNING.
Referenced by vm_authenticate(), and vm_execmain().
05035 { 05036 int x; 05037 if (!ast_adsi_available(chan)) 05038 return; 05039 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 05040 if (x < 0) 05041 return; 05042 if (!x) { 05043 if (adsi_load_vmail(chan, useadsi)) { 05044 ast_log(LOG_WARNING, "Unable to upload voicemail scripts\n"); 05045 return; 05046 } 05047 } else 05048 *useadsi = 1; 05049 }
| static void adsi_delete | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5223 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_set_keys, ast_adsi_transmit_message, ast_adsi_voice_mode, vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.
Referenced by vm_execmain().
05224 { 05225 int bytes = 0; 05226 unsigned char buf[256]; 05227 unsigned char keys[8]; 05228 05229 int x; 05230 05231 if (!ast_adsi_available(chan)) 05232 return; 05233 05234 /* New meaning for keys */ 05235 for (x = 0; x < 5; x++) 05236 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05237 05238 keys[6] = 0x0; 05239 keys[7] = 0x0; 05240 05241 if (!vms->curmsg) { 05242 /* No prev key, provide "Folder" instead */ 05243 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05244 } 05245 if (vms->curmsg >= vms->lastmsg) { 05246 /* If last message ... */ 05247 if (vms->curmsg) { 05248 /* but not only message, provide "Folder" instead */ 05249 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05250 } else { 05251 /* Otherwise if only message, leave blank */ 05252 keys[3] = 1; 05253 } 05254 } 05255 05256 /* If deleted, show "undeleted" */ 05257 if (vms->deleted[vms->curmsg]) 05258 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05259 05260 /* Except "Exit" */ 05261 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05262 bytes += ast_adsi_set_keys(buf + bytes, keys); 05263 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05264 05265 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05266 }
| static void adsi_folders | ( | struct ast_channel * | chan, | |
| int | start, | |||
| char * | label | |||
| ) | [static] |
Definition at line 5099 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_execmain().
05100 { 05101 unsigned char buf[256]; 05102 int bytes = 0; 05103 unsigned char keys[8]; 05104 int x, y; 05105 05106 if (!ast_adsi_available(chan)) 05107 return; 05108 05109 for (x = 0; x < 5; x++) { 05110 y = ADSI_KEY_APPS + 12 + start + x; 05111 if (y > ADSI_KEY_APPS + 12 + 4) 05112 y = 0; 05113 keys[x] = ADSI_KEY_SKT | y; 05114 } 05115 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 05116 keys[6] = 0; 05117 keys[7] = 0; 05118 05119 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 05120 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 05121 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05122 bytes += ast_adsi_set_keys(buf + bytes, keys); 05123 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05124 05125 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05126 }
| static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5371 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_execmain().
05372 { 05373 unsigned char buf[256]; 05374 int bytes = 0; 05375 05376 if (!ast_adsi_available(chan)) 05377 return; 05378 bytes += adsi_logo(buf + bytes); 05379 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 05380 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 05381 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05382 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05383 05384 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05385 }
| static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 4905 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, mbox(), and num.
Referenced by adsi_begin().
04906 { 04907 unsigned char buf[256]; 04908 int bytes = 0; 04909 int x; 04910 char num[5]; 04911 04912 *useadsi = 0; 04913 bytes += ast_adsi_data_mode(buf + bytes); 04914 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04915 04916 bytes = 0; 04917 bytes += adsi_logo(buf); 04918 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 04919 #ifdef DISPLAY 04920 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 04921 #endif 04922 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 04923 bytes += ast_adsi_data_mode(buf + bytes); 04924 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04925 04926 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 04927 bytes = 0; 04928 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 04929 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 04930 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 04931 bytes += ast_adsi_voice_mode(buf + bytes, 0); 04932 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04933 return 0; 04934 } 04935 04936 #ifdef DISPLAY 04937 /* Add a dot */ 04938 bytes = 0; 04939 bytes += ast_adsi_logo(buf); 04940 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 04941 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 04942 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 04943 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04944 #endif 04945 bytes = 0; 04946 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 04947 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 04948 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 04949 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 04950 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 04951 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 04952 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 04953 04954 #ifdef DISPLAY 04955 /* Add another dot */ 04956 bytes = 0; 04957 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 04958 bytes += ast_adsi_voice_mode(buf + bytes, 0); 04959 04960 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 04961 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04962 #endif 04963 04964 bytes = 0; 04965 /* These buttons we load but don't use yet */ 04966 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 04967 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 04968 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 04969 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 04970 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 04971 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 04972 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 04973 04974 #ifdef DISPLAY 04975 /* Add another dot */ 04976 bytes = 0; 04977 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 04978 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 04979 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04980 #endif 04981 04982 bytes = 0; 04983 for (x = 0; x < 5; x++) { 04984 snprintf(num, sizeof(num), "%d", x); 04985 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1); 04986 } 04987 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 04988 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 04989 04990 #ifdef DISPLAY 04991 /* Add another dot */ 04992 bytes = 0; 04993 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 04994 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 04995 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 04996 #endif 04997 04998 if (ast_adsi_end_download(chan)) { 04999 bytes = 0; 05000 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 05001 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05002 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05003 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05004 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05005 return 0; 05006 } 05007 bytes = 0; 05008 bytes += ast_adsi_download_disconnect(buf + bytes); 05009 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05010 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05011 05012 ast_debug(1, "Done downloading scripts...\n"); 05013 05014 #ifdef DISPLAY 05015 /* Add last dot */ 05016 bytes = 0; 05017 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 05018 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05019 #endif 05020 ast_debug(1, "Restarting session...\n"); 05021 05022 bytes = 0; 05023 /* Load the session now */ 05024 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 05025 *useadsi = 1; 05026 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 05027 } else 05028 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 05029 05030 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05031 return 0; 05032 }
| static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5051 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_input_control, ast_adsi_input_format, ast_adsi_load_soft_key, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_authenticate().
05052 { 05053 unsigned char buf[256]; 05054 int bytes = 0; 05055 unsigned char keys[8]; 05056 int x; 05057 if (!ast_adsi_available(chan)) 05058 return; 05059 05060 for (x = 0; x < 8; x++) 05061 keys[x] = 0; 05062 /* Set one key for next */ 05063 keys[3] = ADSI_KEY_APPS + 3; 05064 05065 bytes += adsi_logo(buf + bytes); 05066 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 05067 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 05068 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05069 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 05070 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 05071 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 05072 bytes += ast_adsi_set_keys(buf + bytes, keys); 05073 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05074 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05075 }
| static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 4897 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().
04898 { 04899 int bytes = 0; 04900 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 04901 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 04902 return bytes; 04903 }
| static void adsi_message | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5128 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, ast_callerid_parse(), ast_copy_string(), ast_strlen_zero(), vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, name, num, and strsep().
Referenced by play_message(), and vm_execmain().
05129 { 05130 int bytes = 0; 05131 unsigned char buf[256]; 05132 char buf1[256], buf2[256]; 05133 char fn2[PATH_MAX]; 05134 05135 char cid[256] = ""; 05136 char *val; 05137 char *name, *num; 05138 char datetime[21] = ""; 05139 FILE *f; 05140 05141 unsigned char keys[8]; 05142 05143 int x; 05144 05145 if (!ast_adsi_available(chan)) 05146 return; 05147 05148 /* Retrieve important info */ 05149 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 05150 f = fopen(fn2, "r"); 05151 if (f) { 05152 while (!feof(f)) { 05153 if (!fgets((char *)buf, sizeof(buf), f)) { 05154 continue; 05155 } 05156 if (!feof(f)) { 05157 char *stringp = NULL; 05158 stringp = (char *)buf; 05159 strsep(&stringp, "="); 05160 val = strsep(&stringp, "="); 05161 if (!ast_strlen_zero(val)) { 05162 if (!strcmp((char *)buf, "callerid")) 05163 ast_copy_string(cid, val, sizeof(cid)); 05164 if (!strcmp((char *)buf, "origdate")) 05165 ast_copy_string(datetime, val, sizeof(datetime)); 05166 } 05167 } 05168 } 05169 fclose(f); 05170 } 05171 /* New meaning for keys */ 05172 for (x = 0; x < 5; x++) 05173 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 05174 keys[6] = 0x0; 05175 keys[7] = 0x0; 05176 05177 if (!vms->curmsg) { 05178 /* No prev key, provide "Folder" instead */ 05179 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05180 } 05181 if (vms->curmsg >= vms->lastmsg) { 05182 /* If last message ... */ 05183 if (vms->curmsg) { 05184 /* but not only message, provide "Folder" instead */ 05185 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 05186 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05187 05188 } else { 05189 /* Otherwise if only message, leave blank */ 05190 keys[3] = 1; 05191 } 05192 } 05193 05194 if (!ast_strlen_zero(cid)) { 05195 ast_callerid_parse(cid, &name, &num); 05196 if (!name) 05197 name = num; 05198 } else 05199 name = "Unknown Caller"; 05200 05201 /* If deleted, show "undeleted" */ 05202 05203 if (vms->deleted[vms->curmsg]) 05204 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 05205 05206 /* Except "Exit" */ 05207 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 05208 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 05209 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 05210 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 05211 05212 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05213 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05214 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 05215 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 05216 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05217 bytes += ast_adsi_set_keys(buf + bytes, keys); 05218 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05219 05220 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05221 }
| static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5077 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_input_control, ast_adsi_input_format, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_authenticate().
05078 { 05079 unsigned char buf[256]; 05080 int bytes = 0; 05081 unsigned char keys[8]; 05082 int x; 05083 if (!ast_adsi_available(chan)) 05084 return; 05085 05086 for (x = 0; x < 8; x++) 05087 keys[x] = 0; 05088 /* Set one key for next */ 05089 keys[3] = ADSI_KEY_APPS + 3; 05090 05091 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05092 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 05093 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 05094 bytes += ast_adsi_set_keys(buf + bytes, keys); 05095 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05096 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05097 }
| static void adsi_status | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5268 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
05269 { 05270 unsigned char buf[256] = ""; 05271 char buf1[256] = "", buf2[256] = ""; 05272 int bytes = 0; 05273 unsigned char keys[8]; 05274 int x; 05275 05276 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 05277 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 05278 if (!ast_adsi_available(chan)) 05279 return; 05280 if (vms->newmessages) { 05281 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 05282 if (vms->oldmessages) { 05283 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 05284 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 05285 } else { 05286 snprintf(buf2, sizeof(buf2), "%s.", newm); 05287 } 05288 } else if (vms->oldmessages) { 05289 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 05290 snprintf(buf2, sizeof(buf2), "%s.", oldm); 05291 } else { 05292 strcpy(buf1, "You have no messages."); 05293 buf2[0] = ' '; 05294 buf2[1] = '\0'; 05295 } 05296 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05297 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05298 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05299 05300 for (x = 0; x < 6; x++) 05301 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 05302 keys[6] = 0; 05303 keys[7] = 0; 05304 05305 /* Don't let them listen if there are none */ 05306 if (vms->lastmsg < 0) 05307 keys[0] = 1; 05308 bytes += ast_adsi_set_keys(buf + bytes, keys); 05309 05310 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05311 05312 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05313 }
| static void adsi_status2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 5315 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
05316 { 05317 unsigned char buf[256] = ""; 05318 char buf1[256] = "", buf2[256] = ""; 05319 int bytes = 0; 05320 unsigned char keys[8]; 05321 int x; 05322 05323 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 05324 05325 if (!ast_adsi_available(chan)) 05326 return; 05327 05328 /* Original command keys */ 05329 for (x = 0; x < 6; x++) 05330 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 05331 05332 keys[6] = 0; 05333 keys[7] = 0; 05334 05335 if ((vms->lastmsg + 1) < 1) 05336 keys[0] = 0; 05337 05338 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 05339 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 05340 05341 if (vms->lastmsg + 1) 05342 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 05343 else 05344 strcpy(buf2, "no messages."); 05345 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 05346 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 05347 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 05348 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05349 bytes += ast_adsi_set_keys(buf + bytes, keys); 05350 05351 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05352 05353 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05354 05355 }
| 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] |
Definition at line 9910 of file app_voicemail.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::fn2, vm_state::heard, leave_voicemail(), LOG_WARNING, ast_vm_user::mailbox, make_file(), name, num, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
09911 { 09912 int res = 0; 09913 char filename[PATH_MAX]; 09914 struct ast_config *msg_cfg = NULL; 09915 const char *origtime, *context; 09916 char *name, *num; 09917 int retries = 0; 09918 char *cid; 09919 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 09920 09921 vms->starting = 0; 09922 09923 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 09924 09925 /* Retrieve info from VM attribute file */ 09926 09927 make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 09928 snprintf(filename, sizeof(filename), "%s.txt", vms->fn2); 09929 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 09930 msg_cfg = ast_config_load(filename, config_flags); 09931 DISPOSE(vms->curdir, vms->curmsg); 09932 if (!msg_cfg) { 09933 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 09934 return 0; 09935 } 09936 09937 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 09938 ast_config_destroy(msg_cfg); 09939 return 0; 09940 } 09941 09942 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 09943 09944 context = ast_variable_retrieve(msg_cfg, "message", "context"); 09945 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 09946 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 09947 switch (option) { 09948 case 3: 09949 if (!res) 09950 res = play_message_datetime(chan, vmu, origtime, filename); 09951 if (!res) 09952 res = play_message_callerid(chan, vms, cid, context, 0); 09953 09954 res = 't'; 09955 break; 09956 09957 case 2: /* Call back */ 09958 09959 if (ast_strlen_zero(cid)) 09960 break; 09961 09962 ast_callerid_parse(cid, &name, &num); 09963 while ((res > -1) && (res != 't')) { 09964 switch (res) { 09965 case '1': 09966 if (num) { 09967 /* Dial the CID number */ 09968 res = dialout(chan, vmu, num, vmu->callback); 09969 if (res) { 09970 ast_config_destroy(msg_cfg); 09971 return 9; 09972 } 09973 } else { 09974 res = '2'; 09975 } 09976 break; 09977 09978 case '2': 09979 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 09980 if (!ast_strlen_zero(vmu->dialout)) { 09981 res = dialout(chan, vmu, NULL, vmu->dialout); 09982 if (res) { 09983 ast_config_destroy(msg_cfg); 09984 return 9; 09985 } 09986 } else { 09987 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 09988 res = ast_play_and_wait(chan, "vm-sorry"); 09989 } 09990 ast_config_destroy(msg_cfg); 09991 return res; 09992 case '*': 09993 res = 't'; 09994 break; 09995 case '3': 09996 case '4': 09997 case '5': 09998 case '6': 09999 case '7': 10000 case '8': 10001 case '9': 10002 case '0': 10003 10004 res = ast_play_and_wait(chan, "vm-sorry"); 10005 retries++; 10006 break; 10007 default: 10008 if (num) { 10009 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 10010 res = ast_play_and_wait(chan, "vm-num-i-have"); 10011 if (!res) 10012 res = play_message_callerid(chan, vms, num, vmu->context, 1); 10013 if (!res) 10014 res = ast_play_and_wait(chan, "vm-tocallnum"); 10015 /* Only prompt for a caller-specified number if there is a dialout context specified */ 10016 if (!ast_strlen_zero(vmu->dialout)) { 10017 if (!res) 10018 res = ast_play_and_wait(chan, "vm-calldiffnum"); 10019 } 10020 } else { 10021 res = ast_play_and_wait(chan, "vm-nonumber"); 10022 if (!ast_strlen_zero(vmu->dialout)) { 10023 if (!res) 10024 res = ast_play_and_wait(chan, "vm-toenternumber"); 10025 } 10026 } 10027 if (!res) 10028 res = ast_play_and_wait(chan, "vm-star-cancel"); 10029 if (!res) 10030 res = ast_waitfordigit(chan, 6000); 10031 if (!res) { 10032 retries++; 10033 if (retries > 3) 10034 res = 't'; 10035 } 10036 break; 10037 10038 } 10039 if (res == 't') 10040 res = 0; 10041 else if (res == '*') 10042 res = -1; 10043 } 10044 break; 10045 10046 case 1: /* Reply */ 10047 /* Send reply directly to sender */ 10048 if (ast_strlen_zero(cid)) 10049 break; 10050 10051 ast_callerid_parse(cid, &name, &num); 10052 if (!num) { 10053 ast_verb(3, "No CID number available, no reply sent\n"); 10054 if (!res) 10055 res = ast_play_and_wait(chan, "vm-nonumber"); 10056 ast_config_destroy(msg_cfg); 10057 return res; 10058 } else { 10059 struct ast_vm_user vmu2; 10060 if (find_user(&vmu2, vmu->context, num)) { 10061 struct leave_vm_options leave_options; 10062 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 10063 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 10064 10065 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 10066 10067 memset(&leave_options, 0, sizeof(leave_options)); 10068 leave_options.record_gain = record_gain; 10069 res = leave_voicemail(chan, mailbox, &leave_options); 10070 if (!res) 10071 res = 't'; 10072 ast_config_destroy(msg_cfg); 10073 return res; 10074 } else { 10075 /* Sender has no mailbox, can't reply */ 10076 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 10077 ast_play_and_wait(chan, "vm-nobox"); 10078 res = 't'; 10079 ast_config_destroy(msg_cfg); 10080 return res; 10081 } 10082 } 10083 res = 0; 10084 10085 break; 10086 } 10087 10088 #ifndef IMAP_STORAGE 10089 ast_config_destroy(msg_cfg); 10090 10091 if (!res) { 10092 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 10093 vms->heard[msg] = 1; 10094 res = wait_file(chan, vms, vms->fn); 10095 } 10096 #endif 10097 return res; 10098 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | mbox, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 8514 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_strdupa, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount(), ast_vm_user::pager, ast_vm_user::password, populate_defaults(), queue_mwi_event(), s, and strsep().
Referenced by load_config().
08515 { 08516 /* Assumes lock is already held */ 08517 char *tmp; 08518 char *stringp; 08519 char *s; 08520 struct ast_vm_user *vmu; 08521 char *mailbox_full; 08522 int new = 0, old = 0; 08523 08524 tmp = ast_strdupa(data); 08525 08526 if (!(vmu = find_or_create(context, mbox))) 08527 return -1; 08528 08529 populate_defaults(vmu); 08530 08531 stringp = tmp; 08532 if ((s = strsep(&stringp, ","))) 08533 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 08534 if (stringp && (s = strsep(&stringp, ","))) 08535 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 08536 if (stringp && (s = strsep(&stringp, ","))) 08537 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 08538 if (stringp && (s = strsep(&stringp, ","))) 08539 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 08540 if (stringp && (s = strsep(&stringp, ","))) 08541 apply_options(vmu, s); 08542 08543 mailbox_full = alloca(strlen(mbox) + strlen(context) + 1); 08544 strcpy(mailbox_full, mbox); 08545 strcat(mailbox_full, "@"); 08546 strcat(mailbox_full, context); 08547 08548 inboxcount(mailbox_full, &new, &old); 08549 queue_mwi_event(mailbox_full, new, old); 08550 08551 return 0; 08552 }
| static void apply_option | ( | struct ast_vm_user * | vmu, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 730 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_log(), 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, LOG_WARNING, 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_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().
00731 { 00732 int x; 00733 if (!strcasecmp(var, "attach")) { 00734 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 00735 } else if (!strcasecmp(var, "attachfmt")) { 00736 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 00737 } else if (!strcasecmp(var, "serveremail")) { 00738 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 00739 } else if (!strcasecmp(var, "language")) { 00740 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 00741 } else if (!strcasecmp(var, "tz")) { 00742 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 00743 #ifdef IMAP_STORAGE 00744 } else if (!strcasecmp(var, "imapuser")) { 00745 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 00746 vmu->imapversion = imapversion; 00747 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 00748 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 00749 vmu->imapversion = imapversion; 00750 } else if (!strcasecmp(var, "imapvmshareid")) { 00751 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 00752 vmu->imapversion = imapversion; 00753 #endif 00754 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 00755 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 00756 } else if (!strcasecmp(var, "saycid")) { 00757 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 00758 } else if (!strcasecmp(var, "sendvoicemail")) { 00759 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 00760 } else if (!strcasecmp(var, "review")) { 00761 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 00762 } else if (!strcasecmp(var, "tempgreetwarn")) { 00763 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 00764 } else if (!strcasecmp(var, "operator")) { 00765 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 00766 } else if (!strcasecmp(var, "envelope")) { 00767 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 00768 } else if (!strcasecmp(var, "moveheard")) { 00769 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 00770 } else if (!strcasecmp(var, "sayduration")) { 00771 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 00772 } else if (!strcasecmp(var, "saydurationm")) { 00773 if (sscanf(value, "%30d", &x) == 1) { 00774 vmu->saydurationm = x; 00775 } else { 00776 ast_log(LOG_WARNING, "Invalid min duration for say duration\n"); 00777 } 00778 } else if (!strcasecmp(var, "forcename")) { 00779 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 00780 } else if (!strcasecmp(var, "forcegreetings")) { 00781 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 00782 } else if (!strcasecmp(var, "callback")) { 00783 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 00784 } else if (!strcasecmp(var, "dialout")) { 00785 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 00786 } else if (!strcasecmp(var, "exitcontext")) { 00787 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 00788 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 00789 vmu->maxsecs = atoi(value); 00790 if (vmu->maxsecs <= 0) { 00791 ast_log(LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 00792 vmu->maxsecs = vmmaxsecs; 00793 } else { 00794 vmu->maxsecs = atoi(value); 00795 } 00796 if (!strcasecmp(var, "maxmessage")) 00797 ast_log(LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 00798 } else if (!strcasecmp(var, "maxmsg")) { 00799 vmu->maxmsg = atoi(value); 00800 if (vmu->maxmsg <= 0) { 00801 ast_log(LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 00802 vmu->maxmsg = MAXMSG; 00803 } else if (vmu->maxmsg > MAXMSGLIMIT) { 00804 ast_log(LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 00805 vmu->maxmsg = MAXMSGLIMIT; 00806 } 00807 } else if (!strcasecmp(var, "backupdeleted")) { 00808 if (sscanf(value, "%30d", &x) == 1) 00809 vmu->maxdeletedmsg = x; 00810 else if (ast_true(value)) 00811 vmu->maxdeletedmsg = MAXMSG; 00812 else 00813 vmu->maxdeletedmsg = 0; 00814 00815 if (vmu->maxdeletedmsg < 0) { 00816 ast_log(LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 00817 vmu->maxdeletedmsg = MAXMSG; 00818 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 00819 ast_log(LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 00820 vmu->maxdeletedmsg = MAXMSGLIMIT; 00821 } 00822 } else if (!strcasecmp(var, "volgain")) { 00823 sscanf(value, "%30lf", &vmu->volgain); 00824 } else if (!strcasecmp(var, "options")) { 00825 apply_options(vmu, value); 00826 } 00827 }
| static void apply_options | ( | struct ast_vm_user * | vmu, | |
| const char * | options | |||
| ) | [static] |
Definition at line 844 of file app_voicemail.c.
References apply_option(), ast_strdupa, s, strsep(), and var.
Referenced by append_mailbox(), and apply_option().
00845 { /* Destructively Parse options and apply */ 00846 char *stringp; 00847 char *s; 00848 char *var, *value; 00849 stringp = ast_strdupa(options); 00850 while ((s = strsep(&stringp, "|"))) { 00851 value = s; 00852 if ((var = strsep(&value, "=")) && value) { 00853 apply_option(vmu, var, value); 00854 } 00855 } 00856 }
| static void apply_options_full | ( | struct ast_vm_user * | retval, | |
| struct ast_variable * | var | |||
| ) | [static] |
Definition at line 858 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, and ast_variable::value.
Referenced by find_user_realtime(), and load_config().
00859 { 00860 struct ast_variable *tmp; 00861 tmp = var; 00862 while (tmp) { 00863 if (!strcasecmp(tmp->name, "vmsecret")) { 00864 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 00865 } else if (!strcasecmp(tmp->name, "secret") || !strcasecmp(tmp->name, "password")) { /* don't overwrite vmsecret if it exists */ 00866 if (ast_strlen_zero(retval->password)) 00867 ast_copy_string(retval->password, tmp->value, sizeof(retval->password)); 00868 } else if (!strcasecmp(tmp->name, "uniqueid")) { 00869 ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid)); 00870 } else if (!strcasecmp(tmp->name, "pager")) { 00871 ast_copy_string(retval->pager, tmp->value, sizeof(retval->pager)); 00872 } else if (!strcasecmp(tmp->name, "email")) { 00873 ast_copy_string(retval->email, tmp->value, sizeof(retval->email)); 00874 } else if (!strcasecmp(tmp->name, "fullname")) { 00875 ast_copy_string(retval->fullname, tmp->value, sizeof(retval->fullname)); 00876 } else if (!strcasecmp(tmp->name, "context")) { 00877 ast_copy_string(retval->context, tmp->value, sizeof(retval->context)); 00878 #ifdef IMAP_STORAGE 00879 } else if (!strcasecmp(tmp->name, "imapuser")) { 00880 ast_copy_string(retval->imapuser, tmp->value, sizeof(retval->imapuser)); 00881 retval->imapversion = imapversion; 00882 } else if (!strcasecmp(tmp->name, "imappassword") || !strcasecmp(tmp->name, "imapsecret")) { 00883 ast_copy_string(retval->imappassword, tmp->value, sizeof(retval->imappassword)); 00884 retval->imapversion = imapversion; 00885 } else if (!strcasecmp(tmp->name, "imapvmshareid")) { 00886 ast_copy_string(retval->imapvmshareid, tmp->value, sizeof(retval->imapvmshareid)); 00887 retval->imapversion = imapversion; 00888 #endif 00889 } else 00890 apply_option(retval, tmp->name, tmp->value); 00891 tmp = tmp->next; 00892 } 00893 }
| static int base_encode | ( | char * | filename, | |
| FILE * | so | |||
| ) | [static] |
Definition at line 3275 of file app_voicemail.c.
References ast_log(), BASEMAXINLINE, eol, errno, inchar(), baseio::iocp, LOG_WARNING, and ochar().
03276 { 03277 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 03278 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 03279 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 03280 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 03281 int i, hiteof = 0; 03282 FILE *fi; 03283 struct baseio bio; 03284 03285 memset(&bio, 0, sizeof(bio)); 03286 bio.iocp = BASEMAXINLINE; 03287 03288 if (!(fi = fopen(filename, "rb"))) { 03289 ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 03290 return -1; 03291 } 03292 03293 while (!hiteof) { 03294 unsigned char igroup[3], ogroup[4]; 03295 int c, n; 03296 03297 igroup[0] = igroup[1] = igroup[2] = 0; 03298 03299 for (n = 0; n < 3; n++) { 03300 if ((c = inchar(&bio, fi)) == EOF) { 03301 hiteof = 1; 03302 break; 03303 } 03304 03305 igroup[n] = (unsigned char)c; 03306 } 03307 03308 if (n > 0) { 03309 ogroup[0] = dtable[igroup[0] >> 2]; 03310 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 03311 ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 03312 ogroup[3] = dtable[igroup[2] & 0x3F]; 03313 03314 if (n < 3) { 03315 ogroup[3] = '='; 03316 03317 if (n < 2) 03318 ogroup[2] = '='; 03319 } 03320 03321 for (i = 0; i < 4; i++) 03322 ochar(&bio, ogroup[i], so); 03323 } 03324 } 03325 03326 fclose(fi); 03327 03328 if (fputs(eol, so) == EOF) 03329 return 0; 03330 03331 return 1; 03332 }
| static int change_password_realtime | ( | struct ast_vm_user * | vmu, | |
| const char * | password | |||
| ) | [static] |
Definition at line 829 of file app_voicemail.c.
References ast_copy_string(), ast_strlen_zero(), ast_update_realtime(), ast_vm_user::password, and ast_vm_user::uniqueid.
Referenced by vm_change_password().
00830 { 00831 int res = -1; 00832 if (!strcmp(vmu->password, password)) { 00833 /* No change (but an update would return 0 rows updated, so we opt out here) */ 00834 return 0; 00835 } else if (!ast_strlen_zero(vmu->uniqueid)) { 00836 if (ast_update_realtime("voicemail", "uniqueid", vmu->uniqueid, "password", password, NULL) > 0) { 00837 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 00838 res = 0; 00839 } 00840 } 00841 return res; 00842 }
| 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 3432 of file app_voicemail.c.
Referenced by make_email_file().
03433 { 03434 for (; *str; str++) { 03435 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 03436 return 1; 03437 } 03438 } 03439 return 0; 03440 }
| static int close_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 6284 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_log(), ast_test_flag, ast_unlock_path(), ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, ERROR_LOCK_PATH, ERROR_MAILBOX_FULL, EXISTS, vm_state::fn, vm_state::fn2, vm_state::heard, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
06285 { 06286 int x = 0; 06287 #ifndef IMAP_STORAGE 06288 int res = 0, nummsg; 06289 #endif 06290 06291 if (vms->lastmsg <= -1) 06292 goto done; 06293 06294 vms->curmsg = -1; 06295 #ifndef IMAP_STORAGE 06296 /* Get the deleted messages fixed */ 06297 if (vm_lock_path(vms->curdir)) 06298 return ERROR_LOCK_PATH; 06299 06300 for (x = 0; x < vmu->maxmsg; x++) { 06301 if (!vms->deleted[x] && (strcasecmp(vms->curbox, "INBOX") || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 06302 /* Save this message. It's not in INBOX or hasn't been heard */ 06303 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 06304 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 06305 break; 06306 vms->curmsg++; 06307 make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 06308 if (strcmp(vms->fn, vms->fn2)) { 06309 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, vms->fn2); 06310 } 06311 } else if (!strcasecmp(vms->curbox, "INBOX") && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 06312 /* Move to old folder before deleting */ 06313 res = save_to_folder(vmu, vms, x, 1); 06314 if (res == ERROR_LOCK_PATH || res == ERROR_MAILBOX_FULL) { 06315 /* If save failed do not delete the message */ 06316 ast_log(LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 06317 vms->deleted[x] = 0; 06318 vms->heard[x] = 0; 06319 --x; 06320 } 06321 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 06322 /* Move to deleted folder */ 06323 res = save_to_folder(vmu, vms, x, 10); 06324 if (res == ERROR_LOCK_PATH) { 06325 /* If save failed do not delete the message */ 06326 vms->deleted[x] = 0; 06327 vms->heard[x] = 0; 06328 --x; 06329 } 06330 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 06331 /* If realtime storage enabled - we should explicitly delete this message, 06332 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 06333 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 06334 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 06335 DELETE(vms->curdir, x, vms->fn, vmu); 06336 } 06337 } 06338 06339 /* Delete ALL remaining messages */ 06340 nummsg = x - 1; 06341 for (x = vms->curmsg + 1; x <= nummsg; x++) { 06342 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 06343 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 06344 DELETE(vms->curdir, x, vms->fn, vmu); 06345 } 06346 ast_unlock_path(vms->curdir); 06347 #else 06348 if (vms->deleted) { 06349 for (x = 0; x < vmu->maxmsg; x++) { 06350 if (vms->deleted[x]) { 06351 ast_debug(3, "IMAP delete of %d\n", x); 06352 DELETE(vms->curdir, x, vms->fn, vmu); 06353 } 06354 } 06355 } 06356 #endif 06357 06358 done: 06359 if (vms->deleted) 06360 memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 06361 if (vms->heard) 06362 memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 06363 06364 return 0; 06365 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 8698 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
08699 { 08700 int which = 0; 08701 int wordlen; 08702 struct ast_vm_user *vmu; 08703 const char *context = ""; 08704 08705 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 08706 if (pos > 4) 08707 return NULL; 08708 if (pos == 3) 08709 return (state == 0) ? ast_strdup("for") : NULL; 08710 wordlen = strlen(word); 08711 AST_LIST_TRAVERSE(&users, vmu, list) { 08712 if (!strncasecmp(word, vmu->context, wordlen)) { 08713 if (context && strcmp(context, vmu->context) && ++which > state) 08714 return ast_strdup(vmu->context); 08715 /* ignore repeated contexts ? */ 08716 context = vmu->context; 08717 } 08718 } 08719 return NULL; 08720 }
| static int copy | ( | char * | infile, | |
| char * | outfile | |||
| ) | [static] |
Definition at line 3107 of file app_voicemail.c.
References ast_log(), errno, LOG_WARNING, and VOICEMAIL_FILE_MODE.
03108 { 03109 int ifd; 03110 int ofd; 03111 int res; 03112 int len; 03113 char buf[4096]; 03114 03115 #ifdef HARDLINK_WHEN_POSSIBLE 03116 /* Hard link if possible; saves disk space & is faster */ 03117 if (link(infile, outfile)) { 03118 #endif 03119 if ((ifd = open(infile, O_RDONLY)) < 0) { 03120 ast_log(LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03121 return -1; 03122 } 03123 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03124 ast_log(LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03125 close(ifd); 03126 return -1; 03127 } 03128 do { 03129 len = read(ifd, buf, sizeof(buf)); 03130 if (len < 0) { 03131 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03132 close(ifd); 03133 close(ofd); 03134 unlink(outfile); 03135 } 03136 if (len) { 03137 res = write(ofd, buf, len); 03138 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03139 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03140 close(ifd); 03141 close(ofd); 03142 unlink(outfile); 03143 } 03144 } 03145 } while (len); 03146 close(ifd); 03147 close(ofd); 03148 return 0; 03149 #ifdef HARDLINK_WHEN_POSSIBLE 03150 } else { 03151 /* Hard link succeeded */ 03152 return 0; 03153 } 03154 #endif 03155 }
| 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 | |||
| ) | [static] |
Definition at line 4149 of file app_voicemail.c.
References ast_copy_string(), ast_log(), ast_unlock_path(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, create_dirpath(), ERROR_LOCK_PATH, last_message_index(), LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_dir(), make_file(), mbox(), notify_new_message(), S_OR, and vm_lock_path().
Referenced by forward_message(), and leave_voicemail().
04150 { 04151 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 04152 const char *frombox = mbox(imbox); 04153 int recipmsgnum; 04154 04155 ast_log(LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 04156 04157 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04158 04159 if (!dir) 04160 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 04161 else 04162 ast_copy_string(fromdir, dir, sizeof(fromdir)); 04163 04164 make_file(frompath, sizeof(frompath), fromdir, msgnum); 04165 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04166 04167 if (vm_lock_path(todir)) 04168 return ERROR_LOCK_PATH; 04169 04170 recipmsgnum = last_message_index(recip, todir) + 1; 04171 if (recipmsgnum < recip->maxmsg) { 04172 make_file(topath, sizeof(topath), todir, recipmsgnum); 04173 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 04174 } else { 04175 ast_log(LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 04176 } 04177 ast_unlock_path(todir); 04178 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL)); 04179 04180 return 0; 04181 }
| static void copy_plain_file | ( | char * | frompath, | |
| char * | topath | |||
| ) | [static] |
Definition at line 3157 of file app_voicemail.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), ast_store_realtime(), ast_variables_destroy(), copy(), exten, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by forward_message().
03158 { 03159 char frompath2[PATH_MAX], topath2[PATH_MAX]; 03160 struct ast_variable *tmp, *var = NULL; 03161 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 03162 ast_filecopy(frompath, topath, NULL); 03163 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 03164 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 03165 if (ast_check_realtime("voicemail_data")) { 03166 var = ast_load_realtime("voicemail_data", "filename", frompath, NULL); 03167 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 03168 for (tmp = var; tmp; tmp = tmp->next) { 03169 if (!strcasecmp(tmp->name, "origmailbox")) { 03170 origmailbox = tmp->value; 03171 } else if (!strcasecmp(tmp->name, "context")) { 03172 context = tmp->value; 03173 } else if (!strcasecmp(tmp->name, "macrocontext")) { 03174 macrocontext = tmp->value; 03175 } else if (!strcasecmp(tmp->name, "exten")) { 03176 exten = tmp->value; 03177 } else if (!strcasecmp(tmp->name, "priority")) { 03178 priority = tmp->value; 03179 } else if (!strcasecmp(tmp->name, "callerchan")) { 03180 callerchan = tmp->value; 03181 } else if (!strcasecmp(tmp->name, "callerid")) { 03182 callerid = tmp->value; 03183 } else if (!strcasecmp(tmp->name, "origdate")) { 03184 origdate = tmp->value; 03185 } else if (!strcasecmp(tmp->name, "origtime")) { 03186 origtime = tmp->value; 03187 } else if (!strcasecmp(tmp->name, "category")) { 03188 category = tmp->value; 03189 } else if (!strcasecmp(tmp->name, "duration")) { 03190 duration = tmp->value; 03191 } 03192 } 03193 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, NULL); 03194 } 03195 copy(frompath2, topath2); 03196 ast_variables_destroy(var); 03197 }
| static int count_messages | ( | struct ast_vm_user * | vmu, | |
| char * | dir | |||
| ) | [static] |
Definition at line 3032 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().
03033 { 03034 /* Find all .txt files - even if they are not in sequence from 0000 */ 03035 03036 int vmcount = 0; 03037 DIR *vmdir = NULL; 03038 struct dirent *vment = NULL; 03039 03040 if (vm_lock_path(dir)) 03041 return ERROR_LOCK_PATH; 03042 03043 if ((vmdir = opendir(dir))) { 03044 while ((vment = readdir(vmdir))) { 03045 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) 03046 vmcount++; 03047 } 03048 closedir(vmdir); 03049 } 03050 ast_unlock_path(dir); 03051 03052 return vmcount; 03053 }
| 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 1116 of file app_voicemail.c.
References ast_log(), ast_mkdir(), LOG_WARNING, make_dir(), and VOICEMAIL_DIR_MODE.
01117 { 01118 mode_t mode = VOICEMAIL_DIR_MODE; 01119 int res; 01120 01121 make_dir(dest, len, context, ext, folder); 01122 if ((res = ast_mkdir(dest, mode))) { 01123 ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01124 return -1; 01125 } 01126 return 0; 01127 }
| static int dialout | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | num, | |||
| char * | outgoing_context | |||
| ) | [static] |
Definition at line 9853 of file app_voicemail.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verb, ast_waitfordigit(), ast_channel::context, ast_channel::exten, and ast_channel::priority.
Referenced by advanced_options(), and vm_execmain().
09854 { 09855 int cmd = 0; 09856 char destination[80] = ""; 09857 int retries = 0; 09858 09859 if (!num) { 09860 ast_verb(3, "Destination number will be entered manually\n"); 09861 while (retries < 3 && cmd != 't') { 09862 destination[1] = '\0'; 09863 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 09864 if (!cmd) 09865 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 09866 if (!cmd) 09867 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 09868 if (!cmd) { 09869 cmd = ast_waitfordigit(chan, 6000); 09870 if (cmd) 09871 destination[0] = cmd; 09872 } 09873 if (!cmd) { 09874 retries++; 09875 } else { 09876 09877 if (cmd < 0) 09878 return 0; 09879 if (cmd == '*') { 09880 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 09881 return 0; 09882 } 09883 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination)-1, 6000, 10000, "#")) < 0) 09884 retries++; 09885 else 09886 cmd = 't'; 09887 } 09888 } 09889 if (retries >= 3) { 09890 return 0; 09891 } 09892 09893 } else { 09894 ast_verb(3, "Destination number is CID number '%s'\n", num); 09895 ast_copy_string(destination, num, sizeof(destination)); 09896 } 09897 09898 if (!ast_strlen_zero(destination)) { 09899 if (destination[strlen(destination) -1 ] == '*') 09900 return 0; 09901 ast_verb(3, "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 09902 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 09903 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 09904 chan->priority = 0; 09905 return 9; 09906 } 09907 return 0; 09908 }
| 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 3458 of file app_voicemail.c.
References charset.
Referenced by make_email_file().
03459 { 03460 char tmp[80]; 03461 int first_section = 1; 03462 size_t endlen = 0, tmplen = 0; 03463 *end = '\0'; 03464 03465 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 03466 for (; *start; start++) { 03467 int need_encoding = 0; 03468 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 03469 need_encoding = 1; 03470 } 03471 if ((first_section && need_encoding && preamble + tmplen > 70) || 03472 (first_section && !need_encoding && preamble + tmplen > 72) || 03473 (!first_section && need_encoding && tmplen > 70) || 03474 (!first_section && !need_encoding && tmplen > 72)) { 03475 /* Start new line */ 03476 endlen += snprintf(end + endlen, endsize - endlen, "%s%s?=", first_section ? "" : " ", tmp); 03477 tmplen = snprintf(tmp, sizeof(tmp), "=?%s?Q?", charset); 03478 first_section = 0; 03479 } 03480 if (need_encoding && *start == ' ') { 03481 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "_"); 03482 } else if (need_encoding) { 03483 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "=%hhX", *start); 03484 } else { 03485 tmplen += snprintf(tmp + tmplen, sizeof(tmp) - tmplen, "%c", *start); 03486 } 03487 } 03488 snprintf(end + endlen, endsize - endlen, "%s%s?=%s", first_section ? "" : " ", tmp, endlen + postamble > 74 ? " " : ""); 03489 return end; 03490 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | mbox | |||
| ) | [static, read] |
Definition at line 8482 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, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by append_mailbox(), and load_config().
08483 { 08484 struct ast_vm_user *vmu; 08485 08486 AST_LIST_TRAVERSE(&users, vmu, list) { 08487 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mbox, vmu->mailbox)) { 08488 if (strcasecmp(vmu->context, context)) { 08489 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 08490 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 08491 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 08492 \n\tamend your voicemail.conf file to avoid this situation.\n", mbox); 08493 } 08494 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", mbox); 08495 return NULL; 08496 } 08497 if (!strcasecmp(context, vmu->context) && !strcasecmp(mbox, vmu->mailbox)) { 08498 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", mbox, context); 08499 return NULL; 08500 } 08501 } 08502 08503 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 08504 return NULL; 08505 08506 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 08507 ast_copy_string(vmu->mailbox, mbox, sizeof(vmu->mailbox)); 08508 08509 AST_LIST_INSERT_TAIL(&users, vmu, list); 08510 08511 return vmu; 08512 }
| static struct ast_vm_user* find_user | ( | struct ast_vm_user * | ivm, | |
| const char * | context, | |||
| const char * | mailbox | |||
| ) | [static, read] |
Definition at line 939 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, VM_ALLOCED, and VM_SEARCH.
00940 { 00941 /* This function could be made to generate one from a database, too */ 00942 struct ast_vm_user *vmu = NULL, *cur; 00943 AST_LIST_LOCK(&users); 00944 00945 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 00946 context = "default"; 00947 00948 AST_LIST_TRAVERSE(&users, cur, list) { 00949 #ifdef IMAP_STORAGE 00950 if (cur->imapversion != imapversion) { 00951 continue; 00952 } 00953 #endif 00954 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 00955 break; 00956 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 00957 break; 00958 } 00959 if (cur) { 00960 /* Make a copy, so that on a reload, we have no race */ 00961 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 00962 memcpy(vmu, cur, sizeof(*vmu)); 00963 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 00964 AST_LIST_NEXT(vmu, list) = NULL; 00965 } 00966 } else 00967 vmu = find_user_realtime(ivm, context, mailbox); 00968 AST_LIST_UNLOCK(&users); 00969 return vmu; 00970 }
| static struct ast_vm_user* find_user_realtime | ( | struct ast_vm_user * | ivm, | |
| const char * | context, | |||
| const char * | mailbox | |||
| ) | [static, read] |
Definition at line 910 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, ast_vm_user::mailbox, populate_defaults(), var, VM_ALLOCED, and VM_SEARCH.
00911 { 00912 struct ast_variable *var; 00913 struct ast_vm_user *retval; 00914 00915 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 00916 if (!ivm) 00917 ast_set_flag(retval, VM_ALLOCED); 00918 else 00919 memset(retval, 0, sizeof(*retval)); 00920 if (mailbox) 00921 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 00922 populate_defaults(retval); 00923 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 00924 var = ast_load_realtime("voicemail", "mailbox", mailbox, NULL); 00925 else 00926 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, NULL); 00927 if (var) { 00928 apply_options_full(retval, var); 00929 ast_variables_destroy(var); 00930 } else { 00931 if (!ivm) 00932 ast_free(retval); 00933 retval = NULL; 00934 } 00935 } 00936 return retval; 00937 }
| static int forward_message | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| struct vm_state * | vms, | |||
| struct ast_vm_user * | sender, | |||
| char * | fmt, | |||
| int | flag, | |||
| signed char | record_gain | |||
| ) | [static] |
Definition at line 5618 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_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), copy_plain_file(), create_dirpath(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_channel::language, leave_voicemail(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_vm_user::mailbox, make_file(), pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, strsep(), vm_state::username, VM_ATTACH, VM_DIRECFORWARD, and vm_forwardoptions().
Referenced by vm_execmain().
05619 { 05620 #ifdef IMAP_STORAGE 05621 int todircount = 0; 05622 struct vm_state *dstvms; 05623 #endif 05624 char username[70] = ""; 05625 char fn[PATH_MAX]; /* for playback of name greeting */ 05626 char ecodes[16] = "#"; 05627 int res = 0, cmd = 0; 05628 struct ast_vm_user *receiver = NULL, *vmtmp; 05629 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 05630 char *stringp; 05631 const char *s; 05632 int saved_messages = 0, found = 0; 05633 int valid_extensions = 0; 05634 char *dir; 05635 int curmsg; 05636 05637 if (vms == NULL) return -1; 05638 dir = vms->curdir; 05639 curmsg = vms->curmsg; 05640 05641 while (!res && !valid_extensions) { 05642 int use_directory = 0; 05643 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 05644 int done = 0; 05645 int retries = 0; 05646 cmd = 0; 05647 while ((cmd >= 0) && !done) { 05648 if (cmd) 05649 retries = 0; 05650 switch (cmd) { 05651 case '1': 05652 use_directory = 0; 05653 done = 1; 05654 break; 05655 case '2': 05656 use_directory = 1; 05657 done = 1; 05658 break; 05659 case '*': 05660 cmd = 't'; 05661 done = 1; 05662 break; 05663 default: 05664 /* Press 1 to enter an extension press 2 to use the directory */ 05665 cmd = ast_play_and_wait(chan, "vm-forward"); 05666 if (!cmd) 05667 cmd = ast_waitfordigit(chan, 3000); 05668 if (!cmd) 05669 retries++; 05670 if (retries > 3) { 05671 cmd = 't'; 05672 done = 1; 05673 } 05674 05675 } 05676 } 05677 if (cmd < 0 || cmd == 't') 05678 break; 05679 } 05680 05681 if (use_directory) { 05682 /* use app_directory */ 05683 05684 char old_context[sizeof(chan->context)]; 05685 char old_exten[sizeof(chan->exten)]; 05686 int old_priority; 05687 struct ast_app* app; 05688 05689 app = pbx_findapp("Directory"); 05690 if (app) { 05691 char vmcontext[256]; 05692 /* make backup copies */ 05693 memcpy(old_context, chan->context, sizeof(chan->context)); 05694 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 05695 old_priority = chan->priority; 05696 05697 /* call the the Directory, changes the channel */ 05698 snprintf(vmcontext, sizeof(vmcontext), "%s||v", context ? context : "default"); 05699 res = pbx_exec(chan, app, vmcontext); 05700 05701 ast_copy_string(username, chan->exten, sizeof(username)); 05702 05703 /* restore the old context, exten, and priority */ 05704 memcpy(chan->context, old_context, sizeof(chan->context)); 05705 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 05706 chan->priority = old_priority; 05707 05708 } else { 05709 ast_log(LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 05710 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 05711 } 05712 } else { 05713 /* Ask for an extension */ 05714 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 05715 if (res) 05716 break; 05717 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 05718 break; 05719 } 05720 05721 /* start all over if no username */ 05722 if (ast_strlen_zero(username)) 05723 continue; 05724 stringp = username; 05725 s = strsep(&stringp, "*"); 05726 /* start optimistic */ 05727 valid_extensions = 1; 05728 while (s) { 05729 /* Don't forward to ourselves but allow leaving a message for ourselves (flag == 1). find_user is going to malloc since we have a NULL as first argument */ 05730 if ((flag == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 05731 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 05732 found++; 05733 } else { 05734 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 05735 free_user(receiver); 05736 } 05737 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 05738 valid_extensions = 0; 05739 break; 05740 } 05741 05742 /* play name if available, else play extension number */ 05743 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 05744 RETRIEVE(fn, -1, s, receiver->context); 05745 if (ast_fileexists(fn, NULL, NULL) > 0) { 05746 res = ast_stream_and_wait(chan, fn, ecodes); 05747 if (res) { 05748 DISPOSE(fn, -1); 05749 return res; 05750 } 05751 } else { 05752 res = ast_say_digit_str(chan, s, ecodes, chan->language); 05753 } 05754 DISPOSE(fn, -1); 05755 05756 s = strsep(&stringp, "*"); 05757 } 05758 /* break from the loop of reading the extensions */ 05759 if (valid_extensions) 05760 break; 05761 /* "I am sorry, that's not a valid extension. Please try again." */ 05762 res = ast_play_and_wait(chan, "pbx-invalid"); 05763 } 05764 /* check if we're clear to proceed */ 05765 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 05766 return res; 05767 if (flag==1) { 05768 struct leave_vm_options leave_options; 05769 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 05770 /* Make sure that context doesn't get set as a literal "(null)" (or else find_user won't find it) */ 05771 if (context) 05772 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 05773 else 05774 ast_copy_string(mailbox, username, sizeof(mailbox)); 05775 05776 /* Send VoiceMail */ 05777 memset(&leave_options, 0, sizeof(leave_options)); 05778 leave_options.record_gain = record_gain; 05779 cmd = leave_voicemail(chan, mailbox, &leave_options); 05780 } else { 05781 /* Forward VoiceMail */ 05782 long duration = 0; 05783 char origmsgfile[PATH_MAX], msgfile[PATH_MAX]; 05784 struct vm_state vmstmp; 05785 memcpy(&vmstmp, vms, sizeof(vmstmp)); 05786 05787 make_file(origmsgfile, sizeof(origmsgfile), dir, curmsg); 05788 create_dirpath(vmstmp.curdir, sizeof(vmstmp.curdir), sender->context, vmstmp.username, "tmp"); 05789 make_file(msgfile, sizeof(msgfile), vmstmp.curdir, curmsg); 05790 05791 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 05792 05793 /* Alter a surrogate file, only */ 05794 copy_plain_file(origmsgfile, msgfile); 05795 05796 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp); 05797 if (!cmd) { 05798 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 05799 #ifdef IMAP_STORAGE 05800 char *myserveremail = serveremail; 05801 int attach_user_voicemail; 05802 /* get destination mailbox */ 05803 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, 0); 05804 if (!dstvms) { 05805 dstvms = create_vm_state_from_user(vmtmp); 05806 } 05807 if (dstvms) { 05808 init_mailstream(dstvms, 0); 05809 if (!dstvms->mailstream) { 05810 ast_log(LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 05811 } else { 05812 STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms); 05813 run_externnotify(vmtmp->context, vmtmp->mailbox); 05814 } 05815 } else { 05816 ast_log(LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 05817 } 05818 if (!ast_strlen_zero(vmtmp->serveremail)) 05819 myserveremail = vmtmp->serveremail; 05820 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 05821 /* NULL category for IMAP storage */ 05822 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vms->fn, fmt, duration, attach_user_voicemail, chan, NULL); 05823 #else 05824 copy_message(chan, sender, -1, curmsg, duration, vmtmp, fmt, vmstmp.curdir); 05825 #endif 05826 saved_messages++; 05827 AST_LIST_REMOVE_CURRENT(list); 05828 free_user(vmtmp); 05829 if (res) 05830 break; 05831 } 05832 AST_LIST_TRAVERSE_SAFE_END; 05833 if (saved_messages > 0) { 05834 /* give confirmation that the message was saved */ 05835 /* commented out since we can't forward batches yet 05836 if (saved_messages == 1) 05837 res = ast_play_and_wait(chan, "vm-message"); 05838 else 05839 res = ast_play_and_wait(chan, "vm-messages"); 05840 if (!res) 05841 res = ast_play_and_wait(chan, "vm-saved"); */ 05842 res = ast_play_and_wait(chan, "vm-msgsaved"); 05843 } 05844 } 05845 /* Remove surrogate file */ 05846 DISPOSE(dir, curmsg); 05847 } 05848 05849 /* If anything failed above, we still have this list to free */ 05850 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) 05851 free_user(vmtmp); 05852 return res ? res : cmd; 05853 }
| static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1152 of file app_voicemail.c.
References ast_free, ast_test_flag, and VM_ALLOCED.
01153 { 01154 if (ast_test_flag(vmu, VM_ALLOCED)) 01155 ast_free(vmu); 01156 }
| static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 9128 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), and VM_ALLOCED.
Referenced by load_config(), and unload_module().
09129 { 09130 struct ast_vm_user *cur; 09131 AST_LIST_LOCK(&users); 09132 while ((cur = AST_LIST_REMOVE_HEAD(&users, list))) { 09133 ast_set_flag(cur, VM_ALLOCED); 09134 free_user(cur); 09135 } 09136 AST_LIST_UNLOCK(&users); 09137 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 9140 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by load_config(), and unload_module().
09141 { 09142 struct vm_zone *zcur; 09143 AST_LIST_LOCK(&zones); 09144 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 09145 free_zone(zcur); 09146 AST_LIST_UNLOCK(&zones); 09147 }
| static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 3973 of file app_voicemail.c.
References ast_free.
03974 { 03975 ast_free(z); 03976 }
| static int get_date | ( | char * | s, | |
| int | len | |||
| ) | [static] |
Definition at line 3910 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
03911 { 03912 struct ast_tm tm; 03913 struct timeval t = ast_tvnow(); 03914 03915 ast_localtime(&t, &tm, "UTC"); 03916 03917 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 03918 }
| 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 5391 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().
Referenced by get_folder2().
05392 { 05393 int x; 05394 int d; 05395 char fn[PATH_MAX]; 05396 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 05397 if (d) 05398 return d; 05399 for (x = start; x < 5; x++) { /* For all folders */ 05400 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 05401 return d; 05402 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 05403 if (d) 05404 return d; 05405 snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */ 05406 d = vm_play_folder_name(chan, fn); 05407 if (d) 05408 return d; 05409 d = ast_waitfordigit(chan, 500); 05410 if (d) 05411 return d; 05412 } 05413 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 05414 if (d) 05415 return d; 05416 d = ast_waitfordigit(chan, 4000); 05417 return d; 05418 }
| static int get_folder2 | ( | struct ast_channel * | chan, | |
| char * | fn, | |||
| int | start | |||
| ) | [static] |
Definition at line 5420 of file app_voicemail.c.
References ast_play_and_wait(), and get_folder().
Referenced by vm_execmain().
05421 { 05422 int res = 0; 05423 res = ast_play_and_wait(chan, fn); /* Folder name */ 05424 while (((res < '0') || (res > '9')) && 05425 (res != '#') && (res >= 0)) { 05426 res = get_folder(chan, 0); 05427 } 05428 return res; 05429 }
| 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 8833 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli_entry::args, 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.
08834 { 08835 switch (cmd) { 08836 case CLI_INIT: 08837 e->command = "voicemail reload"; 08838 e->usage = 08839 "Usage: voicemail reload\n" 08840 " Reload voicemail configuration\n"; 08841 return NULL; 08842 case CLI_GENERATE: 08843 return NULL; 08844 } 08845 08846 if (a->argc != e->args) 08847 return CLI_SHOWUSAGE; 08848 08849 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 08850 load_config(1); 08851 08852 return CLI_SUCCESS; 08853 }
| 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 8723 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::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.
08724 { 08725 struct ast_vm_user *vmu; 08726 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 08727 const char *context = NULL; 08728 int users_counter = 0; 08729 08730 switch (cmd) { 08731 case CLI_INIT: 08732 e->command = "voicemail show users"; 08733 e->usage = 08734 "Usage: voicemail show users [for <context>]\n" 08735 " Lists all mailboxes currently set up\n"; 08736 return NULL; 08737 case CLI_GENERATE: 08738 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 08739 } 08740 08741 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 08742 return CLI_SHOWUSAGE; 08743 if (a->argc == 5) { 08744 if (strcmp(a->argv[3], "for")) 08745 return CLI_SHOWUSAGE; 08746 context = a->argv[4]; 08747 } 08748 08749 if (ast_check_realtime("voicemail")) { 08750 if (!context) { 08751 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 08752 return CLI_SHOWUSAGE; 08753 } 08754 return show_users_realtime(a->fd, context); 08755 } 08756 08757 AST_LIST_LOCK(&users); 08758 if (AST_LIST_EMPTY(&users)) { 08759 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 08760 AST_LIST_UNLOCK(&users); 08761 return CLI_FAILURE; 08762 } 08763 if (a->argc == 3) 08764 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 08765 else { 08766 int count = 0; 08767 AST_LIST_TRAVERSE(&users, vmu, list) { 08768 if (!strcmp(context, vmu->context)) 08769 count++; 08770 } 08771 if (count) { 08772 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 08773 } else { 08774 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 08775 AST_LIST_UNLOCK(&users); 08776 return CLI_FAILURE; 08777 } 08778 } 08779 AST_LIST_TRAVERSE(&users, vmu, list) { 08780 int newmsgs = 0, oldmsgs = 0; 08781 char count[12], tmp[256] = ""; 08782 08783 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 08784 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 08785 inboxcount(tmp, &newmsgs, &oldmsgs); 08786 snprintf(count, sizeof(count), "%d", newmsgs); 08787 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 08788 users_counter++; 08789 } 08790 } 08791 AST_LIST_UNLOCK(&users); 08792 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 08793 return CLI_SUCCESS; 08794 }
| 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 8797 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli_entry::args, 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::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.
08798 { 08799 struct vm_zone *zone; 08800 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 08801 char *res = CLI_SUCCESS; 08802 08803 switch (cmd) { 08804 case CLI_INIT: 08805 e->command = "voicemail show zones"; 08806 e->usage = 08807 "Usage: voicemail show zones\n" 08808 " Lists zone message formats\n"; 08809 return NULL; 08810 case CLI_GENERATE: 08811 return NULL; 08812 } 08813 08814 if (a->argc != e->args) 08815 return CLI_SHOWUSAGE; 08816 08817 AST_LIST_LOCK(&zones); 08818 if (!AST_LIST_EMPTY(&zones)) { 08819 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 08820 AST_LIST_TRAVERSE(&zones, zone, list) { 08821 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 08822 } 08823 } else { 08824 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 08825 res = CLI_FAILURE; 08826 } 08827 AST_LIST_UNLOCK(&zones); 08828 08829 return res; 08830 }
| static int has_voicemail | ( | const char * | mailbox, | |
| const char * | folder | |||
| ) | [static] |
Definition at line 4227 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and strsep().
04228 { 04229 char tmp[256], *tmp2 = tmp, *mbox, *context; 04230 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04231 while ((mbox = strsep(&tmp2, ","))) { 04232 if ((context = strchr(mbox, '@'))) 04233 *context++ = '\0'; 04234 else 04235 context = "default"; 04236 if (__has_voicemail(context, mbox, folder, 1)) 04237 return 1; 04238 } 04239 return 0; 04240 }
| static int inboxcount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 4243 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by append_mailbox(), handle_voicemail_show_users(), leave_voicemail(), load_module(), manager_list_voicemail_users(), poll_subscribed_mailboxes(), and run_externnotify().
04244 { 04245 char tmp[256]; 04246 char *context; 04247 04248 /* If no mailbox, return immediately */ 04249 if (ast_strlen_zero(mailbox)) 04250 return 0; 04251 04252 if (newmsgs) 04253 *newmsgs = 0; 04254 if (oldmsgs) 04255 *oldmsgs = 0; 04256 04257 if (strchr(mailbox, ',')) { 04258 int tmpnew, tmpold; 04259 char *mb, *cur; 04260 04261 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04262 mb = tmp; 04263 while ((cur = strsep(&mb, ", "))) { 04264 if (!ast_strlen_zero(cur)) { 04265 if (inboxcount(cur, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 04266 return -1; 04267 else { 04268 if (newmsgs) 04269 *newmsgs += tmpnew; 04270 if (oldmsgs) 04271 *oldmsgs += tmpold; 04272 } 04273 } 04274 } 04275 return 0; 04276 } 04277 04278 ast_copy_string(tmp, mailbox, sizeof(tmp)); 04279 04280 if ((context = strchr(tmp, '@'))) 04281 *context++ = '\0'; 04282 else 04283 context = "default"; 04284 04285 if (newmsgs) 04286 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 04287 if (oldmsgs) 04288 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 04289 04290 return 0; 04291 }
| static int inbuf | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
Definition at line 3227 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().
03228 { 03229 int l; 03230 03231 if (bio->ateof) 03232 return 0; 03233 03234 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 03235 if (ferror(fi)) 03236 return -1; 03237 03238 bio->ateof = 1; 03239 return 0; 03240 } 03241 03242 bio->iolen = l; 03243 bio->iocp = 0; 03244 03245 return 1; 03246 }
| static int inchar | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
Definition at line 3248 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
03249 { 03250 if (bio->iocp >= bio->iolen) { 03251 if (!inbuf(bio, fi)) 03252 return EOF; 03253 } 03254 03255 return bio->iobuf[bio->iocp++]; 03256 }
| static int invent_message | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | ext, | |||
| int | busy, | |||
| char * | ecodes | |||
| ) | [static] |
Definition at line 3945 of file app_voicemail.c.
References ast_log(), ast_say_digit_str(), ast_stream_and_wait(), ast_vm_user::context, create_dirpath(), ast_channel::language, LOG_WARNING, and play_greeting().
03946 { 03947 int res; 03948 char fn[PATH_MAX]; 03949 char dest[PATH_MAX]; 03950 03951 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, ext); 03952 03953 if ((res = create_dirpath(dest, sizeof(dest), vmu->context, ext, ""))) { 03954 ast_log(LOG_WARNING, "Failed to make directory(%s)\n", fn); 03955 return -1; 03956 } 03957 03958 res = play_greeting(chan, vmu, fn, ecodes); 03959 if (res == -2) { 03960 /* File did not exist */ 03961 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 03962 if (res) 03963 return res; 03964 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 03965 } 03966 if (res) 03967 return res; 03968 03969 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 03970 return res; 03971 }
| static int is_valid_dtmf | ( | const char * | key | ) | [static] |
Definition at line 895 of file app_voicemail.c.
References ast_log(), ast_strdupa, LOG_WARNING, and VALID_DTMF.
Referenced by load_config().
00896 { 00897 int i; 00898 char *local_key = ast_strdupa(key); 00899 00900 for (i = 0; i < strlen(key); ++i) { 00901 if (!strchr(VALID_DTMF, *local_key)) { 00902 ast_log(LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 00903 return 0; 00904 } 00905 local_key++; 00906 } 00907 return 1; 00908 }
| static int last_message_index | ( | struct ast_vm_user * | vmu, | |
| char * | dir | |||
| ) | [static] |
A negative return value indicates an error.
Definition at line 3074 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().
03075 { 03076 int x; 03077 unsigned char map[MAXMSGLIMIT] = ""; 03078 DIR *msgdir; 03079 struct dirent *msgdirent; 03080 int msgdirint; 03081 03082 /* Reading the entire directory into a file map scales better than 03083 * doing a stat repeatedly on a predicted sequence. I suspect this 03084 * is partially due to stat(2) internally doing a readdir(2) itself to 03085 * find each file. */ 03086 if (!(msgdir = opendir(dir))) { 03087 return -1; 03088 } 03089 03090 while ((msgdirent = readdir(msgdir))) { 03091 if (sscanf(msgdirent->d_name, "msg%30d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) 03092 map[msgdirint] = 1; 03093 } 03094 closedir(msgdir); 03095 03096 for (x = 0; x < vmu->maxmsg; x++) { 03097 if (map[x] == 0) 03098 break; 03099 } 03100 03101 return x - 1; 03102 }
| static int leave_voicemail | ( | struct ast_channel * | chan, | |
| char * | ext, | |||
| struct leave_vm_options * | options | |||
| ) | [static] |
Definition at line 4343 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer, ast_str_create(), ast_str_set(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verb, ast_waitstream(), 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(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, 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_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_greeting(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, S_OR, STORE, strsep(), transfer, vm_lock_path(), VM_OPERATOR, and VOICEMAIL_FILE_MODE.
04344 { 04345 #ifdef IMAP_STORAGE 04346 int newmsgs, oldmsgs; 04347 #endif 04348 char txtfile[PATH_MAX], tmptxtfile[PATH_MAX]; 04349 struct vm_state *vms = NULL; 04350 char callerid[256]; 04351 FILE *txt; 04352 char date[256]; 04353 int txtdes; 04354 int res = 0; 04355 int msgnum; 04356 int duration = 0; 04357 int ausemacro = 0; 04358 int ousemacro = 0; 04359 int ouseexten = 0; 04360 int rtmsgid = 0; 04361 char tmpid[16]; 04362 char tmpdur[16]; 04363 char priority[16]; 04364 char origtime[16]; 04365 char dir[PATH_MAX], tmpdir[PATH_MAX]; 04366 char fn[PATH_MAX]; 04367 char prefile[PATH_MAX] = ""; 04368 char tempfile[PATH_MAX] = ""; 04369 char ext_context[256] = ""; 04370 char fmt[80]; 04371 char *context; 04372 char ecodes[17] = "#"; 04373 char *tmpptr; 04374 struct ast_str *tmp = ast_str_create(16); 04375 struct ast_vm_user *vmu; 04376 struct ast_vm_user svm; 04377 const char *category = NULL, *code, *alldtmf = "0123456789ABCD*#"; 04378 04379 ast_str_set(&tmp, 0, "%s", ext); 04380 ext = ast_str_buffer(tmp); 04381 if ((context = strchr(ext, '@'))) { 04382 *context++ = '\0'; 04383 tmpptr = strchr(context, '&'); 04384 } else { 04385 tmpptr = strchr(ext, '&'); 04386 } 04387 04388 if (tmpptr) { 04389 *tmpptr++ = '\0'; 04390 } 04391 04392 category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"); 04393 04394 ast_debug(3, "Before find_user\n"); 04395 if (!(vmu = find_user(&svm, context, ext))) { 04396 ast_log(LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 04397 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04398 ast_free(tmp); 04399 return res; 04400 } 04401 /* Setup pre-file if appropriate */ 04402 if (strcmp(vmu->context, "default")) { 04403 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 04404 } else { 04405 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 04406 } 04407 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 04408 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 04409 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 04410 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 04411 } 04412 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 04413 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 04414 ast_log(LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 04415 ast_free(tmp); 04416 return -1; 04417 } 04418 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 04419 if (ast_fileexists(tempfile, NULL, NULL) > 0) { 04420 ast_copy_string(prefile, tempfile, sizeof(prefile)); 04421 } 04422 DISPOSE(tempfile, -1); 04423 /* It's easier just to try to make it than to check for its existence */ 04424 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 04425 04426 /* Check current or macro-calling context for special extensions */ 04427 if (ast_test_flag(vmu, VM_OPERATOR)) { 04428 if (!ast_strlen_zero(vmu->exit)) { 04429 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 04430 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 04431 ouseexten = 1; 04432 } 04433 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 04434 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 04435 ouseexten = 1; 04436 } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 04437 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 04438 ousemacro = 1; 04439 } 04440 } 04441 04442 if (!ast_strlen_zero(vmu->exit)) { 04443 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) { 04444 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 04445 } 04446 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) { 04447 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 04448 } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 04449 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 04450 ausemacro = 1; 04451 } 04452 04453 if (ast_test_flag(options, OPT_DTMFEXIT)) { 04454 for (code = alldtmf; *code; code++) { 04455 char e[2] = ""; 04456 e[0] = *code; 04457 if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) { 04458 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 04459 } 04460 } 04461 } 04462 04463 /* Play the beginning intro if desired */ 04464 if (!ast_strlen_zero(prefile)) { 04465 res = play_greeting(chan, vmu, prefile, ecodes); 04466 if (res == -2) { 04467 /* The file did not exist */ 04468 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 04469 res = invent_message(chan, vmu, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 04470 } 04471 if (res < 0) { 04472 ast_debug(1, "Hang up during prefile playback\n"); 04473 free_user(vmu); 04474 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04475 ast_free(tmp); 04476 return -1; 04477 } 04478 } 04479 if (res == '#') { 04480 /* On a '#' we skip the instructions */ 04481 ast_set_flag(options, OPT_SILENT); 04482 res = 0; 04483 } 04484 if (!res && !ast_test_flag(options, OPT_SILENT)) { 04485 res = ast_stream_and_wait(chan, INTRO, ecodes); 04486 if (res == '#') { 04487 ast_set_flag(options, OPT_SILENT); 04488 res = 0; 04489 } 04490 } 04491 if (res > 0) { 04492 ast_stopstream(chan); 04493 } 04494 /* Check for a '*' here in case the caller wants to escape from voicemail to something 04495 * other than the operator -- an automated attendant or mailbox login for example */ 04496 if (res == '*') { 04497 chan->exten[0] = 'a'; 04498 chan->exten[1] = '\0'; 04499 if (!ast_strlen_zero(vmu->exit)) { 04500 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 04501 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 04502 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 04503 } 04504 chan->priority = 0; 04505 free_user(vmu); 04506 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 04507 ast_free(tmp); 04508 return 0; 04509 } 04510 04511 /* Check for a '0' here */ 04512 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 04513 transfer: 04514 if (ouseexten || ousemacro) { 04515 chan->exten[0] = 'o'; 04516 chan->exten[1] = '\0'; 04517 if (!ast_strlen_zero(vmu->exit)) { 04518 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 04519 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 04520 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 04521 } 04522 ast_play_and_wait(chan, "transfer"); 04523 chan->priority = 0; 04524 free_user(vmu); 04525 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 04526 } 04527 ast_free(tmp); 04528 return 0; 04529 } 04530 04531 /* Allow all other digits to exit Voicemail and return to the dialplan */ 04532 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 04533 if (!ast_strlen_zero(options->exitcontext)) { 04534 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 04535 } 04536 free_user(vmu); 04537 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 04538 return res; 04539 } 04540 04541 if (res < 0) { 04542 free_user(vmu); 04543 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04544 ast_free(tmp); 04545 return -1; 04546 } 04547 /* The meat of recording the message... All the announcements and beeps have been played*/ 04548 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 04549 if (!ast_strlen_zero(fmt)) { 04550 msgnum = 0; 04551 04552 #ifdef IMAP_STORAGE 04553 /* Is ext a mailbox? */ 04554 /* must open stream for this user to get info! */ 04555 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 04556 if (res < 0) { 04557 ast_log(LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 04558 ast_free(tmp); 04559 return -1; 04560 } 04561 if (!(vms = get_vm_state_by_mailbox(ext, 0))) { 04562 /* It is possible under certain circumstances that inboxcount did not 04563 * create a vm_state when it was needed. This is a catchall which will 04564 * rarely be used. 04565 */ 04566 if (!(vms = create_vm_state_from_user(vmu))) { 04567 ast_log(LOG_ERROR, "Couldn't allocate necessary space\n"); 04568 ast_free(tmp); 04569 return -1; 04570 } 04571 } 04572 vms->newmessages++; 04573 04574 /* here is a big difference! We add one to it later */ 04575 msgnum = newmsgs + oldmsgs; 04576 ast_debug(3, "Messagecount set to %d\n", msgnum); 04577 snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 04578 /* set variable for compatibility */ 04579 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 04580 04581 /* Check if mailbox is full */ 04582 check_quota(vms, imapfolder); 04583 if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) { 04584 ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit); 04585 ast_play_and_wait(chan, "vm-mailboxfull"); 04586 ast_free(tmp); 04587 return -1; 04588 } 04589 04590 /* Check if we have exceeded maxmsg */ 04591 if (msgnum >= vmu->maxmsg) { 04592 ast_log(LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg); 04593 ast_play_and_wait(chan, "vm-mailboxfull"); 04594 ast_free(tmp); 04595 return -1; 04596 } 04597 #else 04598 if (count_messages(vmu, dir) >= vmu->maxmsg) { 04599 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 04600 if (!res) { 04601 res = ast_waitstream(chan, ""); 04602 } 04603 ast_log(LOG_WARNING, "No more messages possible\n"); 04604 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04605 goto leave_vm_out; 04606 } 04607 04608 #endif 04609 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 04610 txtdes = mkstemp(tmptxtfile); 04611 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 04612 if (txtdes < 0) { 04613 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 04614 if (!res) { 04615 res = ast_waitstream(chan, ""); 04616 } 04617 ast_log(LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 04618 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04619 goto leave_vm_out; 04620 } 04621 04622 /* Now play the beep once we have the message number for our next message. */ 04623 if (res >= 0) { 04624 /* Unless we're *really* silent, try to send the beep */ 04625 res = ast_stream_and_wait(chan, "beep", ""); 04626 } 04627 04628 /* Store information in real-time storage */ 04629 if (ast_check_realtime("voicemail_data")) { 04630 snprintf(priority, sizeof(priority), "%d", chan->priority); 04631 snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL)); 04632 get_date(date, sizeof(date)); 04633 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", category ? category : "", NULL); 04634 } 04635 04636 /* Store information */ 04637 txt = fdopen(txtdes, "w+"); 04638 if (txt) { 04639 get_date(date, sizeof(date)); 04640 fprintf(txt, 04641 ";\n" 04642 "; Message Information file\n" 04643 ";\n" 04644 "[message]\n" 04645 "origmailbox=%s\n" 04646 "context=%s\n" 04647 "macrocontext=%s\n" 04648 "exten=%s\n" 04649 "priority=%d\n" 04650 "callerchan=%s\n" 04651 "callerid=%s\n" 04652 "origdate=%s\n" 04653 "origtime=%ld\n" 04654 "category=%s\n", 04655 ext, 04656 chan->context, 04657 chan->macrocontext, 04658 chan->exten, 04659 chan->priority, 04660 chan->name, 04661 ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"), 04662 date, (long)time(NULL), 04663 category ? category : ""); 04664 } else { 04665 ast_log(LOG_WARNING, "Error opening text file for output\n"); 04666 } 04667 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms); 04668 04669 if (txt) { 04670 if (duration < vmminsecs) { 04671 fclose(txt); 04672 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs); 04673 ast_filedelete(tmptxtfile, NULL); 04674 unlink(tmptxtfile); 04675 if (ast_check_realtime("voicemail_data")) { 04676 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 04677 ast_destroy_realtime("voicemail_data", "id", tmpid, NULL); 04678 } 04679 } else { 04680 fprintf(txt, "duration=%d\n", duration); 04681 fclose(txt); 04682 if (vm_lock_path(dir)) { 04683 ast_log(LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 04684 /* Delete files */ 04685 ast_filedelete(tmptxtfile, NULL); 04686 unlink(tmptxtfile); 04687 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 04688 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 04689 unlink(tmptxtfile); 04690 ast_unlock_path(dir); 04691 if (ast_check_realtime("voicemail_data")) { 04692 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 04693 ast_destroy_realtime("voicemail_data", "id", tmpid, NULL); 04694 } 04695 } else { 04696 #ifndef IMAP_STORAGE 04697 msgnum = last_message_index(vmu, dir) + 1; 04698 #endif 04699 make_file(fn, sizeof(fn), dir, msgnum); 04700 04701 /* assign a variable with the name of the voicemail file */ 04702 #ifndef IMAP_STORAGE 04703 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 04704 #else 04705 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 04706 #endif 04707 04708 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 04709 ast_filerename(tmptxtfile, fn, NULL); 04710 rename(tmptxtfile, txtfile); 04711 04712 /* Properly set permissions on voicemail text descriptor file. 04713 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 04714 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) { 04715 ast_log(LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 04716 } 04717 04718 ast_unlock_path(dir); 04719 if (ast_check_realtime("voicemail_data")) { 04720 snprintf(tmpid, sizeof(tmpid), "%d", rtmsgid); 04721 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 04722 ast_update_realtime("voicemail_data", "id", tmpid, "filename", fn, "duration", tmpdur, NULL); 04723 } 04724 /* We must store the file first, before copying the message, because 04725 * ODBC storage does the entire copy with SQL. 04726 */ 04727 if (ast_fileexists(fn, NULL, NULL) > 0) { 04728 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms); 04729 } 04730 04731 /* Are there to be more recipients of this message? */ 04732 while (tmpptr) { 04733 struct ast_vm_user recipu, *recip; 04734 char *exten, *context; 04735 04736 exten = strsep(&tmpptr, "&"); 04737 context = strchr(exten, '@'); 04738 if (context) { 04739 *context = '\0'; 04740 context++; 04741 } 04742 if ((recip = find_user(&recipu, context, exten))) { 04743 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir); 04744 free_user(recip); 04745 } 04746 } 04747 /* Notification and disposal needs to happen after the copy, though. */ 04748 if (ast_fileexists(fn, NULL, NULL)) { 04749 #ifdef IMAP_STORAGE 04750 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL)); 04751 #else 04752 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL)); 04753 #endif 04754 DISPOSE(dir, msgnum); 04755 } 04756 } 04757 } 04758 } 04759 if (res == '0') { 04760 goto transfer; 04761 } else if (res > 0) { 04762 res = 0; 04763 } 04764 04765 if (duration < vmminsecs) { 04766 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 04767 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 04768 } else { 04769 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 04770 } 04771 } else { 04772 ast_log(LOG_WARNING, "No format for saving voicemail?\n"); 04773 } 04774 leave_vm_out: 04775 free_user(vmu); 04776 04777 ast_free(tmp); 04778 return res; 04779 }
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 9194 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_false(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, ast_vm_user::context, 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(), ast_variable::lineno, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, LOG_ERROR, LOG_WARNING, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, vm_zone::msg_format, vm_zone::name, ast_variable::name, ast_variable::next, pagerbody, pagerfromstring, pagersubject, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, saydurationminfo, SENDMAIL, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), vm_zone::timezone, ast_variable::value, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_pls_try_again, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.
09195 { 09196 struct ast_vm_user *cur; 09197 struct ast_config *cfg, *ucfg; 09198 char *cat; 09199 struct ast_variable *var; 09200 const char *val; 09201 char *q, *stringp; 09202 int x; 09203 int tmpadsi[4]; 09204 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 09205 09206 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 09207 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) 09208 return 0; 09209 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 09210 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 09211 } else { 09212 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 09213 ucfg = ast_config_load("users.conf", config_flags); 09214 } 09215 #ifdef IMAP_STORAGE 09216 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 09217 #endif 09218 /* set audio control prompts */ 09219 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 09220 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 09221 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 09222 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 09223 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 09224 09225 /* Free all the users structure */ 09226 free_vm_users(); 09227 09228 /* Free all the zones structure */ 09229 free_vm_zones(); 09230 09231 AST_LIST_LOCK(&users); 09232 09233 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 09234 09235 if (cfg) { 09236 /* General settings */ 09237 09238 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 09239 val = "default"; 09240 ast_copy_string(userscontext, val, sizeof(userscontext)); 09241 /* Attach voice message to mail message ? */ 09242 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 09243 val = "yes"; 09244 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 09245 09246 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 09247 val = "no"; 09248 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 09249 09250 volgain = 0.0; 09251 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 09252 sscanf(val, "%30lf", &volgain); 09253 09254 #ifdef ODBC_STORAGE 09255 strcpy(odbc_database, "asterisk"); 09256 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 09257 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 09258 } 09259 strcpy(odbc_table, "voicemessages"); 09260 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 09261 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 09262 } 09263 #endif 09264 /* Mail command */ 09265 strcpy(mailcmd, SENDMAIL); 09266 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 09267 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 09268 09269 maxsilence = 0; 09270 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 09271 maxsilence = atoi(val); 09272 if (maxsilence > 0) 09273 maxsilence *= 1000; 09274 } 09275 09276 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 09277 maxmsg = MAXMSG; 09278 } else { 09279 maxmsg = atoi(val); 09280 if (maxmsg <= 0) { 09281 ast_log(LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 09282 maxmsg = MAXMSG; 09283 } else if (maxmsg > MAXMSGLIMIT) { 09284 ast_log(LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 09285 maxmsg = MAXMSGLIMIT; 09286 } 09287 } 09288 09289 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 09290 maxdeletedmsg = 0; 09291 } else { 09292 if (sscanf(val, "%30d", &x) == 1) 09293 maxdeletedmsg = x; 09294 else if (ast_true(val)) 09295 maxdeletedmsg = MAXMSG; 09296 else 09297 maxdeletedmsg = 0; 09298 09299 if (maxdeletedmsg < 0) { 09300 ast_log(LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 09301 maxdeletedmsg = MAXMSG; 09302 } else if (maxdeletedmsg > MAXMSGLIMIT) { 09303 ast_log(LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 09304 maxdeletedmsg = MAXMSGLIMIT; 09305 } 09306 } 09307 09308 /* Load date format config for voicemail mail */ 09309 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 09310 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 09311 } 09312 09313 /* External password changing command */ 09314 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 09315 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 09316 pwdchange = PWDCHANGE_EXTERNAL; 09317 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 09318 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 09319 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 09320 } 09321 09322 #ifdef IMAP_STORAGE 09323 /* IMAP server address */ 09324 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 09325 ast_copy_string(imapserver, val, sizeof(imapserver)); 09326 } else { 09327 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 09328 } 09329 /* IMAP server port */ 09330 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 09331 ast_copy_string(imapport, val, sizeof(imapport)); 09332 } else { 09333 ast_copy_string(imapport, "143", sizeof(imapport)); 09334 } 09335 /* IMAP server flags */ 09336 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 09337 ast_copy_string(imapflags, val, sizeof(imapflags)); 09338 } 09339 /* IMAP server master username */ 09340 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 09341 ast_copy_string(authuser, val, sizeof(authuser)); 09342 } 09343 /* IMAP server master password */ 09344 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 09345 ast_copy_string(authpassword, val, sizeof(authpassword)); 09346 } 09347 /* Expunge on exit */ 09348 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 09349 if (ast_false(val)) 09350 expungeonhangup = 0; 09351 else 09352 expungeonhangup = 1; 09353 } else { 09354 expungeonhangup = 1; 09355 } 09356 /* IMAP voicemail folder */ 09357 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 09358 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 09359 } else { 09360 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 09361 } 09362 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 09363 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 09364 } 09365 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 09366 imapgreetings = ast_true(val); 09367 } else { 09368 imapgreetings = 0; 09369 } 09370 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 09371 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 09372 } else { 09373 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 09374 } 09375 09376 /* There is some very unorthodox casting done here. This is due 09377 * to the way c-client handles the argument passed in. It expects a 09378 * void pointer and casts the pointer directly to a long without 09379 * first dereferencing it. */ 09380 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 09381 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 09382 } else { 09383 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 09384 } 09385 09386 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 09387 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 09388 } else { 09389 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 09390 } 09391 09392 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 09393 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 09394 } else { 09395 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 09396 } 09397 09398 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 09399 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 09400 } else { 09401 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 09402 } 09403 09404 /* Increment configuration version */ 09405 imapversion++; 09406 #endif 09407 /* External voicemail notify application */ 09408 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 09409 ast_copy_string(externnotify, val, sizeof(externnotify)); 09410 ast_debug(1, "found externnotify: %s\n", externnotify); 09411 } else { 09412 externnotify[0] = '\0'; 09413 } 09414 09415 /* SMDI voicemail notification */ 09416 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 09417 ast_debug(1, "Enabled SMDI voicemail notification\n"); 09418 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 09419 smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find(val) : NULL; 09420 } else { 09421 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 09422 smdi_iface = ast_smdi_interface_find ? ast_smdi_interface_find("/dev/ttyS0") : NULL; 09423 } 09424 if (!smdi_iface) { 09425 ast_log(LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 09426 } 09427 } 09428 09429 /* Silence treshold */ 09430 silencethreshold = 256; 09431 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 09432 silencethreshold = atoi(val); 09433 09434 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 09435 val = ASTERISK_USERNAME; 09436 ast_copy_string(serveremail, val, sizeof(serveremail)); 09437 09438 vmmaxsecs = 0; 09439 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 09440 if (sscanf(val, "%30d", &x) == 1) { 09441 vmmaxsecs = x; 09442 } else { 09443 ast_log(LOG_WARNING, "Invalid max message time length\n"); 09444 } 09445 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 09446 static int maxmessage_deprecate = 0; 09447 if (maxmessage_deprecate == 0) { 09448 maxmessage_deprecate = 1; 09449 ast_log(LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 09450 } 09451 if (sscanf(val, "%30d", &x) == 1) { 09452 vmmaxsecs = x; 09453 } else { 09454 ast_log(LOG_WARNING, "Invalid max message time length\n"); 09455 } 09456 } 09457 09458 vmminsecs = 0; 09459 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 09460 if (sscanf(val, "%30d", &x) == 1) { 09461 vmminsecs = x; 09462 if (maxsilence / 1000 >= vmminsecs) { 09463 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 09464 } 09465 } else { 09466 ast_log(LOG_WARNING, "Invalid min message time length\n"); 09467 } 09468 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 09469 static int maxmessage_deprecate = 0; 09470 if (maxmessage_deprecate == 0) { 09471 maxmessage_deprecate = 1; 09472 ast_log(LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 09473 } 09474 if (sscanf(val, "%30d", &x) == 1) { 09475 vmminsecs = x; 09476 if (maxsilence / 1000 >= vmminsecs) { 09477 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 09478 } 09479 } else { 09480 ast_log(LOG_WARNING, "Invalid min message time length\n"); 09481 } 09482 } 09483 09484 val = ast_variable_retrieve(cfg, "general", "format"); 09485 if (!val) 09486 val = "wav"; 09487 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 09488 09489 skipms = 3000; 09490 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 09491 if (sscanf(val, "%30d", &x) == 1) { 09492 maxgreet = x; 09493 } else { 09494 ast_log(LOG_WARNING, "Invalid max message greeting length\n"); 09495 } 09496 } 09497 09498 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 09499 if (sscanf(val, "%30d", &x) == 1) { 09500 skipms = x; 09501 } else { 09502 ast_log(LOG_WARNING, "Invalid skipms value\n"); 09503 } 09504 } 09505 09506 maxlogins = 3; 09507 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 09508 if (sscanf(val, "%30d", &x) == 1) { 09509 maxlogins = x; 09510 } else { 09511 ast_log(LOG_WARNING, "Invalid max failed login attempts\n"); 09512 } 09513 } 09514 09515 /* Force new user to record name ? */ 09516 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 09517 val = "no"; 09518 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 09519 09520 /* Force new user to record greetings ? */ 09521 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 09522 val = "no"; 09523 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 09524 09525 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 09526 ast_debug(1, "VM_CID Internal context string: %s\n", val); 09527 stringp = ast_strdupa(val); 09528 for (x = 0; x < MAX_NUM_CID_CONTEXTS; x++) { 09529 if (!ast_strlen_zero(stringp)) { 09530 q = strsep(&stringp, ","); 09531 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 09532 q++; 09533 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 09534 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 09535 } else { 09536 cidinternalcontexts[x][0] = '\0'; 09537 } 09538 } 09539 } 09540 if (!(val = ast_variable_retrieve(cfg, "general", "review"))) { 09541 ast_debug(1, "VM Review Option disabled globally\n"); 09542 val = "no"; 09543 } 09544 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 09545 09546 /* Temporary greeting reminder */ 09547 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 09548 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 09549 val = "no"; 09550 } else { 09551 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 09552 } 09553 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 09554 09555 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))) { 09556 ast_debug(1, "VM Operator break disabled globally\n"); 09557 val = "no"; 09558 } 09559 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 09560 09561 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 09562 ast_debug(1, "VM CID Info before msg disabled globally\n"); 09563 val = "no"; 09564 } 09565 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 09566 09567 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))) { 09568 ast_debug(1, "Send Voicemail msg disabled globally\n"); 09569 val = "no"; 09570 } 09571 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 09572 09573 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 09574 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 09575 val = "yes"; 09576 } 09577 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 09578 09579 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 09580 ast_debug(1, "Move Heard enabled globally\n"); 09581 val = "yes"; 09582 } 09583 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 09584 09585 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 09586 ast_debug(1, "Duration info before msg enabled globally\n"); 09587 val = "yes"; 09588 } 09589 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 09590 09591 saydurationminfo = 2; 09592 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 09593 if (sscanf(val, "%30d", &x) == 1) { 09594 saydurationminfo = x; 09595 } else { 09596 ast_log(LOG_WARNING, "Invalid min duration for say duration\n"); 09597 } 09598 } 09599 09600 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 09601 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 09602 val = "no"; 09603 } 09604 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 09605 09606 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 09607 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 09608 ast_debug(1, "found dialout context: %s\n", dialcontext); 09609 } else { 09610 dialcontext[0] = '\0'; 09611 } 09612 09613 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 09614 ast_copy_string(callcontext, val, sizeof(callcontext)); 09615 ast_debug(1, "found callback context: %s\n", callcontext); 09616 } else { 09617 callcontext[0] = '\0'; 09618 } 09619 09620 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 09621 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 09622 ast_debug(1, "found operator context: %s\n", exitcontext); 09623 } else { 09624 exitcontext[0] = '\0'; 09625 } 09626 09627 /* load password sounds configuration */ 09628 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 09629 ast_copy_string(vm_password, val, sizeof(vm_password)); 09630 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 09631 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 09632 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 09633 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 09634 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 09635 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 09636 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 09637 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 09638 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 09639 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 09640 } 09641 /* load configurable audio prompts */ 09642 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 09643 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 09644 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 09645 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 09646 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 09647 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 09648 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 09649 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 09650 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 09651 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 09652 09653 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 09654 val = "no"; 09655 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 09656 09657 poll_freq = DEFAULT_POLL_FREQ; 09658 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 09659 if (sscanf(val, "%30u", &poll_freq) != 1) { 09660 poll_freq = DEFAULT_POLL_FREQ; 09661 ast_log(LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 09662 } 09663 } 09664 09665 poll_mailboxes = 0; 09666 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 09667 poll_mailboxes = ast_true(val); 09668 09669 if (ucfg) { 09670 for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) { 09671 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 09672 continue; 09673 if ((cur = find_or_create(userscontext, cat))) { 09674 populate_defaults(cur); 09675 apply_options_full(cur, ast_variable_browse(ucfg, cat)); 09676 ast_copy_string(cur->context, userscontext, sizeof(cur->context)); 09677 } 09678 } 09679 ast_config_destroy(ucfg); 09680 } 09681 cat = ast_category_browse(cfg, NULL); 09682 while (cat) { 09683 if (strcasecmp(cat, "general")) { 09684 var = ast_variable_browse(cfg, cat); 09685 if (strcasecmp(cat, "zonemessages")) { 09686 /* Process mailboxes in this context */ 09687 while (var) { 09688 append_mailbox(cat, var->name, var->value); 09689 var = var->next; 09690 } 09691 } else { 09692 /* Timezones in this context */ 09693 while (var) { 09694 struct vm_zone *z; 09695 if ((z = ast_malloc(sizeof(*z)))) { 09696 char *msg_format, *timezone; 09697 msg_format = ast_strdupa(var->value); 09698 timezone = strsep(&msg_format, "|"); 09699 if (msg_format) { 09700 ast_copy_string(z->name, var->name, sizeof(z->name)); 09701 ast_copy_string(z->timezone, timezone, sizeof(z->timezone)); 09702 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 09703 AST_LIST_LOCK(&zones); 09704 AST_LIST_INSERT_HEAD(&zones, z, list); 09705 AST_LIST_UNLOCK(&zones); 09706 } else { 09707 ast_log(LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 09708 ast_free(z); 09709 } 09710 } else { 09711 AST_LIST_UNLOCK(&users); 09712 ast_config_destroy(cfg); 09713 return -1; 09714 } 09715 var = var->next; 09716 } 09717 } 09718 } 09719 cat = ast_category_browse(cfg, cat); 09720 } 09721 memset(fromstring, 0, sizeof(fromstring)); 09722 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 09723 strcpy(charset, "ISO-8859-1"); 09724 if (emailbody) { 09725 ast_free(emailbody); 09726 emailbody = NULL; 09727 } 09728 if (emailsubject) { 09729 ast_free(emailsubject); 09730 emailsubject = NULL; 09731 } 09732 if (pagerbody) { 09733 ast_free(pagerbody); 09734 pagerbody = NULL; 09735 } 09736 if (pagersubject) { 09737 ast_free(pagersubject); 09738 pagersubject = NULL; 09739 } 09740 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 09741 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 09742 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 09743 ast_copy_string(fromstring, val, sizeof(fromstring)); 09744 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 09745 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 09746 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 09747 ast_copy_string(charset, val, sizeof(charset)); 09748 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 09749 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 09750 for (x = 0; x < 4; x++) { 09751 memcpy(&adsifdn[x], &tmpadsi[x], 1); 09752 } 09753 } 09754 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 09755 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 09756 for (x = 0; x < 4; x++) { 09757 memcpy(&adsisec[x], &tmpadsi[x], 1); 09758 } 09759 } 09760 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 09761 if (atoi(val)) { 09762 adsiver = atoi(val); 09763 } 09764 } 09765 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 09766 ast_copy_string(zonetag, val, sizeof(zonetag)); 09767 } 09768 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 09769 emailsubject = ast_strdup(val); 09770 } 09771 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 09772 emailbody = substitute_escapes(val); 09773 } 09774 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 09775 pagersubject = ast_strdup(val); 09776 } 09777 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 09778 pagerbody = substitute_escapes(val); 09779 } 09780 AST_LIST_UNLOCK(&users); 09781 ast_config_destroy(cfg); 09782 09783 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 09784 start_poll_thread(); 09785 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 09786 stop_poll_thread();; 09787 09788 return 0; 09789 } else { 09790 AST_LIST_UNLOCK(&users); 09791 ast_log(LOG_WARNING, "Failed to load configuration file.\n"); 09792 if (ucfg) 09793 ast_config_destroy(ucfg); 09794 return 0; 09795 } 09796 }
| static int load_module | ( | void | ) | [static] |
Definition at line 9825 of file app_voicemail.c.
References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_install_vm_functions(), ast_manager_register, ast_register_application, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().
09826 { 09827 int res; 09828 my_umask = umask(0); 09829 umask(my_umask); 09830 09831 /* compute the location of the voicemail spool directory */ 09832 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 09833 09834 if ((res = load_config(0))) 09835 return res; 09836 09837 res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm); 09838 res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain); 09839 res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists); 09840 res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate); 09841 res |= ast_custom_function_register(&mailbox_exists_acf); 09842 res |= ast_manager_register("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users, "List All Voicemail User Information"); 09843 if (res) 09844 return res; 09845 09846 ast_cli_register_multiple(cli_voicemail, sizeof(cli_voicemail) / sizeof(struct ast_cli_entry)); 09847 09848 ast_install_vm_functions(has_voicemail, inboxcount, messagecount); 09849 09850 return res; 09851 }
| static int make_dir | ( | char * | dest, | |
| int | len, | |||
| const char * | context, | |||
| const char * | ext, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 1072 of file app_voicemail.c.
01073 { 01074 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01075 }
| 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 * | format, | |||
| int | duration, | |||
| int | attach_user_voicemail, | |||
| struct ast_channel * | chan, | |||
| const char * | category, | |||
| int | imap | |||
| ) | [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 3512 of file app_voicemail.c.
References ast_channel_alloc, ast_channel_free(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), base_encode(), charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, create_dirpath(), ast_vm_user::email, emailbody, emaildateformat, emailsubject, encode_mime_str(), ENDL, fromstring, ast_vm_user::fullname, globalflags, LOG_WARNING, 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, vmu_tm(), VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
Referenced by sendmail().
03513 { 03514 char date[256]; 03515 char host[MAXHOSTNAMELEN] = ""; 03516 char who[256]; 03517 char bound[256]; 03518 char fname[256]; 03519 char dur[256]; 03520 char tmpcmd[256]; 03521 struct ast_tm tm; 03522 char enc_cidnum[256] = "", enc_cidname[256] = ""; 03523 char *passdata = NULL, *passdata2; 03524 size_t len_passdata = 0, len_passdata2, tmplen; 03525 char *greeting_attachment; 03526 03527 #ifdef IMAP_STORAGE 03528 #define ENDL "\r\n" 03529 #else 03530 #define ENDL "\n" 03531 #endif 03532 03533 /* One alloca for multiple fields */ 03534 len_passdata2 = strlen(vmu->fullname); 03535 if (emailsubject && (tmplen = strlen(emailsubject)) > len_passdata2) { 03536 len_passdata2 = tmplen; 03537 } 03538 if ((tmplen = strlen(fromstring)) > len_passdata2) { 03539 len_passdata2 = tmplen; 03540 } 03541 len_passdata2 = len_passdata2 * 3 + 200; 03542 passdata2 = alloca(len_passdata2); 03543 03544 if (!ast_strlen_zero(cidnum)) { 03545 strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum)); 03546 } 03547 if (!ast_strlen_zero(cidname)) { 03548 strip_control(cidname, enc_cidname, sizeof(enc_cidname)); 03549 } 03550 gethostname(host, sizeof(host) - 1); 03551 03552 if (strchr(srcemail, '@')) 03553 ast_copy_string(who, srcemail, sizeof(who)); 03554 else 03555 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 03556 03557 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 03558 if (greeting_attachment) 03559 *greeting_attachment++ = '\0'; 03560 03561 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 03562 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 03563 fprintf(p, "Date: %s" ENDL, date); 03564 03565 /* Set date format for voicemail mail */ 03566 ast_strftime(date, sizeof(date), emaildateformat, &tm); 03567 03568 if (!ast_strlen_zero(fromstring)) { 03569 struct ast_channel *ast; 03570 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 03571 char *ptr; 03572 memset(passdata2, 0, len_passdata2); 03573 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, passdata2, len_passdata2, category); 03574 pbx_substitute_variables_helper(ast, fromstring, passdata2, len_passdata2); 03575 len_passdata = strlen(passdata2) * 3 + 300; 03576 passdata = alloca(len_passdata); 03577 if (check_mime(passdata2)) { 03578 int first_line = 1; 03579 encode_mime_str(passdata2, passdata, len_passdata, strlen("From: "), strlen(who) + 3); 03580 while ((ptr = strchr(passdata, ' '))) { 03581 *ptr = '\0'; 03582 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", passdata); 03583 first_line = 0; 03584 passdata = ptr + 1; 03585 } 03586 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", passdata, who); 03587 } else { 03588 fprintf(p, "From: %s <%s>" ENDL, quote(passdata2, passdata, len_passdata), who); 03589 } 03590 ast_channel_free(ast); 03591 } else { 03592 ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 03593 } 03594 } else { 03595 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 03596 } 03597 03598 if (check_mime(vmu->fullname)) { 03599 int first_line = 1; 03600 char *ptr; 03601 encode_mime_str(vmu->fullname, passdata2, len_passdata2, strlen("To: "), strlen(vmu->email) + 3); 03602 while ((ptr = strchr(passdata2, ' '))) { 03603 *ptr = '\0'; 03604 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", passdata2); 03605 first_line = 0; 03606 passdata2 = ptr + 1; 03607 } 03608 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", passdata2, vmu->email); 03609 } else { 03610 fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata2), vmu->email); 03611 } 03612 if (!ast_strlen_zero(emailsubject)) { 03613 struct ast_channel *ast; 03614 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 03615 int vmlen = strlen(emailsubject) * 3 + 200; 03616 /* Only allocate more space if the previous was not large enough */ 03617 if (vmlen > len_passdata) { 03618 passdata = alloca(vmlen); 03619 len_passdata = vmlen; 03620 } 03621 03622 memset(passdata, 0, len_passdata); 03623 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, len_passdata, category); 03624 pbx_substitute_variables_helper(ast, emailsubject, passdata, len_passdata); 03625 if (check_mime(passdata)) { 03626 int first_line = 1; 03627 char *ptr; 03628 encode_mime_str(passdata, passdata2, len_passdata2, strlen("Subject: "), 0); 03629 while ((ptr = strchr(passdata2, ' '))) { 03630 *ptr = '\0'; 03631 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 03632 first_line = 0; 03633 passdata2 = ptr + 1; 03634 } 03635 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", passdata2); 03636 } else { 03637 fprintf(p, "Subject: %s" ENDL, passdata); 03638 } 03639 ast_channel_free(ast); 03640 } else { 03641 ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 03642 } 03643 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 03644 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 03645 } else { 03646 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 03647 } 03648 03649 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, (unsigned int)ast_random(), mailbox, (int)getpid(), host); 03650 if (imap) { 03651 /* additional information needed for IMAP searching */ 03652 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 03653 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 03654 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 03655 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 03656 #ifdef IMAP_STORAGE 03657 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 03658 #else 03659 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 03660 #endif 03661 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 03662 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 03663 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 03664 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 03665 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 03666 if (!ast_strlen_zero(category)) { 03667 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 03668 } else { 03669 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 03670 } 03671 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 03672 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 03673 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long)time(NULL)); 03674 } 03675 if (!ast_strlen_zero(cidnum)) { 03676 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 03677 } 03678 if (!ast_strlen_zero(cidname)) { 03679 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 03680 } 03681 fprintf(p, "MIME-Version: 1.0" ENDL); 03682 if (attach_user_voicemail) { 03683 /* Something unique. */ 03684 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, (int)getpid(), (unsigned int)ast_random()); 03685 03686 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 03687 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 03688 fprintf(p, "--%s" ENDL, bound); 03689 } 03690 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 03691 if (emailbody) { 03692 struct ast_channel *ast; 03693 if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Substitution/voicemail"))) { 03694 char *passdata; 03695 int vmlen = strlen(emailbody) * 3 + 200; 03696 passdata = alloca(vmlen); 03697 memset(passdata, 0, vmlen); 03698 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, passdata, vmlen, category); 03699 pbx_substitute_variables_helper(ast, emailbody, passdata, vmlen); 03700 fprintf(p, "%s" ENDL, passdata); 03701 ast_channel_free(ast); 03702 } else 03703 ast_log(LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 03704 } else if (msgnum > -1) { 03705 if (strcmp(vmu->mailbox, mailbox)) { 03706 /* Forwarded type */ 03707 struct ast_config *msg_cfg; 03708 const char *v; 03709 int inttime; 03710 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 03711 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 03712 /* Retrieve info from VM attribute file */ 03713 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 03714 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 03715 if (strlen(fromfile) < sizeof(fromfile) - 5) { 03716 strcat(fromfile, ".txt"); 03717 } 03718 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 03719 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 03720 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 03721 } 03722 03723 /* You might be tempted to do origdate, except that a) it's in the wrong 03724 * format, and b) it's missing for IMAP recordings. */ 03725 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 03726 struct timeval tv = { inttime, }; 03727 struct ast_tm tm; 03728 ast_localtime(&tv, &tm, NULL); 03729 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 03730 } 03731 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 03732 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 03733 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 03734 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 03735 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 03736 date, origcallerid, origdate); 03737 ast_config_destroy(msg_cfg); 03738 } else { 03739 goto plain_message; 03740 } 03741 } else { 03742 plain_message: 03743 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 03744 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 03745 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 03746 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 03747 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 03748 } 03749 } else { 03750 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 03751 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 03752 } 03753 if (attach_user_voicemail) { 03754 /* Eww. We want formats to tell us their own MIME type */ 03755 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 03756 char tmpdir[256], newtmp[256]; 03757 int tmpfd = -1; 03758 03759 if (vmu->volgain < -.001 || vmu->volgain > .001) { 03760 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 03761 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 03762 tmpfd = mkstemp(newtmp); 03763 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 03764 ast_debug(3, "newtmp: %s\n", newtmp); 03765 if (tmpfd > -1) { 03766 int soxstatus; 03767 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 03768 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 03769 attach = newtmp; 03770 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 03771 } else { 03772 ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 03773 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 03774 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 03775 } 03776 } 03777 } 03778 fprintf(p, "--%s" ENDL, bound); 03779 if (msgnum > -1) 03780 fprintf(p, "Content-Type: %s%s; name=\"msg%04d.%s\"" ENDL, ctype, format, msgnum + 1, format); 03781 else 03782 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 03783 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 03784 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 03785 if (msgnum > -1) 03786 fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"" ENDL ENDL, msgnum + 1, format); 03787 else 03788 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 03789 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 03790 base_encode(fname, p); 03791 fprintf(p, ENDL "--%s--" ENDL "." ENDL, bound); 03792 if (tmpfd > -1) { 03793 unlink(fname); 03794 close(tmpfd); 03795 unlink(newtmp); 03796 } 03797 } 03798 #undef ENDL 03799 }
| 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 1087 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), resequence_mailbox(), 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 9026 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::mailbox, ast_vm_user::mailcmd, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, ast_vm_user::saydurationm, ast_vm_user::serveremail, ast_vm_user::uniqueid, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_OPERATOR, VM_REVIEW, VM_SAYCID, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by load_module().
09027 { 09028 struct ast_vm_user *vmu = NULL; 09029 const char *id = astman_get_header(m, "ActionID"); 09030 char actionid[128] = ""; 09031 09032 if (!ast_strlen_zero(id)) 09033 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 09034 09035 AST_LIST_LOCK(&users); 09036 09037 if (AST_LIST_EMPTY(&users)) { 09038 astman_send_ack(s, m, "There are no voicemail users currently defined."); 09039 AST_LIST_UNLOCK(&users); 09040 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 09041 return RESULT_SUCCESS; 09042 } 09043 09044 astman_send_ack(s, m, "Voicemail user list will follow"); 09045 09046 AST_LIST_TRAVERSE(&users, vmu, list) { 09047 char dirname[256]; 09048 09049 #ifdef IMAP_STORAGE 09050 int new, old; 09051 inboxcount (vmu->mailbox, &new, &old); 09052 #endif 09053 09054 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 09055 astman_append(s, 09056 "%s" 09057 "Event: VoicemailUserEntry\r\n" 09058 "VMContext: %s\r\n" 09059 "VoiceMailbox: %s\r\n" 09060 "Fullname: %s\r\n" 09061 "Email: %s\r\n" 09062 "Pager: %s\r\n" 09063 "ServerEmail: %s\r\n" 09064 "MailCommand: %s\r\n" 09065 "Language: %s\r\n" 09066 "TimeZone: %s\r\n" 09067 "Callback: %s\r\n" 09068 "Dialout: %s\r\n" 09069 "UniqueID: %s\r\n" 09070 "ExitContext: %s\r\n" 09071 "SayDurationMinimum: %d\r\n" 09072 "SayEnvelope: %s\r\n" 09073 "SayCID: %s\r\n" 09074 "AttachMessage: %s\r\n" 09075 "AttachmentFormat: %s\r\n" 09076 "DeleteMessage: %s\r\n" 09077 "VolumeGain: %.2f\r\n" 09078 "CanReview: %s\r\n" 09079 "CallOperator: %s\r\n" 09080 "MaxMessageCount: %d\r\n" 09081 "MaxMessageLength: %d\r\n" 09082 "NewMessageCount: %d\r\n" 09083 #ifdef IMAP_STORAGE 09084 "OldMessageCount: %d\r\n" 09085 "IMAPUser: %s\r\n" 09086 #endif 09087 "\r\n", 09088 actionid, 09089 vmu->context, 09090 vmu->mailbox, 09091 vmu->fullname, 09092 vmu->email, 09093 vmu->pager, 09094 vmu->serveremail, 09095 vmu->mailcmd, 09096 vmu->language, 09097 vmu->zonetag, 09098 vmu->callback, 09099 vmu->dialout, 09100 vmu->uniqueid, 09101 vmu->exit, 09102 vmu->saydurationm, 09103 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 09104 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 09105 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 09106 vmu->attachfmt, 09107 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 09108 vmu->volgain, 09109 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 09110 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 09111 vmu->maxmsg, 09112 vmu->maxsecs, 09113 #ifdef IMAP_STORAGE 09114 new, old, vmu->imapuser 09115 #else 09116 count_messages(vmu, dirname) 09117 #endif 09118 ); 09119 } 09120 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 09121 09122 AST_LIST_UNLOCK(&users); 09123 09124 return RESULT_SUCCESS; 09125 }
| static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 8883 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().
08884 { 08885 while (poll_thread_run) { 08886 struct timespec ts = { 0, }; 08887 struct timeval tv; 08888 08889 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 08890 ts.tv_sec = tv.tv_sec; 08891 ts.tv_nsec = tv.tv_usec * 1000; 08892 08893 ast_mutex_lock(&poll_lock); 08894 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 08895 ast_mutex_unlock(&poll_lock); 08896 08897 if (!poll_thread_run) 08898 break; 08899 08900 poll_subscribed_mailboxes(); 08901 } 08902 08903 return NULL; 08904 }
| static const char* mbox | ( | int | id | ) | [static] |
Definition at line 1129 of file app_voicemail.c.
Referenced by add_peer_mailboxes(), adsi_load_vmail(), copy_message(), get_folder(), and save_to_folder().
01130 { 01131 static const char *msgs[] = { 01132 #ifdef IMAP_STORAGE 01133 imapfolder, 01134 #else 01135 "INBOX", 01136 #endif 01137 "Old", 01138 "Work", 01139 "Family", 01140 "Friends", 01141 "Cust1", 01142 "Cust2", 01143 "Cust3", 01144 "Cust4", 01145 "Cust5", 01146 "Deleted", 01147 "Urgent" 01148 }; 01149 return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown"; 01150 }
| static int messagecount | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 4184 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
04185 { 04186 return __has_voicemail(context, mailbox, folder, 0); 04187 }
| static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 8906 of file app_voicemail.c.
References ast_free.
Referenced by mwi_unsub_event_cb().
08907 { 08908 ast_free(mwi_sub); 08909 }
| static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 8938 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_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub::mailbox, and mwi_sub::uniqueid.
Referenced by start_poll_thread().
08939 { 08940 const char *mailbox; 08941 const char *context; 08942 uint32_t uniqueid; 08943 unsigned int len; 08944 struct mwi_sub *mwi_sub; 08945 08946 if (ast_event_get_type(event) != AST_EVENT_SUB) 08947 return; 08948 08949 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 08950 return; 08951 08952 mailbox = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX); 08953 context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT); 08954 uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 08955 08956 len = sizeof(*mwi_sub); 08957 if (!ast_strlen_zero(mailbox)) 08958 len += strlen(mailbox); 08959 08960 if (!ast_strlen_zero(context)) 08961 len += strlen(context) + 1; /* Allow for seperator */ 08962 08963 if (!(mwi_sub = ast_calloc(1, len))) 08964 return; 08965 08966 mwi_sub->uniqueid = uniqueid; 08967 if (!ast_strlen_zero(mailbox)) 08968 strcpy(mwi_sub->mailbox, mailbox); 08969 08970 if (!ast_strlen_zero(context)) { 08971 strcat(mwi_sub->mailbox, "@"); 08972 strcat(mwi_sub->mailbox, context); 08973 } 08974 08975 AST_RWLIST_WRLOCK(&mwi_subs); 08976 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 08977 AST_RWLIST_UNLOCK(&mwi_subs); 08978 }
| static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 8911 of file app_voicemail.c.
References ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, 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 start_poll_thread().
08912 { 08913 uint32_t uniqueid; 08914 struct mwi_sub *mwi_sub; 08915 08916 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 08917 return; 08918 08919 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 08920 return; 08921 08922 uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 08923 08924 AST_RWLIST_WRLOCK(&mwi_subs); 08925 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 08926 if (mwi_sub->uniqueid == uniqueid) { 08927 AST_LIST_REMOVE_CURRENT(entry); 08928 break; 08929 } 08930 } 08931 AST_RWLIST_TRAVERSE_SAFE_END 08932 AST_RWLIST_UNLOCK(&mwi_subs); 08933 08934 if (mwi_sub) 08935 mwi_sub_destroy(mwi_sub); 08936 }
| 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 | |||
| ) | [static] |
Definition at line 5558 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_app_inboxcount(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, globalflags, LOG_WARNING, ast_vm_user::mailbox, make_dir(), make_file(), manager_event, ast_vm_user::pager, pbx_builtin_getvar_helper(), queue_mwi_event(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, strsep(), VM_ATTACH, and VM_DELETE.
05559 { 05560 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 05561 int newmsgs = 0, oldmsgs = 0; 05562 const char *category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"); 05563 char *myserveremail = serveremail; 05564 05565 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); 05566 make_file(fn, sizeof(fn), todir, msgnum); 05567 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 05568 05569 if (!ast_strlen_zero(vmu->attachfmt)) { 05570 if (strstr(fmt, vmu->attachfmt)) 05571 fmt = vmu->attachfmt; 05572 else 05573 ast_log(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); 05574 } 05575 05576 /* Attach only the first format */ 05577 fmt = ast_strdupa(fmt); 05578 stringp = fmt; 05579 strsep(&stringp, "|"); 05580 05581 if (!ast_strlen_zero(vmu->serveremail)) 05582 myserveremail = vmu->serveremail; 05583 05584 if (!ast_strlen_zero(vmu->email)) { 05585 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 05586 if (!attach_user_voicemail) 05587 attach_user_voicemail = ast_test_flag((&globalflags), VM_ATTACH); 05588 05589 if (attach_user_voicemail) 05590 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 05591 05592 /* XXX possible imap issue, should category be NULL XXX */ 05593 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, fn, fmt, duration, attach_user_voicemail, chan, category); 05594 05595 if (attach_user_voicemail) 05596 DISPOSE(todir, msgnum); 05597 } 05598 05599 if (!ast_strlen_zero(vmu->pager)) { 05600 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(0), cidnum, cidname, duration, vmu, category); 05601 } 05602 05603 if (ast_test_flag(vmu, VM_DELETE)) 05604 DELETE(todir, msgnum, fn, vmu); 05605 05606 /* Leave voicemail for someone */ 05607 if (ast_app_has_voicemail(ext_context, NULL)) 05608 ast_app_inboxcount(ext_context, &newmsgs, &oldmsgs); 05609 05610 queue_mwi_event(ext_context, newmsgs, oldmsgs); 05611 05612 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); 05613 run_externnotify(vmu->context, vmu->mailbox); 05614 05615 return 0; 05616 }
| static int ochar | ( | struct baseio * | bio, | |
| int | c, | |||
| FILE * | so | |||
| ) | [static] |
Definition at line 3258 of file app_voicemail.c.
References BASELINELEN, eol, and baseio::linelength.
Referenced by base_encode().
03259 { 03260 if (bio->linelength >= BASELINELEN) { 03261 if (fputs(eol, so) == EOF) 03262 return -1; 03263 03264 bio->linelength= 0; 03265 } 03266 03267 if (putc(((unsigned char)c), so) == EOF) 03268 return -1; 03269 03270 bio->linelength++; 03271 03272 return 1; 03273 }
| static int open_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu, | |||
| int | box | |||
| ) | [static] |
Definition at line 6234 of file app_voicemail.c.
References ast_copy_string(), ast_log(), ast_unlock_path(), ast_vm_user::context, count_messages(), create_dirpath(), vm_state::curbox, vm_state::curdir, last_message_index(), vm_state::lastmsg, LOG_ERROR, LOG_NOTICE, resequence_mailbox(), vm_state::username, vm_lock_path(), and vm_state::vmbox.
Referenced by vm_execmain().
06235 { 06236 int res = 0; 06237 int count_msg, last_msg; 06238 06239 ast_copy_string(vms->curbox, mbox(box), sizeof(vms->curbox)); 06240 06241 /* Rename the member vmbox HERE so that we don't try to return before 06242 * we know what's going on. 06243 */ 06244 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 06245 06246 /* Faster to make the directory than to check if it exists. */ 06247 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 06248 06249 count_msg = count_messages(vmu, vms->curdir); 06250 if (count_msg < 0) 06251 return count_msg; 06252 else 06253 vms->lastmsg = count_msg - 1; 06254 06255 /* 06256 The following test is needed in case sequencing gets messed up. 06257 There appears to be more than one way to mess up sequence, so 06258 we will not try to find all of the root causes--just fix it when 06259 detected. 06260 */ 06261 06262 if (vm_lock_path(vms->curdir)) { 06263 ast_log(LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 06264 return -1; 06265 } 06266 06267 last_msg = last_message_index(vmu, vms->curdir); 06268 ast_unlock_path(vms->curdir); 06269 06270 if (last_msg < 0) 06271 return last_msg; 06272 else if (vms->lastmsg != last_msg) { 06273 ast_log(LOG_NOTICE, "Resequencing Mailbox: %s\n", vms->curdir); 06274 res = resequence_mailbox(vmu, vms->curdir); 06275 if (res) 06276 return res; 06277 } 06278 06279 return 0; 06280 }
| static int play_greeting | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | filename, | |||
| char * | ecodes | |||
| ) | [static] |
Definition at line 3920 of file app_voicemail.c.
References ast_debug, ast_fileexists(), ast_streamfile(), ast_waitstream(), ast_vm_user::context, DISPOSE, ast_channel::language, ast_vm_user::mailbox, and RETRIEVE.
Referenced by invent_message(), and leave_voicemail().
03921 { 03922 int res = -2; 03923 03924 #ifdef ODBC_STORAGE 03925 int success = 03926 #endif 03927 RETRIEVE(filename, -1, vmu->mailbox, vmu->context); 03928 if (ast_fileexists(filename, NULL, NULL) > 0) { 03929 res = ast_streamfile(chan, filename, chan->language); 03930 if (res > -1) 03931 res = ast_waitstream(chan, ecodes); 03932 #ifdef ODBC_STORAGE 03933 if (success == -1) { 03934 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 03935 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 03936 store_file(filename, vmu->mailbox, vmu->context, -1); 03937 } 03938 #endif 03939 } 03940 DISPOSE(filename, -1); 03941 03942 return res; 03943 }
| static int play_message | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6070 of file app_voicemail.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_log(), ast_say_number(), ast_strdupa, ast_test_flag, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::fn2, 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_it(), vm_browse_messages_pt(), vm_browse_messages_zh(), and vm_execmain().
06071 { 06072 int res = 0; 06073 char filename[256], *cid; 06074 const char *origtime, *context, *category, *duration; 06075 struct ast_config *msg_cfg; 06076 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06077 06078 vms->starting = 0; 06079 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06080 adsi_message(chan, vms); 06081 if (!vms->curmsg) 06082 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 06083 else if (vms->curmsg == vms->lastmsg) 06084 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 06085 if (!res) { 06086 /* POLISH syntax */ 06087 if (!strcasecmp(chan->language, "pl")) { 06088 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 06089 int ten, one; 06090 char nextmsg[256]; 06091 ten = (vms->curmsg + 1) / 10; 06092 one = (vms->curmsg + 1) % 10; 06093 06094 if (vms->curmsg < 20) { 06095 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 06096 res = wait_file2(chan, vms, nextmsg); 06097 } else { 06098 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 06099 res = wait_file2(chan, vms, nextmsg); 06100 if (one > 0) { 06101 if (!res) { 06102 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 06103 res = wait_file2(chan, vms, nextmsg); 06104 } 06105 } 06106 } 06107 } 06108 if (!res) 06109 res = wait_file2(chan, vms, "vm-message"); 06110 } else { 06111 if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */ 06112 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 06113 else /* DEFAULT syntax */ { 06114 res = wait_file2(chan, vms, "vm-message"); 06115 } 06116 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 06117 if (!res) { 06118 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 06119 } 06120 } 06121 } 06122 } 06123 06124 /* Retrieve info from VM attribute file */ 06125 make_file(vms->fn2, sizeof(vms->fn2), vms->curdir, vms->curmsg); 06126 snprintf(filename, sizeof(filename), "%s.txt", vms->fn2); 06127 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 06128 msg_cfg = ast_config_load(filename, config_flags); 06129 if (!msg_cfg) { 06130 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 06131 return 0; 06132 } 06133 06134 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 06135 ast_log(LOG_WARNING, "No origtime?!\n"); 06136 DISPOSE(vms->curdir, vms->curmsg); 06137 ast_config_destroy(msg_cfg); 06138 return 0; 06139 } 06140 06141 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 06142 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 06143 category = ast_variable_retrieve(msg_cfg, "message", "category"); 06144 06145 context = ast_variable_retrieve(msg_cfg, "message", "context"); 06146 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 06147 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 06148 if (!res) { 06149 res = play_message_category(chan, category); 06150 } 06151 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 06152 res = play_message_datetime(chan, vmu, origtime, filename); 06153 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 06154 res = play_message_callerid(chan, vms, cid, context, 0); 06155 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 06156 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 06157 /* Allow pressing '1' to skip envelope / callerid */ 06158 if (res == '1') 06159 res = 0; 06160 ast_config_destroy(msg_cfg); 06161 06162 if (!res) { 06163 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 06164 vms->heard[vms->curmsg] = 1; 06165 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 06166 ast_log(LOG_WARNING, "Playback of message %s failed\n", vms->fn); 06167 res = 0; 06168 } 06169 } 06170 DISPOSE(vms->curdir, vms->curmsg); 06171 return res; 06172 }
| static int play_message_callerid | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| char * | cid, | |||
| const char * | context, | |||
| int | callback | |||
| ) | [static] |
Definition at line 5956 of file app_voicemail.c.
References ast_callerid_parse(), ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verb, cidinternalcontexts, ast_channel::language, MAX_NUM_CID_CONTEXTS, name, and wait_file2().
Referenced by advanced_options(), and play_message().
05957 { 05958 int res = 0; 05959 int i; 05960 char *callerid, *name; 05961 char prefile[PATH_MAX] = ""; 05962 05963 05964 /* If voicemail cid is not enabled, or we didn't get cid or context from 05965 * the attribute file, leave now. 05966 * 05967 * TODO Still need to change this so that if this function is called by the 05968 * message envelope (and someone is explicitly requesting to hear the CID), 05969 * it does not check to see if CID is enabled in the config file. 05970 */ 05971 if ((cid == NULL)||(context == NULL)) 05972 return res; 05973 05974 /* Strip off caller ID number from name */ 05975 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 05976 ast_callerid_parse(cid, &name, &callerid); 05977 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 05978 /* Check for internal contexts and only */ 05979 /* say extension when the call didn't come from an internal context in the list */ 05980 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++) { 05981 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 05982 if ((strcmp(cidinternalcontexts[i], context) == 0)) 05983 break; 05984 } 05985 if (i != MAX_NUM_CID_CONTEXTS) { /* internal context? */ 05986 if (!res) { 05987 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 05988 if (!ast_strlen_zero(prefile)) { 05989 /* See if we can find a recorded name for this person instead of their extension number */ 05990 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05991 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 05992 if (!callback) 05993 res = wait_file2(chan, vms, "vm-from"); 05994 res = ast_stream_and_wait(chan, prefile, ""); 05995 } else { 05996 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 05997 /* Say "from extension" as one saying to sound smoother */ 05998 if (!callback) 05999 res = wait_file2(chan, vms, "vm-from-extension"); 06000 res = ast_say_digit_str(chan, callerid, "", chan->language); 06001 } 06002 } 06003 } 06004 } else if (!res) { 06005 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 06006 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 06007 if (!callback) 06008 res = wait_file2(chan, vms, "vm-from-phonenumber"); 06009 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 06010 } 06011 } else { 06012 /* Number unknown */ 06013 ast_debug(1, "VM-CID: From an unknown number\n"); 06014 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 06015 res = wait_file2(chan, vms, "vm-unknown-caller"); 06016 } 06017 return res; 06018 }
| static int play_message_category | ( | struct ast_channel * | chan, | |
| const char * | category | |||
| ) | [static] |
Definition at line 5868 of file app_voicemail.c.
References ast_log(), ast_play_and_wait(), ast_strlen_zero(), and LOG_WARNING.
Referenced by play_message().
05869 { 05870 int res = 0; 05871 05872 if (!ast_strlen_zero(category)) 05873 res = ast_play_and_wait(chan, category); 05874 05875 if (res) { 05876 ast_log(LOG_WARNING, "No sound file for category '%s' was found.\n", category); 05877 res = 0; 05878 } 05879 05880 return res; 05881 }
| static int play_message_datetime | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| const char * | origtime, | |||
| const char * | filename | |||
| ) | [static] |
Definition at line 5883 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, LOG_WARNING, 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().
05884 { 05885 int res = 0; 05886 struct vm_zone *the_zone = NULL; 05887 time_t t; 05888 05889 if (ast_get_time_t(origtime, &t, 0, NULL)) { 05890 ast_log(LOG_WARNING, "Couldn't find origtime in %s\n", filename); 05891 return 0; 05892 } 05893 05894 /* Does this user have a timezone specified? */ 05895 if (!ast_strlen_zero(vmu->zonetag)) { 05896 /* Find the zone in the list */ 05897 struct vm_zone *z; 05898 AST_LIST_LOCK(&zones); 05899 AST_LIST_TRAVERSE(&zones, z, list) { 05900 if (!strcmp(z->name, vmu->zonetag)) { 05901 the_zone = z; 05902 break; 05903 } 05904 } 05905 AST_LIST_UNLOCK(&zones); 05906 } 05907 05908 /* No internal variable parsing for now, so we'll comment it out for the time being */ 05909 #if 0 05910 /* Set the DIFF_* variables */ 05911 ast_localtime(&t, &time_now, NULL); 05912 tv_now = ast_tvnow(); 05913 ast_localtime(&tv_now, &time_then, NULL); 05914 05915 /* Day difference */ 05916 if (time_now.tm_year == time_then.tm_year) 05917 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 05918 else 05919 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 05920 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 05921 05922 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 05923 #endif 05924 if (the_zone) { 05925 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 05926 } 05927 else if (!strcasecmp(chan->language,"pl")) /* POLISH syntax */ 05928 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 05929 else if (!strcasecmp(chan->language, "se")) /* SWEDISH syntax */ 05930 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 05931 else if (!strcasecmp(chan->language, "no")) /* NORWEGIAN syntax */ 05932 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 05933 else if (!strcasecmp(chan->language, "de")) /* GERMAN syntax */ 05934 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 05935 else if (!strcasecmp(chan->language, "nl")) /* DUTCH syntax */ 05936 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 05937 else if (!strcasecmp(chan->language, "it")) /* ITALIAN syntax */ 05938 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); 05939 else if (!strcasecmp(chan->language, "gr")) 05940 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 05941 else if (!strcasecmp(chan->language, "pt_BR")) 05942 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); 05943 else if (!strncasecmp(chan->language, "zh", 2)) /* CHINESE (Taiwan) syntax */ 05944 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 05945 else { 05946 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 05947 } 05948 #if 0 05949 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 05950 #endif 05951 return res; 05952 }
| static int play_message_duration | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms, | |||
| const char * | duration, | |||
| int | minduration | |||
| ) | [static] |
Definition at line 6020 of file app_voicemail.c.
References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, num, say_and_wait(), and wait_file2().
Referenced by play_message().
06021 { 06022 int res = 0; 06023 int durationm; 06024 int durations; 06025 /* Verify that we have a duration for the message */ 06026 if (duration == NULL) 06027 return res; 06028 06029 /* Convert from seconds to minutes */ 06030 durations = atoi(duration); 06031 durationm = durations / 60; 06032 06033 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 06034 06035 if ((!res) && (durationm >= minduration)) { 06036 res = wait_file2(chan, vms, "vm-duration"); 06037 06038 /* POLISH syntax */ 06039 if (!strcasecmp(chan->language, "pl")) { 06040 div_t num = div(durationm, 10); 06041 06042 if (durationm == 1) { 06043 res = ast_play_and_wait(chan, "digits/1z"); 06044 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 06045 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 06046 if (num.rem == 2) { 06047 if (!num.quot) { 06048 res = ast_play_and_wait(chan, "digits/2-ie"); 06049 } else { 06050 res = say_and_wait(chan, durationm - 2 , chan->language); 06051 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 06052 } 06053 } else { 06054 res = say_and_wait(chan, durationm, chan->language); 06055 } 06056 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 06057 } else { 06058 res = say_and_wait(chan, durationm, chan->language); 06059 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 06060 } 06061 /* DEFAULT syntax */ 06062 } else { 06063 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 06064 res = wait_file2(chan, vms, "vm-minutes"); 06065 } 06066 } 06067 return res; 06068 }
| 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 | |||
| ) | [static] |
Definition at line 10100 of file app_voicemail.c.
References ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, LOG_WARNING, ast_vm_user::mailbox, STORE, vm_exec(), VM_OPERATOR, and VM_REVIEW.
10103 { 10104 /* Record message & let caller review or re-record it, or set options if applicable */ 10105 int res = 0; 10106 int cmd = 0; 10107 int max_attempts = 3; 10108 int attempts = 0; 10109 int recorded = 0; 10110 int message_exists = 0; 10111 signed char zero_gain = 0; 10112 char tempfile[PATH_MAX]; 10113 char *acceptdtmf = "#"; 10114 char *canceldtmf = ""; 10115 10116 /* Note that urgent and private are for flagging messages as such in the future */ 10117 10118 /* barf if no pointer passed to store duration in */ 10119 if (duration == NULL) { 10120 ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n"); 10121 return -1; 10122 } 10123 10124 if (!outsidecaller) 10125 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 10126 else 10127 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 10128 10129 cmd = '3'; /* Want to start by recording */ 10130 10131 while ((cmd >= 0) && (cmd != 't')) { 10132 switch (cmd) { 10133 case '1': 10134 if (!message_exists) { 10135 /* In this case, 1 is to record a message */ 10136 cmd = '3'; 10137 break; 10138 } else { 10139 /* Otherwise 1 is to save the existing message */ 10140 ast_verb(3, "Saving message as is\n"); 10141 if (!outsidecaller) 10142 ast_filerename(tempfile, recordfile, NULL); 10143 ast_stream_and_wait(chan, "vm-msgsaved", ""); 10144 if (!outsidecaller) { 10145 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms); 10146 DISPOSE(recordfile, -1); 10147 } 10148 cmd = 't'; 10149 return res; 10150 } 10151 case '2': 10152 /* Review */ 10153 ast_verb(3, "Reviewing the message\n"); 10154 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 10155 break; 10156 case '3': 10157 message_exists = 0; 10158 /* Record */ 10159 if (recorded == 1) 10160 ast_verb(3, "Re-recording the message\n"); 10161 else 10162 ast_verb(3, "Recording the message\n"); 10163 10164 if (recorded && outsidecaller) { 10165 cmd = ast_play_and_wait(chan, INTRO); 10166 cmd = ast_play_and_wait(chan, "beep"); 10167 } 10168 recorded = 1; 10169 /* 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 */ 10170 if (record_gain) 10171 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 10172 if (ast_test_flag(vmu, VM_OPERATOR)) 10173 canceldtmf = "0"; 10174 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 10175 if (record_gain) 10176 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 10177 if (cmd == -1) { 10178 /* User has hung up, no options to give */ 10179 if (!outsidecaller) { 10180 /* user was recording a greeting and they hung up, so let's delete the recording. */ 10181 ast_filedelete(tempfile, NULL); 10182 } 10183 return cmd; 10184 } 10185 if (cmd == '0') { 10186 break; 10187 } else if (cmd == '*') { 10188 break; 10189 #if 0 10190 } else if (vmu->review && (*duration < 5)) { 10191 /* Message is too short */ 10192 ast_verb(3, "Message too short\n"); 10193 cmd = ast_play_and_wait(chan, "vm-tooshort"); 10194 cmd = ast_filedelete(tempfile, NULL); 10195 break; 10196 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 10197 /* Message is all silence */ 10198 ast_verb(3, "Nothing recorded\n"); 10199 cmd = ast_filedelete(tempfile, NULL); 10200 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 10201 if (!cmd) 10202 cmd = ast_play_and_wait(chan, "vm-speakup"); 10203 break; 10204 #endif 10205 } else { 10206 /* If all is well, a message exists */ 10207 message_exists = 1; 10208 cmd = 0; 10209 } 10210 break; 10211 case '4': 10212 case '5': 10213 case '6': 10214 case '7': 10215 case '8': 10216 case '9': 10217 case '*': 10218 case '#': 10219 cmd = ast_play_and_wait(chan, "vm-sorry"); 10220 break; 10221 #if 0 10222 /* XXX Commented out for the moment because of the dangers of deleting 10223 a message while recording (can put the message numbers out of sync) */ 10224 case '*': 10225 /* Cancel recording, delete message, offer to take another message*/ 10226 cmd = ast_play_and_wait(chan, "vm-deleted"); 10227 cmd = ast_filedelete(tempfile, NULL); 10228 if (outsidecaller) { 10229 res = vm_exec(chan, NULL); 10230 return res; 10231 } 10232 else 10233 return 1; 10234 #endif 10235 case '0': 10236 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10237 cmd = ast_play_and_wait(chan, "vm-sorry"); 10238 break; 10239 } 10240 if (message_exists || recorded) { 10241 cmd = ast_play_and_wait(chan, "vm-saveoper"); 10242 if (!cmd) 10243 cmd = ast_waitfordigit(chan, 3000); 10244 if (cmd == '1') { 10245 ast_play_and_wait(chan, "vm-msgsaved"); 10246 cmd = '0'; 10247 } else { 10248 ast_play_and_wait(chan, "vm-deleted"); 10249 DELETE(recordfile, -1, recordfile, vmu); 10250 cmd = '0'; 10251 } 10252 } 10253 return cmd; 10254 default: 10255 /* If the caller is an ouside caller, and the review option is enabled, 10256 allow them to review the message, but let the owner of the box review 10257 their OGM's */ 10258 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 10259 return cmd; 10260 if (message_exists) { 10261 cmd = ast_play_and_wait(chan, "vm-review"); 10262 } else { 10263 cmd = ast_play_and_wait(chan, "vm-torerecord"); 10264 if (!cmd) 10265 cmd = ast_waitfordigit(chan, 600); 10266 } 10267 10268 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 10269 cmd = ast_play_and_wait(chan, "vm-reachoper"); 10270 if (!cmd) 10271 cmd = ast_waitfordigit(chan, 600); 10272 } 10273 #if 0 10274 if (!cmd) 10275 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 10276 #endif 10277 if (!cmd) 10278 cmd = ast_waitfordigit(chan, 6000); 10279 if (!cmd) { 10280 attempts++; 10281 } 10282 if (attempts > max_attempts) { 10283 cmd = 't'; 10284 } 10285 } 10286 } 10287 if (outsidecaller) 10288 ast_play_and_wait(chan, "vm-goodbye"); 10289 if (cmd == 't') 10290 cmd = 0; 10291 return cmd; 10292 }
| static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 8861 of file app_voicemail.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, inboxcount(), mwi_sub::mailbox, mwi_sub::old_new, mwi_sub::old_old, and queue_mwi_event().
Referenced by mb_poll_thread().
08862 { 08863 struct mwi_sub *mwi_sub; 08864 08865 AST_RWLIST_RDLOCK(&mwi_subs); 08866 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 08867 int new = 0, old = 0; 08868 08869 if (ast_strlen_zero(mwi_sub->mailbox)) 08870 continue; 08871 08872 inboxcount(mwi_sub->mailbox, &new, &old); 08873 08874 if (new != mwi_sub->old_new || old != mwi_sub->old_old) { 08875 mwi_sub->old_new = new; 08876 mwi_sub->old_old = old; 08877 queue_mwi_event(mwi_sub->mailbox, new, old); 08878 } 08879 } 08880 AST_RWLIST_UNLOCK(&mwi_subs); 08881 }
| static void populate_defaults | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 712 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.
00713 { 00714 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00715 if (saydurationminfo) 00716 vmu->saydurationm = saydurationminfo; 00717 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 00718 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 00719 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 00720 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 00721 if (vmmaxsecs) 00722 vmu->maxsecs = vmmaxsecs; 00723 if (maxmsg) 00724 vmu->maxmsg = maxmsg; 00725 if (maxdeletedmsg) 00726 vmu->maxdeletedmsg = maxdeletedmsg; 00727 vmu->volgain = volgain; 00728 }
| 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 | |||
| ) | [static] |
Definition at line 3334 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, 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().
03335 { 03336 char callerid[256]; 03337 char fromdir[256], fromfile[256]; 03338 struct ast_config *msg_cfg; 03339 const char *origcallerid, *origtime; 03340 char origcidname[80], origcidnum[80], origdate[80]; 03341 int inttime; 03342 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 03343 03344 /* Prepare variables for substitution in email body and subject */ 03345 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 03346 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 03347 snprintf(passdata, passdatasize, "%d", msgnum); 03348 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", passdata); 03349 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 03350 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 03351 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 03352 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 03353 pbx_builtin_setvar_helper(ast, "VM_CIDNAME"