#include "asterisk.h"
#include <ctype.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include <locale.h>
#include "asterisk/paths.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/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/callerid.h"
#include "asterisk/event.h"

Go to the source code of this file.
Data Structures | |
| struct | b64_baseio |
| Structure for base64 encoding. More... | |
| struct | leave_vm_options |
| Options for leaving voicemail with the voicemail() application. More... | |
| struct | message_templates |
| The list of e-mail templates. More... | |
| struct | minivm_account |
| struct | minivm_accounts |
| struct | minivm_stats |
| Structure for gathering statistics. More... | |
| struct | minivm_template |
| struct | minivm_zone |
| Voicemail time zones. More... | |
| struct | minivm_zones |
| The list of e-mail time zones. More... | |
Defines | |
| #define | ASTERISK_USERNAME "asterisk" |
| #define | B64_BASELINELEN 72 |
| #define | B64_BASEMAXINLINE 256 |
| #define | DEFAULT_CHARSET "ISO-8859-1" |
| #define | DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
| #define | EOL "\r\n" |
| #define | ERROR_LOCK_PATH -100 |
| #define | FALSE 0 |
| #define | HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" |
| #define | HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
| #define | HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" |
| #define | MAX_DATETIME_FORMAT 512 |
| #define | MAX_NUM_CID_CONTEXTS 10 |
| #define | MVM_ALLOCED (1 << 13) |
| #define | MVM_ENVELOPE (1 << 4) |
| #define | MVM_OPERATOR (1 << 1) |
| #define | MVM_PBXSKIP (1 << 9) |
| #define | MVM_REALTIME (1 << 2) |
| #define | MVM_REVIEW (1 << 0) |
| #define | MVM_SVMAIL (1 << 3) |
| #define | SENDMAIL "/usr/sbin/sendmail -t" |
| Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf. | |
| #define | SOUND_INTRO "vm-intro" |
| #define | TRUE 1 |
| #define | VOICEMAIL_CONFIG "minivm.conf" |
| #define | VOICEMAIL_DIR_MODE 0700 |
Enumerations | |
| enum | minivm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_ARRAY_SIZE = 1 } |
| enum | minivm_option_flags { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_TEMP_GREETING = (1 << 3), OPT_NAME_GREETING = (1 << 4), OPT_RECORDGAIN = (1 << 5) } |
| enum | mvm_messagetype { MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE } |
| Message types for notification. More... | |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | access_counter_file (char *directory, char *countername, int value, int operand) |
| Access counter file, lock directory, read and possibly write it again changed. | |
| static int | apply_general_options (struct ast_variable *var) |
| Apply general configuration options. | |
| static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *charset, const char *start, size_t preamble, size_t postamble) |
| static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
| static int | b64_inbuf (struct b64_baseio *bio, FILE *fi) |
| static int | b64_inchar (struct b64_baseio *bio, FILE *fi) |
| static int | b64_ochar (struct b64_baseio *bio, int c, FILE *so) |
| static int | base_encode (char *filename, FILE *so) |
| static int | check_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
| static int | check_mime (const char *str) |
| static char * | complete_minivm_show_users (const char *line, const char *word, int pos, int state) |
| static int | create_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
| static int | create_vmaccount (char *name, struct ast_variable *var, int realtime) |
| Append new mailbox to mailbox list from configuration file. | |
| static struct minivm_account * | find_account (const char *domain, const char *username, int createtemp) |
| static struct minivm_account * | find_user_realtime (const char *domain, const char *username) |
| static void | free_user (struct minivm_account *vmu) |
| static void | free_zone (struct minivm_zone *z) |
| Free Mini Voicemail timezone. | |
| static int | get_date (char *s, int len) |
| static char * | handle_minivm_list_templates (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI routine for listing templates. | |
| static char * | handle_minivm_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Reload cofiguration. | |
| static char * | handle_minivm_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Show settings. | |
| static char * | handle_minivm_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show stats. | |
| static char * | handle_minivm_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list voicemail accounts. | |
| static char * | handle_minivm_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 | invent_message (struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes) |
| static int | leave_voicemail (struct ast_channel *chan, char *username, struct leave_vm_options *options) |
| static int | load_config (int reload) |
| Load minivoicemail configuration. | |
| static int | load_module (void) |
| Load mini voicemail module. | |
| static int | make_dir (char *dest, int len, const char *domain, const char *username, const char *folder) |
| static void | message_destroy_list (void) |
| static int | message_template_build (const char *name, struct ast_variable *var) |
| static struct minivm_template * | message_template_create (const char *name) |
| static struct minivm_template * | message_template_find (const char *name) |
| static void | message_template_free (struct minivm_template *template) |
| static char * | message_template_parse_emailbody (const char *configuration) |
| Parse emailbody template from configuration file. | |
| static char * | message_template_parse_filebody (const char *filename) |
| Read message template from file. | |
| static int | minivm_accmess_exec (struct ast_channel *chan, const char *data) |
| Record specific messages for voicemail account. | |
| static int | minivm_account_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${MINIVMACCOUNT()} Dialplan function - reads account data | |
| static int | minivm_counter_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${MINIVMCOUNTER()} Dialplan function - read counters | |
| static int | minivm_counter_func_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
| ${MINIVMCOUNTER()} Dialplan function - changes counter data | |
| static int | minivm_delete_exec (struct ast_channel *chan, const char *data) |
| static int | minivm_greet_exec (struct ast_channel *chan, const char *data) |
| static int | minivm_mwi_exec (struct ast_channel *chan, const char *data) |
| static int | minivm_notify_exec (struct ast_channel *chan, const char *data) |
| static int | minivm_record_exec (struct ast_channel *chan, const char *data) |
| static struct minivm_account * | mvm_user_alloc (void) |
| static int | notify_new_message (struct ast_channel *chan, const char *templatename, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname) |
| static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct minivm_account *vmu, int *duration, const char *unlockdir, signed char record_gain) |
| static void | populate_defaults (struct minivm_account *vmu) |
| static void | prep_email_sub_vars (struct ast_channel *channel, const struct minivm_account *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date, const char *counter) |
| static void | queue_mwi_event (const char *mbx, const char *ctx, int urgent, int new, int old) |
| static int | reload (void) |
| Reload mini voicemail module. | |
| static void | run_externnotify (struct ast_channel *chan, struct minivm_account *vmu) |
| Run external notification for voicemail message. | |
| static int | sendmail (struct minivm_template *template, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type, const char *counter) |
| static int | timezone_add (const char *zonename, const char *config) |
| Add time zone to memory list. | |
| static void | timezone_destroy_list (void) |
| Clear list of timezones. | |
| static int | unload_module (void) |
| Unload mini voicemail module. | |
| static int | vm_delete (char *file) |
| static int | vm_lock_path (const char *path) |
| lock directory | |
| static void | vmaccounts_destroy_list (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail 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 * | app_minivm_accmess = "MinivmAccMess" |
| static char * | app_minivm_delete = "MinivmDelete" |
| static char * | app_minivm_greet = "MinivmGreet" |
| static char * | app_minivm_mwi = "MinivmMWI" |
| static char * | app_minivm_notify = "MinivmNotify" |
| static char * | app_minivm_record = "MinivmRecord" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_cli_entry | cli_minivm [] |
| CLI commands for Mini-voicemail. | |
| static char | default_vmformat [80] |
| static char | global_externnotify [160] |
| static char | global_logfile [PATH_MAX] |
| static char | global_mailcmd [160] |
| static int | global_maxgreet |
| static int | global_maxsilence |
| static int | global_saydurationminfo |
| static int | global_silencethreshold = 128 |
| static struct minivm_stats | global_stats |
| Statistics for voicemail. | |
| static int | global_vmmaxmessage |
| static int | global_vmminmessage |
| static double | global_volgain |
| static struct ast_flags | globalflags = {0} |
| static struct ast_app_option | minivm_accmess_options [128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING },} |
| static struct ast_custom_function | minivm_account_function |
| static struct ast_app_option | minivm_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 },} |
| static struct ast_custom_function | minivm_counter_function |
| static ast_mutex_t | minivmlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
| static FILE * | minivmlogfile |
| static ast_mutex_t | minivmloglock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
| static char | MVM_SPOOL_DIR [PATH_MAX] |
A voicemail system in small building blocks, working together based on the Comedian Mail voicemail system (app_voicemail.c).
Definition in file app_minivm.c.
| #define ASTERISK_USERNAME "asterisk" |
Default username for sending mail is asterisk@localhost
Definition at line 530 of file app_minivm.c.
Referenced by load_config().
| #define B64_BASELINELEN 72 |
Line length for Base 64 endoded messages
Definition at line 520 of file app_minivm.c.
Referenced by b64_ochar().
| #define B64_BASEMAXINLINE 256 |
Buffer size for Base 64 attachment encoding
Definition at line 519 of file app_minivm.c.
Referenced by b64_inbuf(), and base_encode().
| #define DEFAULT_CHARSET "ISO-8859-1" |
| #define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
| #define EOL "\r\n" |
| #define ERROR_LOCK_PATH -100 |
Definition at line 526 of file app_minivm.c.
Referenced by close_mailbox(), copy_message(), count_messages(), minivm_record_exec(), save_to_folder(), vm_exec(), and vm_execmain().
| #define FALSE 0 |
Definition at line 502 of file app_minivm.c.
Referenced by __sip_ack(), __sip_semi_ack(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), add_sdp(), ast_tzset(), build_peer(), cb_extensionstate(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), create_addr(), dialog_needdestroy(), do_monitor(), expire_register(), find_call(), find_sdp(), function_sippeer(), handle_invite_replaces(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), interpret_t38_parameters(), invent_message(), load_config(), minivm_accmess_exec(), minivm_counter_func_read(), minivm_counter_func_write(), parse_register_contact(), parse_sip_options(), proc_session_timer(), process_sdp(), proxy_update(), rcvfax_exec(), receive_message(), register_verify(), reload_config(), reqprep(), send_provisional_keepalive_full(), set_destination(), show_console(), sip_addheader(), sip_answer(), sip_destroy_peer(), sip_devicestate(), sip_do_debug_peer(), sip_hangup(), sip_peer_hold(), sip_poke_noanswer(), sip_prune_realtime(), sip_read(), sip_register(), sip_sendhtml(), sip_set_history(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_inuse(), sip_show_settings(), sip_show_user(), sip_show_users(), sndfax_exec(), st_get_mode(), st_get_refresher(), st_get_se(), stop_session_timer(), time1(), time2(), time2sub(), transmit_audio(), transmit_fake_auth_response(), transmit_invite(), transmit_provisional_response(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), tzload(), tzparse(), update_call_counter(), and update_connectedline().
| #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" |
Referenced by handle_minivm_show_users().
| #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_minivm_show_zones().
| #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" |
Referenced by handle_minivm_list_templates().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 523 of file app_minivm.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 524 of file app_minivm.c.
Referenced by load_config(), and play_message_callerid().
| #define MVM_ALLOCED (1 << 13) |
Definition at line 512 of file app_minivm.c.
Referenced by find_account(), leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), and minivm_notify_exec().
| #define MVM_ENVELOPE (1 << 4) |
Definition at line 510 of file app_minivm.c.
| #define MVM_OPERATOR (1 << 1) |
Operator exit during voicemail recording
Definition at line 507 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), minivm_greet_exec(), and play_record_review().
| #define MVM_PBXSKIP (1 << 9) |
Definition at line 511 of file app_minivm.c.
| #define MVM_REALTIME (1 << 2) |
This user is a realtime account
Definition at line 508 of file app_minivm.c.
| #define MVM_REVIEW (1 << 0) |
Review message
Definition at line 506 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
| #define MVM_SVMAIL (1 << 3) |
Definition at line 509 of file app_minivm.c.
| #define SENDMAIL "/usr/sbin/sendmail -t" |
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
Definition at line 516 of file app_minivm.c.
Referenced by load_config().
| #define SOUND_INTRO "vm-intro" |
| #define TRUE 1 |
Definition at line 499 of file app_minivm.c.
Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_semi_ack(), __sip_subscribe_mwi_do(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), add_sdp(), ast_tzset(), build_peer(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), cli_activate(), create_addr(), dialog_needdestroy(), find_account(), find_call(), find_sdp(), find_user_realtime(), function_sippeer(), get_sip_pvt_byid_locked(), gmtload(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_peerpoke(), interpret_t38_parameters(), leave_voicemail(), load_config(), local_attended_transfer(), manager_mutestream(), manager_sipnotify(), message_template_create(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), parse_ok_contact(), parse_register_contact(), parse_sip_options(), proc_session_timer(), process_sdp(), proxy_update(), rcvfax_exec(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), reqprep(), respprep(), restart_session_timer(), set_destination(), show_console(), sip_addheader(), sip_alloc(), sip_answer(), sip_cli_notify(), sip_destroy(), sip_destroy_peer(), sip_devicestate(), sip_do_debug_peer(), sip_hangup(), sip_indicate(), sip_park_thread(), sip_poke_noanswer(), sip_poke_peer(), sip_prune_realtime(), sip_read(), sip_registry_destroy(), sip_reload(), sip_request_call(), sip_scheddestroy(), sip_send_mwi_to_peer(), sip_set_history(), sip_set_udptl_peer(), sip_show_channel(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), sip_write(), sndfax_exec(), st_get_mode(), st_get_refresher(), st_get_se(), stop_session_timer(), temp_peer(), time1(), time2(), time2sub(), transmit_audio(), transmit_invite(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_t38(), tzload(), tzparse(), udptl_rx_packet(), unload_module(), update_call_counter(), and update_connectedline().
| #define VOICEMAIL_CONFIG "minivm.conf" |
Definition at line 529 of file app_minivm.c.
| #define VOICEMAIL_DIR_MODE 0700 |
| enum minivm_option_args |
Definition at line 560 of file app_minivm.c.
00560 { 00561 OPT_ARG_RECORDGAIN = 0, 00562 OPT_ARG_ARRAY_SIZE = 1, 00563 };
| enum minivm_option_flags |
| OPT_SILENT | |
| OPT_BUSY_GREETING | |
| OPT_UNAVAIL_GREETING | |
| OPT_TEMP_GREETING | |
| OPT_NAME_GREETING | |
| OPT_RECORDGAIN |
Definition at line 551 of file app_minivm.c.
00551 { 00552 OPT_SILENT = (1 << 0), 00553 OPT_BUSY_GREETING = (1 << 1), 00554 OPT_UNAVAIL_GREETING = (1 << 2), 00555 OPT_TEMP_GREETING = (1 << 3), 00556 OPT_NAME_GREETING = (1 << 4), 00557 OPT_RECORDGAIN = (1 << 5), 00558 };
| enum mvm_messagetype |
Message types for notification.
Definition at line 533 of file app_minivm.c.
00533 { 00534 MVM_MESSAGE_EMAIL, 00535 MVM_MESSAGE_PAGE 00536 /* For trunk: MVM_MESSAGE_JABBER, */ 00537 };
| static void __reg_module | ( | void | ) | [static] |
Definition at line 3546 of file app_minivm.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 3546 of file app_minivm.c.
| static int access_counter_file | ( | char * | directory, | |
| char * | countername, | |||
| int | value, | |||
| int | operand | |||
| ) | [static] |
Access counter file, lock directory, read and possibly write it again changed.
| directory | Directory to crate file in | |
| countername | filename | |
| value | If set to zero, we only read the variable | |
| operand | 0 to read, 1 to set new value, 2 to change |
Definition at line 3260 of file app_minivm.c.
References ast_debug, ast_log(), ast_unlock_path(), errno, LOG_ERROR, and vm_lock_path().
Referenced by minivm_counter_func_read(), and minivm_counter_func_write().
03261 { 03262 char filename[BUFSIZ]; 03263 char readbuf[BUFSIZ]; 03264 FILE *counterfile; 03265 int old = 0, counter = 0; 03266 03267 /* Lock directory */ 03268 if (vm_lock_path(directory)) { 03269 return -1; /* Could not lock directory */ 03270 } 03271 snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername); 03272 if (operand != 1) { 03273 counterfile = fopen(filename, "r"); 03274 if (counterfile) { 03275 if(fgets(readbuf, sizeof(readbuf), counterfile)) { 03276 ast_debug(3, "Read this string from counter file: %s\n", readbuf); 03277 old = counter = atoi(readbuf); 03278 } 03279 fclose(counterfile); 03280 } 03281 } 03282 switch (operand) { 03283 case 0: /* Read only */ 03284 ast_unlock_path(directory); 03285 ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter); 03286 return counter; 03287 break; 03288 case 1: /* Set new value */ 03289 counter = value; 03290 break; 03291 case 2: /* Change value */ 03292 counter += value; 03293 if (counter < 0) /* Don't allow counters to fall below zero */ 03294 counter = 0; 03295 break; 03296 } 03297 03298 /* Now, write the new value to the file */ 03299 counterfile = fopen(filename, "w"); 03300 if (!counterfile) { 03301 ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno)); 03302 ast_unlock_path(directory); 03303 return -1; /* Could not open file for writing */ 03304 } 03305 fprintf(counterfile, "%d\n\n", counter); 03306 fclose(counterfile); 03307 ast_unlock_path(directory); 03308 ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter); 03309 return counter; 03310 }
| static int apply_general_options | ( | struct ast_variable * | var | ) | [static] |
Apply general configuration options.
Definition at line 2740 of file app_minivm.c.
References ast_config_AST_LOG_DIR, ast_copy_string(), ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), default_vmformat, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by load_config().
02741 { 02742 int error = 0; 02743 02744 while (var) { 02745 /* Mail command */ 02746 if (!strcmp(var->name, "mailcmd")) { 02747 ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */ 02748 } else if (!strcmp(var->name, "maxgreet")) { 02749 global_maxgreet = atoi(var->value); 02750 } else if (!strcmp(var->name, "maxsilence")) { 02751 global_maxsilence = atoi(var->value); 02752 if (global_maxsilence > 0) 02753 global_maxsilence *= 1000; 02754 } else if (!strcmp(var->name, "logfile")) { 02755 if (!ast_strlen_zero(var->value) ) { 02756 if(*(var->value) == '/') 02757 ast_copy_string(global_logfile, var->value, sizeof(global_logfile)); 02758 else 02759 snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value); 02760 } 02761 } else if (!strcmp(var->name, "externnotify")) { 02762 /* External voicemail notify application */ 02763 ast_copy_string(global_externnotify, var->value, sizeof(global_externnotify)); 02764 } else if (!strcmp(var->name, "silencetreshold")) { 02765 /* Silence treshold */ 02766 global_silencethreshold = atoi(var->value); 02767 } else if (!strcmp(var->name, "maxmessage")) { 02768 int x; 02769 if (sscanf(var->value, "%30d", &x) == 1) { 02770 global_vmmaxmessage = x; 02771 } else { 02772 error ++; 02773 ast_log(LOG_WARNING, "Invalid max message time length\n"); 02774 } 02775 } else if (!strcmp(var->name, "minmessage")) { 02776 int x; 02777 if (sscanf(var->value, "%30d", &x) == 1) { 02778 global_vmminmessage = x; 02779 if (global_maxsilence <= global_vmminmessage) 02780 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 02781 } else { 02782 error ++; 02783 ast_log(LOG_WARNING, "Invalid min message time length\n"); 02784 } 02785 } else if (!strcmp(var->name, "format")) { 02786 ast_copy_string(default_vmformat, var->value, sizeof(default_vmformat)); 02787 } else if (!strcmp(var->name, "review")) { 02788 ast_set2_flag((&globalflags), ast_true(var->value), MVM_REVIEW); 02789 } else if (!strcmp(var->name, "operator")) { 02790 ast_set2_flag((&globalflags), ast_true(var->value), MVM_OPERATOR); 02791 } 02792 var = var->next; 02793 } 02794 return error; 02795 }
| static const char* ast_str_encode_mime | ( | struct ast_str ** | end, | |
| ssize_t | maxlen, | |||
| const char * | charset, | |||
| const char * | start, | |||
| size_t | preamble, | |||
| size_t | postamble | |||
| ) | [static] |
Definition at line 1154 of file app_minivm.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), and ast_str_strlen().
Referenced by make_email_file(), sendmail(), and sendpage().
01155 { 01156 struct ast_str *tmp = ast_str_alloca(80); 01157 int first_section = 1; 01158 *end = '\0'; 01159 01160 ast_str_reset(*end); 01161 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 01162 for (; *start; start++) { 01163 int need_encoding = 0; 01164 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 01165 need_encoding = 1; 01166 } 01167 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 01168 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 01169 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 01170 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 01171 /* Start new line */ 01172 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 01173 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 01174 first_section = 0; 01175 } 01176 if (need_encoding && *start == ' ') { 01177 ast_str_append(&tmp, -1, "_"); 01178 } else if (need_encoding) { 01179 ast_str_append(&tmp, -1, "=%hhX", *start); 01180 } else { 01181 ast_str_append(&tmp, -1, "%c", *start); 01182 } 01183 } 01184 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 01185 return ast_str_buffer(*end); 01186 }
| static const char* ast_str_quote | ( | struct ast_str ** | buf, | |
| ssize_t | maxlen, | |||
| const char * | from | |||
| ) | [static] |
Definition at line 1196 of file app_minivm.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), sendmail(), and sendpage().
01197 { 01198 const char *ptr; 01199 01200 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 01201 ast_str_set(buf, maxlen, "\""); 01202 for (ptr = from; *ptr; ptr++) { 01203 if (*ptr == '"' || *ptr == '\\') { 01204 ast_str_append(buf, maxlen, "\\%c", *ptr); 01205 } else { 01206 ast_str_append(buf, maxlen, "%c", *ptr); 01207 } 01208 } 01209 ast_str_append(buf, maxlen, "\""); 01210 01211 return ast_str_buffer(*buf); 01212 }
| static int b64_inbuf | ( | struct b64_baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
Definition at line 832 of file app_minivm.c.
References b64_baseio::ateof, B64_BASEMAXINLINE, b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by b64_inchar().
00833 { 00834 int l; 00835 00836 if (bio->ateof) 00837 return 0; 00838 00839 if ((l = fread(bio->iobuf, 1, B64_BASEMAXINLINE,fi)) <= 0) { 00840 if (ferror(fi)) 00841 return -1; 00842 00843 bio->ateof = 1; 00844 return 0; 00845 } 00846 00847 bio->iolen= l; 00848 bio->iocp= 0; 00849 00850 return 1; 00851 }
| static int b64_inchar | ( | struct b64_baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
Definition at line 855 of file app_minivm.c.
References b64_inbuf(), b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by base_encode().
00856 { 00857 if (bio->iocp >= bio->iolen) { 00858 if (!b64_inbuf(bio, fi)) 00859 return EOF; 00860 } 00861 00862 return bio->iobuf[bio->iocp++]; 00863 }
| static int b64_ochar | ( | struct b64_baseio * | bio, | |
| int | c, | |||
| FILE * | so | |||
| ) | [static] |
Definition at line 867 of file app_minivm.c.
References B64_BASELINELEN, EOL, and b64_baseio::linelength.
Referenced by base_encode().
00868 { 00869 if (bio->linelength >= B64_BASELINELEN) { 00870 if (fputs(EOL,so) == EOF) 00871 return -1; 00872 00873 bio->linelength= 0; 00874 } 00875 00876 if (putc(((unsigned char) c), so) == EOF) 00877 return -1; 00878 00879 bio->linelength++; 00880 00881 return 1; 00882 }
| static int base_encode | ( | char * | filename, | |
| FILE * | so | |||
| ) | [static] |
Definition at line 886 of file app_minivm.c.
References ast_log(), B64_BASEMAXINLINE, b64_inchar(), b64_ochar(), EOL, errno, b64_baseio::iocp, and LOG_WARNING.
Referenced by add_email_attachment(), and sendmail().
00887 { 00888 unsigned char dtable[B64_BASEMAXINLINE]; 00889 int i,hiteof= 0; 00890 FILE *fi; 00891 struct b64_baseio bio; 00892 00893 memset(&bio, 0, sizeof(bio)); 00894 bio.iocp = B64_BASEMAXINLINE; 00895 00896 if (!(fi = fopen(filename, "rb"))) { 00897 ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 00898 return -1; 00899 } 00900 00901 for (i= 0; i<9; i++) { 00902 dtable[i]= 'A'+i; 00903 dtable[i+9]= 'J'+i; 00904 dtable[26+i]= 'a'+i; 00905 dtable[26+i+9]= 'j'+i; 00906 } 00907 for (i= 0; i < 8; i++) { 00908 dtable[i+18]= 'S'+i; 00909 dtable[26+i+18]= 's'+i; 00910 } 00911 for (i= 0; i < 10; i++) { 00912 dtable[52+i]= '0'+i; 00913 } 00914 dtable[62]= '+'; 00915 dtable[63]= '/'; 00916 00917 while (!hiteof){ 00918 unsigned char igroup[3], ogroup[4]; 00919 int c,n; 00920 00921 igroup[0]= igroup[1]= igroup[2]= 0; 00922 00923 for (n= 0; n < 3; n++) { 00924 if ((c = b64_inchar(&bio, fi)) == EOF) { 00925 hiteof= 1; 00926 break; 00927 } 00928 igroup[n]= (unsigned char)c; 00929 } 00930 00931 if (n> 0) { 00932 ogroup[0]= dtable[igroup[0]>>2]; 00933 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 00934 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 00935 ogroup[3]= dtable[igroup[2]&0x3F]; 00936 00937 if (n<3) { 00938 ogroup[3]= '='; 00939 00940 if (n<2) 00941 ogroup[2]= '='; 00942 } 00943 00944 for (i= 0;i<4;i++) 00945 b64_ochar(&bio, ogroup[i], so); 00946 } 00947 } 00948 00949 /* Put end of line - line feed */ 00950 if (fputs(EOL, so) == EOF) 00951 return 0; 00952 00953 fclose(fi); 00954 00955 return 1; 00956 }
| static int check_dirpath | ( | char * | dest, | |
| int | len, | |||
| char * | domain, | |||
| char * | username, | |||
| char * | folder | |||
| ) | [static] |
Definition at line 1486 of file app_minivm.c.
References FALSE, make_dir(), and TRUE.
Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().
01487 { 01488 struct stat filestat; 01489 make_dir(dest, len, domain, username, folder ? folder : ""); 01490 if (stat(dest, &filestat)== -1) 01491 return FALSE; 01492 else 01493 return TRUE; 01494 }
| static int check_mime | ( | const char * | str | ) | [static] |
Definition at line 1125 of file app_minivm.c.
Referenced by make_email_file(), sendmail(), and sendpage().
01126 { 01127 for (; *str; str++) { 01128 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 01129 return 1; 01130 } 01131 } 01132 return 0; 01133 }
| static char* complete_minivm_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 2979 of file app_minivm.c.
References AST_LIST_TRAVERSE, ast_strdup, and minivm_account::domain.
Referenced by handle_minivm_show_users().
02980 { 02981 int which = 0; 02982 int wordlen; 02983 struct minivm_account *vmu; 02984 const char *domain = ""; 02985 02986 /* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */ 02987 if (pos > 4) 02988 return NULL; 02989 if (pos == 3) 02990 return (state == 0) ? ast_strdup("for") : NULL; 02991 wordlen = strlen(word); 02992 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 02993 if (!strncasecmp(word, vmu->domain, wordlen)) { 02994 if (domain && strcmp(domain, vmu->domain) && ++which > state) 02995 return ast_strdup(vmu->domain); 02996 /* ignore repeated domains ? */ 02997 domain = vmu->domain; 02998 } 02999 } 03000 return NULL; 03001 }
| static int create_dirpath | ( | char * | dest, | |
| int | len, | |||
| char * | domain, | |||
| char * | username, | |||
| char * | folder | |||
| ) | [static] |
Definition at line 1505 of file app_minivm.c.
References ast_debug, ast_log(), ast_mkdir(), LOG_WARNING, and make_dir().
Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), minivm_counter_func_read(), minivm_counter_func_write(), open_mailbox(), and save_to_folder().
01506 { 01507 int res; 01508 make_dir(dest, len, domain, username, folder); 01509 if ((res = ast_mkdir(dest, 0777))) { 01510 ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01511 return -1; 01512 } 01513 ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest); 01514 return 0; 01515 }
| static int create_vmaccount | ( | char * | name, | |
| struct ast_variable * | var, | |||
| int | realtime | |||
| ) | [static] |
Append new mailbox to mailbox list from configuration file.
Definition at line 2524 of file app_minivm.c.
References minivm_account::accountcode, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_new(), minivm_account::chanvars, minivm_account::domain, minivm_account::email, minivm_account::etemplate, minivm_account::externnotify, minivm_account::fullname, global_stats, minivm_account::language, LOG_ERROR, ast_variable::name, ast_variable::next, minivm_account::pager, minivm_account::pincode, populate_defaults(), minivm_account::ptemplate, minivm_account::serveremail, minivm_account::username, ast_variable::value, minivm_stats::voicemailaccounts, minivm_account::volgain, and minivm_account::zonetag.
Referenced by find_user_realtime(), and load_config().
02525 { 02526 struct minivm_account *vmu; 02527 char *domain; 02528 char *username; 02529 char accbuf[BUFSIZ]; 02530 02531 ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name); 02532 02533 ast_copy_string(accbuf, name, sizeof(accbuf)); 02534 username = accbuf; 02535 domain = strchr(accbuf, '@'); 02536 if (domain) { 02537 *domain = '\0'; 02538 domain++; 02539 } 02540 if (ast_strlen_zero(domain)) { 02541 ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name); 02542 return 0; 02543 } 02544 02545 ast_debug(3, "Creating static account for user %s domain %s\n", username, domain); 02546 02547 /* Allocate user account */ 02548 vmu = ast_calloc(1, sizeof(*vmu)); 02549 if (!vmu) 02550 return 0; 02551 02552 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 02553 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 02554 02555 populate_defaults(vmu); 02556 02557 ast_debug(3, "...Configuring account %s\n", name); 02558 02559 while (var) { 02560 ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name); 02561 if (!strcasecmp(var->name, "serveremail")) { 02562 ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail)); 02563 } else if (!strcasecmp(var->name, "email")) { 02564 ast_copy_string(vmu->email, var->value, sizeof(vmu->email)); 02565 } else if (!strcasecmp(var->name, "accountcode")) { 02566 ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode)); 02567 } else if (!strcasecmp(var->name, "pincode")) { 02568 ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode)); 02569 } else if (!strcasecmp(var->name, "domain")) { 02570 ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain)); 02571 } else if (!strcasecmp(var->name, "language")) { 02572 ast_copy_string(vmu->language, var->value, sizeof(vmu->language)); 02573 } else if (!strcasecmp(var->name, "timezone")) { 02574 ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag)); 02575 } else if (!strcasecmp(var->name, "externnotify")) { 02576 ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify)); 02577 } else if (!strcasecmp(var->name, "etemplate")) { 02578 ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate)); 02579 } else if (!strcasecmp(var->name, "ptemplate")) { 02580 ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate)); 02581 } else if (!strcasecmp(var->name, "fullname")) { 02582 ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname)); 02583 } else if (!strcasecmp(var->name, "setvar")) { 02584 char *varval; 02585 char *varname = ast_strdupa(var->value); 02586 struct ast_variable *tmpvar; 02587 02588 if (varname && (varval = strchr(varname, '='))) { 02589 *varval = '\0'; 02590 varval++; 02591 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 02592 tmpvar->next = vmu->chanvars; 02593 vmu->chanvars = tmpvar; 02594 } 02595 } 02596 } else if (!strcasecmp(var->name, "pager")) { 02597 ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager)); 02598 } else if (!strcasecmp(var->name, "volgain")) { 02599 sscanf(var->value, "%30lf", &vmu->volgain); 02600 } else { 02601 ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name); 02602 } 02603 var = var->next; 02604 } 02605 ast_debug(3, "...Linking account %s\n", name); 02606 02607 AST_LIST_LOCK(&minivm_accounts); 02608 AST_LIST_INSERT_TAIL(&minivm_accounts, vmu, list); 02609 AST_LIST_UNLOCK(&minivm_accounts); 02610 02611 global_stats.voicemailaccounts++; 02612 02613 ast_debug(2, "MVM :: Created account %s@%s - tz %s etemplate %s %s\n", username, domain, ast_strlen_zero(vmu->zonetag) ? "" : vmu->zonetag, ast_strlen_zero(vmu->etemplate) ? "" : vmu->etemplate, realtime ? "(realtime)" : ""); 02614 return 0; 02615 }
| static struct minivm_account* find_account | ( | const char * | domain, | |
| const char * | username, | |||
| int | createtemp | |||
| ) | [static, read] |
Definition at line 1048 of file app_minivm.c.
References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set2_flag, ast_strlen_zero(), minivm_account::domain, find_user_realtime(), LOG_NOTICE, MVM_ALLOCED, mvm_user_alloc(), TRUE, and minivm_account::username.
Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_counter_func_read(), minivm_counter_func_write(), minivm_greet_exec(), and minivm_notify_exec().
01049 { 01050 struct minivm_account *vmu = NULL, *cur; 01051 01052 01053 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 01054 ast_log(LOG_NOTICE, "No username or domain? \n"); 01055 return NULL; 01056 } 01057 ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain); 01058 01059 AST_LIST_LOCK(&minivm_accounts); 01060 AST_LIST_TRAVERSE(&minivm_accounts, cur, list) { 01061 /* Is this the voicemail account we're looking for? */ 01062 if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username)) 01063 break; 01064 } 01065 AST_LIST_UNLOCK(&minivm_accounts); 01066 01067 if (cur) { 01068 ast_debug(3, "Found account for %s@%s\n", username, domain); 01069 vmu = cur; 01070 01071 } else 01072 vmu = find_user_realtime(domain, username); 01073 01074 if (createtemp && !vmu) { 01075 /* Create a temporary user, send e-mail and be gone */ 01076 vmu = mvm_user_alloc(); 01077 ast_set2_flag(vmu, TRUE, MVM_ALLOCED); 01078 if (vmu) { 01079 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 01080 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 01081 ast_debug(1, "Created temporary account\n"); 01082 } 01083 01084 } 01085 return vmu; 01086 }
| static struct minivm_account * find_user_realtime | ( | const char * | domain, | |
| const char * | username | |||
| ) | [static, read] |
Definition at line 1092 of file app_minivm.c.
References ast_copy_string(), ast_free, ast_load_realtime(), ast_variables_destroy(), create_vmaccount(), MAXHOSTNAMELEN, mvm_user_alloc(), populate_defaults(), SENTINEL, TRUE, minivm_account::username, and var.
Referenced by find_account(), and find_user().
01093 { 01094 struct ast_variable *var; 01095 struct minivm_account *retval; 01096 char name[MAXHOSTNAMELEN]; 01097 01098 retval = mvm_user_alloc(); 01099 if (!retval) 01100 return NULL; 01101 01102 if (username) 01103 ast_copy_string(retval->username, username, sizeof(retval->username)); 01104 01105 populate_defaults(retval); 01106 var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL); 01107 01108 if (!var) { 01109 ast_free(retval); 01110 return NULL; 01111 } 01112 01113 snprintf(name, sizeof(name), "%s@%s", username, domain); 01114 create_vmaccount(name, var, TRUE); 01115 01116 ast_variables_destroy(var); 01117 return retval; 01118 }
| static void free_user | ( | struct minivm_account * | vmu | ) | [static] |
Definition at line 970 of file app_minivm.c.
References ast_free, ast_variables_destroy(), and minivm_account::chanvars.
Referenced by forward_message(), free_vm_users(), leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), and vm_execmain().
00971 { 00972 if (vmu->chanvars) 00973 ast_variables_destroy(vmu->chanvars); 00974 ast_free(vmu); 00975 }
| static void free_zone | ( | struct minivm_zone * | z | ) | [static] |
Free Mini Voicemail timezone.
Definition at line 2618 of file app_minivm.c.
References ast_free.
Referenced by free_vm_zones(), and timezone_destroy_list().
02619 { 02620 ast_free(z); 02621 }
| static int get_date | ( | char * | s, | |
| int | len | |||
| ) | [static] |
Definition at line 958 of file app_minivm.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail(), and tds_log().
00959 { 00960 struct ast_tm tm; 00961 struct timeval now = ast_tvnow(); 00962 00963 ast_localtime(&now, &tm, NULL); 00964 return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm); 00965 }
| static char* handle_minivm_list_templates | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI routine for listing templates.
Definition at line 2938 of file app_minivm.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVLT_OUTPUT_FORMAT, and ast_cli_entry::usage.
02939 { 02940 struct minivm_template *this; 02941 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" 02942 int count = 0; 02943 02944 switch (cmd) { 02945 case CLI_INIT: 02946 e->command = "minivm list templates"; 02947 e->usage = 02948 "Usage: minivm list templates\n" 02949 " Lists message templates for e-mail, paging and IM\n"; 02950 return NULL; 02951 case CLI_GENERATE: 02952 return NULL; 02953 } 02954 02955 if (a->argc > 3) 02956 return CLI_SHOWUSAGE; 02957 02958 AST_LIST_LOCK(&message_templates); 02959 if (AST_LIST_EMPTY(&message_templates)) { 02960 ast_cli(a->fd, "There are no message templates defined\n"); 02961 AST_LIST_UNLOCK(&message_templates); 02962 return CLI_FAILURE; 02963 } 02964 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject"); 02965 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------"); 02966 AST_LIST_TRAVERSE(&message_templates, this, list) { 02967 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name, 02968 this->charset ? this->charset : "-", 02969 this->locale ? this->locale : "-", 02970 this->attachment ? "Yes" : "No", 02971 this->subject ? this->subject : "-"); 02972 count++; 02973 } 02974 AST_LIST_UNLOCK(&message_templates); 02975 ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count); 02976 return CLI_SUCCESS; 02977 }
| static char * handle_minivm_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Reload cofiguration.
Definition at line 3499 of file app_minivm.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, reload, and ast_cli_entry::usage.
03500 { 03501 03502 switch (cmd) { 03503 case CLI_INIT: 03504 e->command = "minivm reload"; 03505 e->usage = 03506 "Usage: minivm reload\n" 03507 " Reload mini-voicemail configuration and reset statistics\n"; 03508 return NULL; 03509 case CLI_GENERATE: 03510 return NULL; 03511 } 03512 03513 reload(); 03514 ast_cli(a->fd, "\n-- Mini voicemail re-configured \n"); 03515 return CLI_SUCCESS; 03516 }
| static char* handle_minivm_show_settings | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI Show settings.
Definition at line 3089 of file app_minivm.c.
References ast_cli(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, default_vmformat, ast_cli_args::fd, global_externnotify, global_logfile, global_mailcmd, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, MVM_OPERATOR, MVM_REVIEW, and ast_cli_entry::usage.
03090 { 03091 switch (cmd) { 03092 case CLI_INIT: 03093 e->command = "minivm show settings"; 03094 e->usage = 03095 "Usage: minivm show settings\n" 03096 " Display Mini-Voicemail general settings\n"; 03097 return NULL; 03098 case CLI_GENERATE: 03099 return NULL; 03100 } 03101 03102 ast_cli(a->fd, "* Mini-Voicemail general settings\n"); 03103 ast_cli(a->fd, " -------------------------------\n"); 03104 ast_cli(a->fd, "\n"); 03105 ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd); 03106 ast_cli(a->fd, " Max silence: %d\n", global_maxsilence); 03107 ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold); 03108 ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage); 03109 ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage); 03110 ast_cli(a->fd, " Default format: %s\n", default_vmformat); 03111 ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify); 03112 ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>"); 03113 ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No"); 03114 ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No"); 03115 03116 ast_cli(a->fd, "\n"); 03117 return CLI_SUCCESS; 03118 }
| static char* handle_minivm_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show stats.
Definition at line 3121 of file app_minivm.c.
References ast_cli(), ast_localtime(), ast_strftime(), buf, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_stats, minivm_stats::lastreceived, minivm_stats::receivedmessages, minivm_stats::reset, minivm_stats::templates, minivm_stats::timezones, ast_cli_entry::usage, and minivm_stats::voicemailaccounts.
03122 { 03123 struct ast_tm timebuf; 03124 char buf[BUFSIZ]; 03125 03126 switch (cmd) { 03127 03128 case CLI_INIT: 03129 e->command = "minivm show stats"; 03130 e->usage = 03131 "Usage: minivm show stats\n" 03132 " Display Mini-Voicemail counters\n"; 03133 return NULL; 03134 case CLI_GENERATE: 03135 return NULL; 03136 } 03137 03138 ast_cli(a->fd, "* Mini-Voicemail statistics\n"); 03139 ast_cli(a->fd, " -------------------------\n"); 03140 ast_cli(a->fd, "\n"); 03141 ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts); 03142 ast_cli(a->fd, " Templates: %5d\n", global_stats.templates); 03143 ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones); 03144 if (global_stats.receivedmessages == 0) { 03145 ast_cli(a->fd, " Received messages since last reset: <none>\n"); 03146 } else { 03147 ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages); 03148 ast_localtime(&global_stats.lastreceived, &timebuf, NULL); 03149 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 03150 ast_cli(a->fd, " Last received voicemail: %s\n", buf); 03151 } 03152 ast_localtime(&global_stats.reset, &timebuf, NULL); 03153 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 03154 ast_cli(a->fd, " Last reset: %s\n", buf); 03155 03156 ast_cli(a->fd, "\n"); 03157 return CLI_SUCCESS; 03158 }
| static char* handle_minivm_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI command to list voicemail accounts.
Definition at line 3004 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, minivm_account::attachfmt, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_minivm_show_users(), minivm_account::domain, minivm_account::etemplate, ast_cli_args::fd, minivm_account::fullname, HMSU_OUTPUT_FORMAT, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, minivm_account::ptemplate, ast_cli_entry::usage, minivm_account::username, ast_cli_args::word, and minivm_account::zonetag.
03005 { 03006 struct minivm_account *vmu; 03007 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" 03008 int count = 0; 03009 03010 switch (cmd) { 03011 case CLI_INIT: 03012 e->command = "minivm list accounts"; 03013 e->usage = 03014 "Usage: minivm list accounts\n" 03015 " Lists all mailboxes currently set up\n"; 03016 return NULL; 03017 case CLI_GENERATE: 03018 return complete_minivm_show_users(a->line, a->word, a->pos, a->n); 03019 } 03020 03021 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 03022 return CLI_SHOWUSAGE; 03023 if ((a->argc == 5) && strcmp(a->argv[3],"for")) 03024 return CLI_SHOWUSAGE; 03025 03026 AST_LIST_LOCK(&minivm_accounts); 03027 if (AST_LIST_EMPTY(&minivm_accounts)) { 03028 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 03029 AST_LIST_UNLOCK(&minivm_accounts); 03030 return CLI_FAILURE; 03031 } 03032 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name"); 03033 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------"); 03034 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 03035 char tmp[256] = ""; 03036 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) { 03037 count++; 03038 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain); 03039 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-", 03040 vmu->ptemplate ? vmu->ptemplate : "-", 03041 vmu->zonetag ? vmu->zonetag : "-", 03042 vmu->attachfmt ? vmu->attachfmt : "-", 03043 vmu->fullname); 03044 } 03045 } 03046 AST_LIST_UNLOCK(&minivm_accounts); 03047 ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count); 03048 return CLI_SUCCESS; 03049 }
| static char* handle_minivm_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 3052 of file app_minivm.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, HMSZ_OUTPUT_FORMAT, minivm_zone::msg_format, minivm_zone::name, minivm_zone::timezone, and ast_cli_entry::usage.
03053 { 03054 struct minivm_zone *zone; 03055 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 03056 char *res = CLI_SUCCESS; 03057 03058 switch (cmd) { 03059 case CLI_INIT: 03060 e->command = "minivm list zones"; 03061 e->usage = 03062 "Usage: minivm list zones\n" 03063 " Lists zone message formats\n"; 03064 return NULL; 03065 case CLI_GENERATE: 03066 return NULL; 03067 } 03068 03069 if (a->argc != e->args) 03070 return CLI_SHOWUSAGE; 03071 03072 AST_LIST_LOCK(&minivm_zones); 03073 if (!AST_LIST_EMPTY(&minivm_zones)) { 03074 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 03075 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------"); 03076 AST_LIST_TRAVERSE(&minivm_zones, zone, list) { 03077 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 03078 } 03079 } else { 03080 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 03081 res = CLI_FAILURE; 03082 } 03083 AST_LIST_UNLOCK(&minivm_zones); 03084 03085 return res; 03086 }
| static int invent_message | ( | struct ast_channel * | chan, | |
| char * | domain, | |||
| char * | username, | |||
| int | busy, | |||
| char * | ecodes | |||
| ) | [static] |
Definition at line 1521 of file app_minivm.c.
References ast_debug, ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), FALSE, and ast_channel::language.
Referenced by leave_voicemail(), and minivm_greet_exec().
01522 { 01523 int res; 01524 char fn[PATH_MAX]; 01525 01526 ast_debug(2, "Still preparing to play message ...\n"); 01527 01528 snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username); 01529 01530 if (ast_fileexists(fn, NULL, NULL) > 0) { 01531 res = ast_streamfile(chan, fn, chan->language); 01532 if (res) 01533 return -1; 01534 res = ast_waitstream(chan, ecodes); 01535 if (res) 01536 return res; 01537 } else { 01538 int numericusername = 1; 01539 char *i = username; 01540 01541 ast_debug(2, "No personal prompts. Using default prompt set for language\n"); 01542 01543 while (*i) { 01544 ast_debug(2, "Numeric? Checking %c\n", *i); 01545 if (!isdigit(*i)) { 01546 numericusername = FALSE; 01547 break; 01548 } 01549 i++; 01550 } 01551 01552 if (numericusername) { 01553 if (ast_streamfile(chan, "vm-theperson", chan->language)) 01554 return -1; 01555 if ((res = ast_waitstream(chan, ecodes))) 01556 return res; 01557 01558 res = ast_say_digit_str(chan, username, ecodes, chan->language); 01559 if (res) 01560 return res; 01561 } else { 01562 if (ast_streamfile(chan, "vm-theextensionis", chan->language)) 01563 return -1; 01564 if ((res = ast_waitstream(chan, ecodes))) 01565 return res; 01566 } 01567 } 01568 01569 res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language); 01570 if (res) 01571 return -1; 01572 res = ast_waitstream(chan, ecodes); 01573 return res; 01574 }
| static int leave_voicemail | ( | struct ast_channel * | chan, | |
| char * | username, | |||
| struct leave_vm_options * | options | |||
| ) | [static] |
Definition at line 1822 of file app_minivm.c.
References minivm_account::accountcode, ast_callerid_merge(), ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_localtime(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_streamfile(), ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_verb, ast_waitstream(), minivm_account::attachfmt, check_dirpath(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, create_dirpath(), default_vmformat, minivm_account::domain, errno, ast_channel::exten, find_account(), free_user(), get_date(), global_stats, global_vmmaxmessage, global_vmminmessage, ast_channel::language, minivm_stats::lastreceived, LOG_ERROR, LOG_WARNING, ast_channel::macrocontext, minivmlogfile, minivmloglock, MVM_ALLOCED, ast_channel::name, pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, minivm_stats::receivedmessages, leave_vm_options::record_gain, and TRUE.
Referenced by advanced_options(), forward_message(), minivm_record_exec(), and vm_exec().
01823 { 01824 char tmptxtfile[PATH_MAX]; 01825 char callerid[256]; 01826 FILE *txt; 01827 int res = 0, txtdes; 01828 int msgnum; 01829 int duration = 0; 01830 char date[256]; 01831 char tmpdir[PATH_MAX]; 01832 char ext_context[256] = ""; 01833 char fmt[80]; 01834 char *domain; 01835 char tmp[256] = ""; 01836 struct minivm_account *vmu; 01837 int userdir; 01838 01839 ast_copy_string(tmp, username, sizeof(tmp)); 01840 username = tmp; 01841 domain = strchr(tmp, '@'); 01842 if (domain) { 01843 *domain = '\0'; 01844 domain++; 01845 } 01846 01847 if (!(vmu = find_account(domain, username, TRUE))) { 01848 /* We could not find user, let's exit */ 01849 ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain); 01850 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01851 return 0; 01852 } 01853 01854 /* Setup pre-file if appropriate */ 01855 if (strcmp(vmu->domain, "localhost")) 01856 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 01857 else 01858 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 01859 01860 /* The meat of recording the message... All the announcements and beeps have been played*/ 01861 if (ast_strlen_zero(vmu->attachfmt)) 01862 ast_copy_string(fmt, default_vmformat, sizeof(fmt)); 01863 else 01864 ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt)); 01865 01866 if (ast_strlen_zero(fmt)) { 01867 ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat); 01868 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01869 return res; 01870 } 01871 msgnum = 0; 01872 01873 userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp"); 01874 01875 /* If we have no user directory, use generic temporary directory */ 01876 if (!userdir) { 01877 create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", ""); 01878 ast_debug(3, "Creating temporary directory %s\n", tmpdir); 01879 } 01880 01881 01882 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 01883 01884 /* XXX This file needs to be in temp directory */ 01885 txtdes = mkstemp(tmptxtfile); 01886 if (txtdes < 0) { 01887 ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno)); 01888 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 01889 if (!res) 01890 res = ast_waitstream(chan, ""); 01891 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01892 return res; 01893 } 01894 01895 if (res >= 0) { 01896 /* Unless we're *really* silent, try to send the beep */ 01897 res = ast_streamfile(chan, "beep", chan->language); 01898 if (!res) 01899 res = ast_waitstream(chan, ""); 01900 } 01901 01902 /* OEJ XXX Maybe this can be turned into a log file? Hmm. */ 01903 /* Store information */ 01904 ast_debug(2, "Open file for metadata: %s\n", tmptxtfile); 01905 01906 res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain); 01907 01908 txt = fdopen(txtdes, "w+"); 01909 if (!txt) { 01910 ast_log(LOG_WARNING, "Error opening text file for output\n"); 01911 } else { 01912 struct ast_tm tm; 01913 struct timeval now = ast_tvnow(); 01914 char timebuf[30]; 01915 char logbuf[BUFSIZ]; 01916 get_date(date, sizeof(date)); 01917 ast_localtime(&now, &tm, NULL); 01918 ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm); 01919 01920 snprintf(logbuf, sizeof(logbuf), 01921 /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */ 01922 "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n", 01923 username, 01924 chan->context, 01925 chan->macrocontext, 01926 chan->exten, 01927 chan->priority, 01928 chan->name, 01929 ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), 01930 date, 01931 timebuf, 01932 duration, 01933 duration < global_vmminmessage ? "IGNORED" : "OK", 01934 vmu->accountcode 01935 ); 01936 fprintf(txt, "%s", logbuf); 01937 if (minivmlogfile) { 01938 ast_mutex_lock(&minivmloglock); 01939 fprintf(minivmlogfile, "%s", logbuf); 01940 ast_mutex_unlock(&minivmloglock); 01941 } 01942 01943 if (duration < global_vmminmessage) { 01944 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, global_vmminmessage); 01945 fclose(txt); 01946 ast_filedelete(tmptxtfile, NULL); 01947 unlink(tmptxtfile); 01948 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01949 return 0; 01950 } 01951 fclose(txt); /* Close log file */ 01952 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01953 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 01954 unlink(tmptxtfile); 01955 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01956 if(ast_test_flag(vmu, MVM_ALLOCED)) 01957 free_user(vmu); 01958 return 0; 01959 } 01960 01961 /* Set channel variables for the notify application */ 01962 pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile); 01963 snprintf(timebuf, sizeof(timebuf), "%d", duration); 01964 pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf); 01965 pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt); 01966 01967 } 01968 global_stats.lastreceived = ast_tvnow(); 01969 global_stats.receivedmessages++; 01970 #if 0 01971 /* Go ahead and delete audio files from system, they're not needed any more */ 01972 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01973 ast_filedelete(tmptxtfile, NULL); 01974 /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */ 01975 ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile); 01976 } 01977 #endif 01978 01979 if (res > 0) 01980 res = 0; 01981 01982 if(ast_test_flag(vmu, MVM_ALLOCED)) 01983 free_user(vmu); 01984 01985 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 01986 return res; 01987 }
| static int load_config | ( | int | reload | ) | [static] |
Load minivoicemail configuration.
Definition at line 2798 of file app_minivm.c.
References apply_general_options(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set2_flag, ast_strlen_zero(), ast_tvnow(), ast_variable_browse(), ast_variable_retrieve(), chanvar, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, create_vmaccount(), default_vmformat, errno, FALSE, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_saydurationminfo, global_silencethreshold, global_stats, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_ERROR, LOG_WARNING, message_destroy_list(), message_template_build(), message_template_find(), message_template_parse_emailbody(), minivmlock, minivmlogfile, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, minivm_stats::reset, SENDMAIL, THRESHOLD_SILENCE, timezone_add(), timezone_destroy_list(), TRUE, ast_variable::value, var, vmaccounts_destroy_list(), and VOICEMAIL_CONFIG.
02799 { 02800 struct ast_config *cfg; 02801 struct ast_variable *var; 02802 char *cat; 02803 const char *chanvar; 02804 int error = 0; 02805 struct minivm_template *template; 02806 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 02807 02808 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 02809 if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 02810 return 0; 02811 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02812 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 02813 return 0; 02814 } 02815 02816 ast_mutex_lock(&minivmlock); 02817 02818 /* Destroy lists to reconfigure */ 02819 message_destroy_list(); /* Destroy list of voicemail message templates */ 02820 timezone_destroy_list(); /* Destroy list of timezones */ 02821 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 02822 ast_debug(2, "Destroyed memory objects...\n"); 02823 02824 /* First, set some default settings */ 02825 global_externnotify[0] = '\0'; 02826 global_logfile[0] = '\0'; 02827 global_vmmaxmessage = 2000; 02828 global_maxgreet = 2000; 02829 global_vmminmessage = 0; 02830 strcpy(global_mailcmd, SENDMAIL); 02831 global_maxsilence = 0; 02832 global_saydurationminfo = 2; 02833 ast_copy_string(default_vmformat, "wav", sizeof(default_vmformat)); 02834 ast_set2_flag((&globalflags), FALSE, MVM_REVIEW); 02835 ast_set2_flag((&globalflags), FALSE, MVM_OPERATOR); 02836 /* Reset statistics */ 02837 memset(&global_stats, 0, sizeof(global_stats)); 02838 global_stats.reset = ast_tvnow(); 02839 02840 global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 02841 02842 /* Make sure we could load configuration file */ 02843 if (!cfg) { 02844 ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n"); 02845 ast_mutex_unlock(&minivmlock); 02846 return 0; 02847 } 02848 02849 ast_debug(2, "Loaded configuration file, now parsing\n"); 02850 02851 /* General settings */ 02852 02853 cat = ast_category_browse(cfg, NULL); 02854 while (cat) { 02855 ast_debug(3, "Found configuration section [%s]\n", cat); 02856 if (!strcasecmp(cat, "general")) { 02857 /* Nothing right now */ 02858 error += apply_general_options(ast_variable_browse(cfg, cat)); 02859 } else if (!strncasecmp(cat, "template-", 9)) { 02860 /* Template */ 02861 char *name = cat + 9; 02862 02863 /* Now build and link template to list */ 02864 error += message_template_build(name, ast_variable_browse(cfg, cat)); 02865 } else { 02866 var = ast_variable_browse(cfg, cat); 02867 if (!strcasecmp(cat, "zonemessages")) { 02868 /* Timezones in this context */ 02869 while (var) { 02870 timezone_add(var->name, var->value); 02871 var = var->next; 02872 } 02873 } else { 02874 /* Create mailbox from this */ 02875 error += create_vmaccount(cat, var, FALSE); 02876 } 02877 } 02878 /* Find next section in configuration file */ 02879 cat = ast_category_browse(cfg, cat); 02880 } 02881 02882 /* Configure the default email template */ 02883 message_template_build("email-default", NULL); 02884 template = message_template_find("email-default"); 02885 02886 /* Load date format config for voicemail mail */ 02887 if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat"))) 02888 ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat)); 02889 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring"))) 02890 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02891 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress"))) 02892 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02893 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset"))) 02894 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02895 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject"))) 02896 ast_copy_string(template->subject, chanvar, sizeof(template->subject)); 02897 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody"))) 02898 template->body = message_template_parse_emailbody(chanvar); 02899 template->attachment = TRUE; 02900 02901 message_template_build("pager-default", NULL); 02902 template = message_template_find("pager-default"); 02903 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 02904 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02905 if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress"))) 02906 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02907 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset"))) 02908 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02909 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject"))) 02910 ast_copy_string(template->subject, chanvar,sizeof(template->subject)); 02911 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody"))) 02912 template->body = message_template_parse_emailbody(chanvar); 02913 template->attachment = FALSE; 02914 02915 if (error) 02916 ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error); 02917 02918 ast_mutex_unlock(&minivmlock); 02919 ast_config_destroy(cfg); 02920 02921 /* Close log file if it's open and disabled */ 02922 if(minivmlogfile) 02923 fclose(minivmlogfile); 02924 02925 /* Open log file if it's enabled */ 02926 if(!ast_strlen_zero(global_logfile)) { 02927 minivmlogfile = fopen(global_logfile, "a"); 02928 if(!minivmlogfile) 02929 ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno)); 02930 if (minivmlogfile) 02931 ast_debug(3, "Opened log file %s \n", global_logfile); 02932 } 02933 02934 return 0; 02935 }
| static int load_module | ( | void | ) | [static] |
Load mini voicemail module.
Definition at line 3465 of file app_minivm.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_register_application_xml, cli_minivm, load_config(), minivm_accmess_exec(), minivm_account_function, minivm_counter_function, minivm_delete_exec(), minivm_greet_exec(), minivm_mwi_exec(), minivm_notify_exec(), and minivm_record_exec().
03466 { 03467 int res; 03468 03469 res = ast_register_application_xml(app_minivm_record, minivm_record_exec); 03470 res = ast_register_application_xml(app_minivm_greet, minivm_greet_exec); 03471 res = ast_register_application_xml(app_minivm_notify, minivm_notify_exec); 03472 res = ast_register_application_xml(app_minivm_delete, minivm_delete_exec); 03473 res = ast_register_application_xml(app_minivm_accmess, minivm_accmess_exec); 03474 res = ast_register_application_xml(app_minivm_mwi, minivm_mwi_exec); 03475 03476 ast_custom_function_register(&minivm_account_function); 03477 ast_custom_function_register(&minivm_counter_function); 03478 if (res) 03479 return(res); 03480 03481 if ((res = load_config(0))) 03482 return(res); 03483 03484 ast_cli_register_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03485 03486 /* compute the location of the voicemail spool directory */ 03487 snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 03488 03489 return res; 03490 }
| static int make_dir | ( | char * | dest, | |
| int | len, | |||
| const char * | domain, | |||
| const char * | username, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 1472 of file app_minivm.c.
References ast_strlen_zero().
Referenced by check_dirpath(), copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01473 { 01474 return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : ""); 01475 }
| static void message_destroy_list | ( | void | ) | [static] |
Definition at line 819 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and message_template_free().
Referenced by load_config(), and unload_module().
00820 { 00821 struct minivm_template *this; 00822 AST_LIST_LOCK(&message_templates); 00823 while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list))) { 00824 message_template_free(this); 00825 } 00826 00827 AST_LIST_UNLOCK(&message_templates); 00828 }
| static int message_template_build | ( | const char * | name, | |
| struct ast_variable * | var | |||
| ) | [static] |
Definition at line 734 of file app_minivm.c.
References ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_true(), global_stats, LOG_ERROR, message_template_create(), message_template_parse_emailbody(), message_template_parse_filebody(), ast_variable::name, ast_variable::next, minivm_stats::templates, and ast_variable::value.
Referenced by load_config().
00735 { 00736 struct minivm_template *template; 00737 int error = 0; 00738 00739 template = message_template_create(name); 00740 if (!template) { 00741 ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name); 00742 return -1; 00743 } 00744 00745 while (var) { 00746 ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name); 00747 if (!strcasecmp(var->name, "fromaddress")) { 00748 ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress)); 00749 } else if (!strcasecmp(var->name, "fromemail")) { 00750 ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail)); 00751 } else if (!strcasecmp(var->name, "subject")) { 00752 ast_copy_string(template->subject, var->value, sizeof(template->subject)); 00753 } else if (!strcasecmp(var->name, "locale")) { 00754 ast_copy_string(template->locale, var->value, sizeof(template->locale)); 00755 } else if (!strcasecmp(var->name, "attachmedia")) { 00756 template->attachment = ast_true(var->value); 00757 } else if (!strcasecmp(var->name, "dateformat")) { 00758 ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat)); 00759 } else if (!strcasecmp(var->name, "charset")) { 00760 ast_copy_string(template->charset, var->value, sizeof(template->charset)); 00761 } else if (!strcasecmp(var->name, "templatefile")) { 00762 if (template->body) 00763 ast_free(template->body); 00764 template->body = message_template_parse_filebody(var->value); 00765 if (!template->body) { 00766 ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value); 00767 error++; 00768 } 00769 } else if (!strcasecmp(var->name, "messagebody")) { 00770 if (template->body) 00771 ast_free(template->body); 00772 template->body = message_template_parse_emailbody(var->value); 00773 if (!template->body) { 00774 ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value); 00775 error++; 00776 } 00777 } else { 00778 ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value); 00779 error++; 00780 } 00781 var = var->next; 00782 } 00783 if (error) 00784 ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name); 00785 00786 AST_LIST_LOCK(&message_templates); 00787 AST_LIST_INSERT_TAIL(&message_templates, template, list); 00788 AST_LIST_UNLOCK(&message_templates); 00789 00790 global_stats.templates++; 00791 00792 return error; 00793 }
| static struct minivm_template* message_template_create | ( | const char * | name | ) | [static, read] |
Definition at line 704 of file app_minivm.c.
References ast_calloc, ast_copy_string(), DEFAULT_CHARSET, DEFAULT_DATEFORMAT, and TRUE.
Referenced by message_template_build().
00705 { 00706 struct minivm_template *template; 00707 00708 template = ast_calloc(1, sizeof(*template)); 00709 if (!template) 00710 return NULL; 00711 00712 /* Set some defaults for templates */ 00713 ast_copy_string(template->name, name, sizeof(template->name)); 00714 ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat)); 00715 ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset)); 00716 ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject)); 00717 template->attachment = TRUE; 00718 00719 return template; 00720 }
| static struct minivm_template* message_template_find | ( | const char * | name | ) | [static, read] |
Definition at line 797 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by load_config(), and notify_new_message().
00798 { 00799 struct minivm_template *this, *res = NULL; 00800 00801 if (ast_strlen_zero(name)) 00802 return NULL; 00803 00804 AST_LIST_LOCK(&message_templates); 00805 AST_LIST_TRAVERSE(&message_templates, this, list) { 00806 if (!strcasecmp(this->name, name)) { 00807 res = this; 00808 break; 00809 } 00810 } 00811 AST_LIST_UNLOCK(&message_templates); 00812 00813 return res; 00814 }
| static void message_template_free | ( | struct minivm_template * | template | ) | [static] |
Definition at line 724 of file app_minivm.c.
References ast_free.
Referenced by message_destroy_list().
00725 { 00726 if (template->body) 00727 ast_free(template->body); 00728 00729 ast_free (template); 00730 }
| static char * message_template_parse_emailbody | ( | const char * | body | ) | [static] |
Parse emailbody template from configuration file.
Definition at line 2713 of file app_minivm.c.
References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.
Referenced by load_config(), and message_template_build().
02714 { 02715 char *tmpread, *tmpwrite; 02716 char *emailbody = ast_strdup(configuration); 02717 02718 /* substitute strings \t and \n into the apropriate characters */ 02719 tmpread = tmpwrite = emailbody; 02720 while ((tmpwrite = strchr(tmpread,'\\'))) { 02721 int len = strlen("\n"); 02722 switch (tmpwrite[1]) { 02723 case 'n': 02724 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02725 strncpy(tmpwrite, "\n", len); 02726 break; 02727 case 't': 02728 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02729 strncpy(tmpwrite, "\t", len); 02730 break; 02731 default: 02732 ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]); 02733 } 02734 tmpread = tmpwrite + len; 02735 } 02736 return emailbody; 02737 }
| static char * message_template_parse_filebody | ( | const char * | filename | ) | [static] |
Read message template from file.
Definition at line 2673 of file app_minivm.c.
References ast_calloc, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), buf, and LOG_ERROR.
Referenced by message_template_build().
02673 { 02674 char buf[BUFSIZ * 6]; 02675 char readbuf[BUFSIZ]; 02676 char filenamebuf[BUFSIZ]; 02677 char *writepos; 02678 char *messagebody; 02679 FILE *fi; 02680 int lines = 0; 02681 02682 if (ast_strlen_zero(filename)) 02683 return NULL; 02684 if (*filename == '/') 02685 ast_copy_string(filenamebuf, filename, sizeof(filenamebuf)); 02686 else 02687 snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 02688 02689 if (!(fi = fopen(filenamebuf, "r"))) { 02690 ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf); 02691 return NULL; 02692 } 02693 writepos = buf; 02694 while (fgets(readbuf, sizeof(readbuf), fi)) { 02695 lines ++; 02696 if (writepos != buf) { 02697 *writepos = '\n'; /* Replace EOL with new line */ 02698 writepos++; 02699 } 02700 ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf)); 02701 writepos += strlen(readbuf) - 1; 02702 } 02703 fclose(fi); 02704 messagebody = ast_calloc(1, strlen(buf + 1)); 02705 ast_copy_string(messagebody, buf, strlen(buf) + 1); 02706 ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) ); 02707 ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody); 02708 02709 return messagebody; 02710 }
| static int minivm_accmess_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Record specific messages for voicemail account.
Definition at line 2420 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_copy_string(), ast_debug, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, default_vmformat, minivm_account::domain, FALSE, find_account(), minivm_account::flags, free_user(), global_maxgreet, LOG_ERROR, LOG_WARNING, minivm_accmess_options, MVM_ALLOCED, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_NAME_GREETING, OPT_TEMP_GREETING, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), play_record_review(), prompt, TRUE, and minivm_account::username.
Referenced by load_module().
02421 { 02422 int argc = 0; 02423 char *argv[2]; 02424 char filename[PATH_MAX]; 02425 char tmp[PATH_MAX]; 02426 char *domain; 02427 char *tmpptr = NULL; 02428 struct minivm_account *vmu; 02429 char *username = argv[0]; 02430 struct ast_flags flags = { 0 }; 02431 char *opts[OPT_ARG_ARRAY_SIZE]; 02432 int error = FALSE; 02433 char *message = NULL; 02434 char *prompt = NULL; 02435 int duration; 02436 int cmd; 02437 02438 if (ast_strlen_zero(data)) { 02439 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02440 error = TRUE; 02441 } else 02442 tmpptr = ast_strdupa((char *)data); 02443 if (!error) { 02444 if (!tmpptr) { 02445 ast_log(LOG_ERROR, "Out of memory\n"); 02446 error = TRUE; 02447 } else 02448 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02449 } 02450 02451 if (argc <=1) { 02452 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02453 error = TRUE; 02454 } 02455 if (!error && strlen(argv[1]) > 1) { 02456 ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]); 02457 error = TRUE; 02458 } 02459 02460 if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) { 02461 ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]); 02462 error = TRUE; 02463 } 02464 02465 if (error) { 02466 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02467 return -1; 02468 } 02469 02470 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02471 username = tmp; 02472 domain = strchr(tmp, '@'); 02473 if (domain) { 02474 *domain = '\0'; 02475 domain++; 02476 } 02477 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02478 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02479 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02480 return -1; 02481 } 02482 02483 if(!(vmu = find_account(domain, username, TRUE))) { 02484 /* We could not find user, let's exit */ 02485 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02486 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02487 return -1; 02488 } 02489 02490 /* Answer channel if it's not already answered */ 02491 if (chan->_state != AST_STATE_UP) 02492 ast_answer(chan); 02493 02494 /* Here's where the action is */ 02495 if (ast_test_flag(&flags, OPT_BUSY_GREETING)) { 02496 message = "busy"; 02497 prompt = "vm-rec-busy"; 02498 } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) { 02499 message = "unavailable"; 02500 prompt = "vm-rec-unv"; 02501 } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) { 02502 message = "temp"; 02503 prompt = "vm-rec-temp"; 02504 } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) { 02505 message = "greet"; 02506 prompt = "vm-rec-name"; 02507 } 02508 snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message); 02509 /* Maybe we should check the result of play_record_review ? */ 02510 cmd = play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, FALSE); 02511 02512 ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration); 02513 02514 if(ast_test_flag(vmu, MVM_ALLOCED)) 02515 free_user(vmu); 02516 02517 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS"); 02518 02519 /* Ok, we're ready to rock and roll. Return to dialplan */ 02520 return 0; 02521 }
| static int minivm_account_func_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${MINIVMACCOUNT()} Dialplan function - reads account data
Definition at line 3161 of file app_minivm.c.
References minivm_account::accountcode, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, minivm_account::chanvars, check_dirpath(), minivm_account::domain, minivm_account::email, minivm_account::etemplate, find_account(), free_user(), minivm_account::fullname, minivm_account::language, LOG_ERROR, MVM_ALLOCED, ast_variable::name, ast_variable::next, minivm_account::pager, minivm_account::pincode, minivm_account::ptemplate, TRUE, minivm_account::username, ast_variable::value, var, and minivm_account::zonetag.
03162 { 03163 struct minivm_account *vmu; 03164 char *username, *domain, *colname; 03165 03166 if (!(username = ast_strdupa(data))) { 03167 ast_log(LOG_ERROR, "Memory Error!\n"); 03168 return -1; 03169 } 03170 03171 if ((colname = strchr(username, ':'))) { 03172 *colname = '\0'; 03173 colname++; 03174 } else { 03175 colname = "path"; 03176 } 03177 if ((domain = strchr(username, '@'))) { 03178 *domain = '\0'; 03179 domain++; 03180 } 03181 if (ast_strlen_zero(username) || ast_strlen_zero(domain)) { 03182 ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n"); 03183 return 0; 03184 } 03185 03186 if (!(vmu = find_account(domain, username, TRUE))) 03187 return 0; 03188 03189 if (!strcasecmp(colname, "hasaccount")) { 03190 ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len); 03191 } else if (!strcasecmp(colname, "fullname")) { 03192 ast_copy_string(buf, vmu->fullname, len); 03193 } else if (!strcasecmp(colname, "email")) { 03194 if (!ast_strlen_zero(vmu->email)) 03195 ast_copy_string(buf, vmu->email, len); 03196 else 03197 snprintf(buf, len, "%s@%s", vmu->username, vmu->domain); 03198 } else if (!strcasecmp(colname, "pager")) { 03199 ast_copy_string(buf, vmu->pager, len); 03200 } else if (!strcasecmp(colname, "etemplate")) { 03201 if (!ast_strlen_zero(vmu->etemplate)) 03202 ast_copy_string(buf, vmu->etemplate, len); 03203 else 03204 ast_copy_string(buf, "email-default", len); 03205 } else if (!strcasecmp(colname, "language")) { 03206 ast_copy_string(buf, vmu->language, len); 03207 } else if (!strcasecmp(colname, "timezone")) { 03208 ast_copy_string(buf, vmu->zonetag, len); 03209 } else if (!strcasecmp(colname, "ptemplate")) { 03210 if (!ast_strlen_zero(vmu->ptemplate)) 03211 ast_copy_string(buf, vmu->ptemplate, len); 03212 else 03213 ast_copy_string(buf, "email-default", len); 03214 } else if (!strcasecmp(colname, "accountcode")) { 03215 ast_copy_string(buf, vmu->accountcode, len); 03216 } else if (!strcasecmp(colname, "pincode")) { 03217 ast_copy_string(buf, vmu->pincode, len); 03218 } else if (!strcasecmp(colname, "path")) { 03219 check_dirpath(buf, len, vmu->domain, vmu->username, NULL); 03220 } else { /* Look in channel variables */ 03221 struct ast_variable *var; 03222 int found = 0; 03223 03224 for (var = vmu->chanvars ; var ; var = var->next) 03225 if (!strcmp(var->name, colname)) { 03226 ast_copy_string(buf, var->value, len); 03227 found = 1; 03228 break; 03229 } 03230 } 03231 03232 if(ast_test_flag(vmu, MVM_ALLOCED)) 03233 free_user(vmu); 03234 03235 return 0; 03236 }
| static int minivm_counter_func_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
${MINIVMCOUNTER()} Dialplan function - read counters
Definition at line 3313 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
03314 { 03315 char *username, *domain, *countername; 03316 struct minivm_account *vmu = NULL; 03317 char userpath[BUFSIZ]; 03318 int res; 03319 03320 *buf = '\0'; 03321 03322 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03323 ast_log(LOG_WARNING, "Memory error!\n"); 03324 return -1; 03325 } 03326 if ((countername = strchr(username, ':'))) { 03327 *countername = '\0'; 03328 countername++; 03329 } 03330 03331 if ((domain = strchr(username, '@'))) { 03332 *domain = '\0'; 03333 domain++; 03334 } 03335 03336 /* If we have neither username nor domain now, let's give up */ 03337 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03338 ast_log(LOG_ERROR, "No account given\n"); 03339 return -1; 03340 } 03341 03342 if (ast_strlen_zero(countername)) { 03343 ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n"); 03344 return -1; 03345 } 03346 03347 /* We only have a domain, no username */ 03348 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03349 domain = username; 03350 username = NULL; 03351 } 03352 03353 /* If we can't find account or if the account is temporary, return. */ 03354 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03355 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03356 return 0; 03357 } 03358 03359 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03360 03361 /* We have the path, now read the counter file */ 03362 res = access_counter_file(userpath, countername, 0, 0); 03363 if (res >= 0) 03364 snprintf(buf, len, "%d", res); 03365 return 0; 03366 }
| static int minivm_counter_func_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
${MINIVMCOUNTER()} Dialplan function - changes counter data
Definition at line 3369 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
03370 { 03371 char *username, *domain, *countername, *operand; 03372 char userpath[BUFSIZ]; 03373 struct minivm_account *vmu; 03374 int change = 0; 03375 int operation = 0; 03376 03377 if(!value) 03378 return -1; 03379 change = atoi(value); 03380 03381 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03382 ast_log(LOG_WARNING, "Memory error!\n"); 03383 return -1; 03384 } 03385 03386 if ((countername = strchr(username, ':'))) { 03387 *countername = '\0'; 03388 countername++; 03389 } 03390 if ((operand = strchr(countername, ':'))) { 03391 *operand = '\0'; 03392 operand++; 03393 } 03394 03395 if ((domain = strchr(username, '@'))) { 03396 *domain = '\0'; 03397 domain++; 03398 } 03399 03400 /* If we have neither username nor domain now, let's give up */ 03401 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03402 ast_log(LOG_ERROR, "No account given\n"); 03403 return -1; 03404 } 03405 03406 /* We only have a domain, no username */ 03407 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03408 domain = username; 03409 username = NULL; 03410 } 03411 03412 if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) { 03413 ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n"); 03414 return -1; 03415 } 03416 03417 /* If we can't find account or if the account is temporary, return. */ 03418 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03419 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03420 return 0; 03421 } 03422 03423 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03424 /* Now, find out our operator */ 03425 if (*operand == 'i') /* Increment */ 03426 operation = 2; 03427 else if (*operand == 'd') { 03428 change = change * -1; 03429 operation = 2; 03430 } else if (*operand == 's') 03431 operation = 1; 03432 else { 03433 ast_log(LOG_ERROR, "Unknown operator: %s\n", operand); 03434 return -1; 03435 } 03436 03437 /* We have the path, now read the counter file */ 03438 access_counter_file(userpath, countername, change, operation); 03439 return 0; 03440 }
| static int minivm_delete_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 2382 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_fileexists(), ast_log(), ast_strlen_zero(), LOG_ERROR, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and vm_delete().
Referenced by load_module().
02383 { 02384 int res = 0; 02385 char filename[BUFSIZ]; 02386 02387 if (!ast_strlen_zero(data)) { 02388 ast_copy_string(filename, (char *) data, sizeof(filename)); 02389 } else { 02390 ast_channel_lock(chan); 02391 ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename)); 02392 ast_channel_unlock(chan); 02393 } 02394 02395 if (ast_strlen_zero(filename)) { 02396 ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n"); 02397 return res; 02398 } 02399 02400 /* Go ahead and delete audio files from system, they're not needed any more */ 02401 /* We should look for both audio and text files here */ 02402 if (ast_fileexists(filename, NULL, NULL) > 0) { 02403 res = vm_delete(filename); 02404 if (res) { 02405 ast_debug(2, "Can't delete file: %s\n", filename); 02406 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02407 } else { 02408 ast_debug(2, "Deleted voicemail file :: %s \n", filename); 02409 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS"); 02410 } 02411 } else { 02412 ast_debug(2, "Filename does not exist: %s\n", filename); 02413 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02414 } 02415 02416 return res; 02417 }
| static int minivm_greet_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 2195 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_copy_flags, ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_play_and_wait(), ast_set_flag, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), check_dirpath(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, minivm_account::domain, minivm_account::exit, ast_channel::exten, find_account(), minivm_account::flags, free_user(), invent_message(), ast_channel::language, LOG_ERROR, ast_channel::macrocontext, minivm_app_options, MVM_ALLOCED, MVM_OPERATOR, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), ast_channel::priority, SOUND_INTRO, TRUE, and minivm_account::username.
Referenced by load_module().
02196 { 02197 struct leave_vm_options leave_options = { 0, '\0'}; 02198 int argc; 02199 char *argv[2]; 02200 struct ast_flags flags = { 0 }; 02201 char *opts[OPT_ARG_ARRAY_SIZE]; 02202 int res = 0; 02203 int ausemacro = 0; 02204 int ousemacro = 0; 02205 int ouseexten = 0; 02206 char tmp[PATH_MAX]; 02207 char dest[PATH_MAX]; 02208 char prefile[PATH_MAX] = ""; 02209 char tempfile[PATH_MAX] = ""; 02210 char ext_context[256] = ""; 02211 char *domain; 02212 char ecodes[16] = "#"; 02213 char *tmpptr; 02214 struct minivm_account *vmu; 02215 char *username = argv[0]; 02216 02217 if (ast_strlen_zero(data)) { 02218 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02219 return -1; 02220 } 02221 tmpptr = ast_strdupa((char *)data); 02222 if (!tmpptr) { 02223 ast_log(LOG_ERROR, "Out of memory\n"); 02224 return -1; 02225 } 02226 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02227 02228 if (argc == 2) { 02229 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) 02230 return -1; 02231 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02232 } 02233 02234 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02235 username = tmp; 02236 domain = strchr(tmp, '@'); 02237 if (domain) { 02238 *domain = '\0'; 02239 domain++; 02240 } 02241 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02242 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]); 02243 return -1; 02244 } 02245 ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain); 02246 02247 if (!(vmu = find_account(domain, username, TRUE))) { 02248 ast_log(LOG_ERROR, "Could not allocate memory. \n"); 02249 return -1; 02250 } 02251 02252 /* Answer channel if it's not already answered */ 02253 if (chan->_state != AST_STATE_UP) 02254 ast_answer(chan); 02255 02256 /* Setup pre-file if appropriate */ 02257 if (strcmp(vmu->domain, "localhost")) 02258 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 02259 else 02260 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 02261 02262 if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) { 02263 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy"); 02264 if (res) 02265 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username); 02266 } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) { 02267 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail"); 02268 if (res) 02269 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username); 02270 } 02271 /* Check for temporary greeting - it overrides busy and unavail */ 02272 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username); 02273 if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) { 02274 ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile); 02275 ast_copy_string(prefile, tempfile, sizeof(prefile)); 02276 } 02277 ast_debug(2, "Preparing to play message ...\n"); 02278 02279 /* Check current or macro-calling context for special extensions */ 02280 if (ast_test_flag(vmu, MVM_OPERATOR)) { 02281 if (!ast_strlen_zero(vmu->exit)) { 02282 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 02283 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02284 ouseexten = 1; 02285 } 02286 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 02287 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02288 ouseexten = 1; 02289 } 02290 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 02291 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02292 ousemacro = 1; 02293 } 02294 } 02295 02296 if (!ast_strlen_zero(vmu->exit)) { 02297 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 02298 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02299 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 02300 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02301 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 02302 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02303 ausemacro = 1; 02304 } 02305 02306 res = 0; /* Reset */ 02307 /* Play the beginning intro if desired */ 02308 if (!ast_strlen_zero(prefile)) { 02309 if (ast_streamfile(chan, prefile, chan->language) > -1) 02310 res = ast_waitstream(chan, ecodes); 02311 } else { 02312 ast_debug(2, "%s doesn't exist, doing what we can\n", prefile); 02313 res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes); 02314 } 02315 if (res < 0) { 02316 ast_debug(2, "Hang up during prefile playback\n"); 02317 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02318 if(ast_test_flag(vmu, MVM_ALLOCED)) 02319 free_user(vmu); 02320 return -1; 02321 } 02322 if (res == '#') { 02323 /* On a '#' we skip the instructions */ 02324 ast_set_flag(&leave_options, OPT_SILENT); 02325 res = 0; 02326 } 02327 if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) { 02328 res = ast_streamfile(chan, SOUND_INTRO, chan->language); 02329 if (!res) 02330 res = ast_waitstream(chan, ecodes); 02331 if (res == '#') { 02332 ast_set_flag(&leave_options, OPT_SILENT); 02333 res = 0; 02334 } 02335 } 02336 if (res > 0) 02337 ast_stopstream(chan); 02338 /* Check for a '*' here in case the caller wants to escape from voicemail to something 02339 other than the operator -- an automated attendant or mailbox login for example */ 02340 if (res == '*') { 02341 chan->exten[0] = 'a'; 02342 chan->exten[1] = '\0'; 02343 if (!ast_strlen_zero(vmu->exit)) { 02344 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02345 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 02346 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02347 } 02348 chan->priority = 0; 02349 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02350 res = 0; 02351 } else if (res == '0') { /* Check for a '0' here */ 02352 if(ouseexten || ousemacro) { 02353 chan->exten[0] = 'o'; 02354 chan->exten[1] = '\0'; 02355 if (!ast_strlen_zero(vmu->exit)) { 02356 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02357 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 02358 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02359 } 02360 ast_play_and_wait(chan, "transfer"); 02361 chan->priority = 0; 02362 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02363 } 02364 res = 0; 02365 } else if (res < 0) { 02366 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02367 res = -1; 02368 } else 02369 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS"); 02370 02371 if(ast_test_flag(vmu, MVM_ALLOCED)) 02372 free_user(vmu); 02373 02374 02375 /* Ok, we're ready to rock and roll. Return to dialplan */ 02376 return res; 02377 02378 }
| static int minivm_mwi_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 2016 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), LOG_ERROR, mailbox, and queue_mwi_event().
Referenced by load_module().
02017 { 02018 int argc; 02019 char *argv[4]; 02020 int res = 0; 02021 char *tmpptr; 02022 char tmp[PATH_MAX]; 02023 char *mailbox; 02024 char *domain; 02025 if (ast_strlen_zero(data)) { 02026 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02027 return -1; 02028 } 02029 tmpptr = ast_strdupa((char *)data); 02030 if (!tmpptr) { 02031 ast_log(LOG_ERROR, "Out of memory\n"); 02032 return -1; 02033 } 02034 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02035 if (argc < 4) { 02036 ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc); 02037 return -1; 02038 } 02039 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02040 mailbox = tmp; 02041 domain = strchr(tmp, '@'); 02042 if (domain) { 02043 *domain = '\0'; 02044 domain++; 02045 } 02046 if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) { 02047 ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]); 02048 return -1; 02049 } 02050 queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); 02051 02052 return res; 02053 }
| static int minivm_notify_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 2058 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, find_account(), format, free_user(), LOG_ERROR, LOG_WARNING, MVM_ALLOCED, notify_new_message(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), TRUE, and minivm_account::username.
Referenced by load_module().
02059 { 02060 int argc; 02061 char *argv[2]; 02062 int res = 0; 02063 char tmp[PATH_MAX]; 02064 char *domain; 02065 char *tmpptr; 02066 struct minivm_account *vmu; 02067 char *username = argv[0]; 02068 const char *template = ""; 02069 const char *filename; 02070 const char *format; 02071 const char *duration_string; 02072 02073 if (ast_strlen_zero(data)) { 02074 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02075 return -1; 02076 } 02077 tmpptr = ast_strdupa((char *)data); 02078 if (!tmpptr) { 02079 ast_log(LOG_ERROR, "Out of memory\n"); 02080 return -1; 02081 } 02082 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02083 02084 if (argc == 2 && !ast_strlen_zero(argv[1])) 02085 template = argv[1]; 02086 02087 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02088 username = tmp; 02089 domain = strchr(tmp, '@'); 02090 if (domain) { 02091 *domain = '\0'; 02092 domain++; 02093 } 02094 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02095 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02096 return -1; 02097 } 02098 02099 if(!(vmu = find_account(domain, username, TRUE))) { 02100 /* We could not find user, let's exit */ 02101 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02102 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED"); 02103 return -1; 02104 } 02105 02106 ast_channel_lock(chan); 02107 if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) { 02108 filename = ast_strdupa(filename); 02109 } 02110 ast_channel_unlock(chan); 02111 /* Notify of new message to e-mail and pager */ 02112 if (!ast_strlen_zero(filename)) { 02113 ast_channel_lock(chan); 02114 if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) { 02115 format = ast_strdupa(format); 02116 } 02117 if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) { 02118 duration_string = ast_strdupa(duration_string); 02119 } 02120 ast_channel_unlock(chan); 02121 res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name); 02122 } 02123 02124 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED"); 02125 02126 02127 if(ast_test_flag(vmu, MVM_ALLOCED)) 02128 free_user(vmu); 02129 02130 /* Ok, we're ready to rock and roll. Return to dialplan */ 02131 02132 return res; 02133 02134 }
| static int minivm_record_exec | ( | struct ast_channel * | chan, | |
| const char * | data | |||
| ) | [static] |
Definition at line 2138 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_copy_flags, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, minivm_account::flags, leave_voicemail(), LOG_ERROR, LOG_WARNING, minivm_app_options, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and leave_vm_options::record_gain.
Referenced by load_module().
02139 { 02140 int res = 0; 02141 char *tmp; 02142 struct leave_vm_options leave_options; 02143 int argc; 02144 char *argv[2]; 02145 struct ast_flags flags = { 0 }; 02146 char *opts[OPT_ARG_ARRAY_SIZE]; 02147 02148 memset(&leave_options, 0, sizeof(leave_options)); 02149 02150 /* Answer channel if it's not already answered */ 02151 if (chan->_state != AST_STATE_UP) 02152 ast_answer(chan); 02153 02154 if (ast_strlen_zero(data)) { 02155 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02156 return -1; 02157 } 02158 tmp = ast_strdupa((char *)data); 02159 if (!tmp) { 02160 ast_log(LOG_ERROR, "Out of memory\n"); 02161 return -1; 02162 } 02163 argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv)); 02164 if (argc == 2) { 02165 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) { 02166 return -1; 02167 } 02168 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02169 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 02170 int gain; 02171 02172 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 02173 ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 02174 return -1; 02175 } else 02176 leave_options.record_gain = (signed char) gain; 02177 } 02178 } 02179 02180 /* Now run the appliation and good luck to you! */ 02181 res = leave_voicemail(chan, argv[0], &leave_options); 02182 02183 if (res == ERROR_LOCK_PATH) { 02184 ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 02185 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 02186 res = 0; 02187 } 02188 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 02189 02190 return res; 02191 }
| static struct minivm_account* mvm_user_alloc | ( | void | ) | [static, read] |
Definition at line 1021 of file app_minivm.c.
References ast_calloc, and populate_defaults().
Referenced by find_account(), and find_user_realtime().
01022 { 01023 struct minivm_account *new; 01024 01025 new = ast_calloc(1, sizeof(*new)); 01026 if (!new) 01027 return NULL; 01028 populate_defaults(new); 01029 01030 return new; 01031 }
| static int notify_new_message | ( | struct ast_channel * | chan, | |
| const char * | templatename, | |||
| struct minivm_account * | vmu, | |||
| const char * | filename, | |||
| long | duration, | |||
| const char * | format, | |||
| char * | cidnum, | |||
| char * | cidname | |||
| ) | [static] |
Definition at line 1742 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), minivm_account::attachfmt, minivm_template::attachment, minivm_account::domain, minivm_account::etemplate, EVENT_FLAG_CALL, minivm_template::locale, LOG_WARNING, manager_event, message_template_find(), MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_account::pager, pbx_builtin_getvar_helper(), minivm_account::ptemplate, run_externnotify(), sendmail(), strsep(), and minivm_account::username.
Referenced by copy_message(), leave_voicemail(), and minivm_notify_exec().
01743 { 01744 char *stringp; 01745 struct minivm_template *etemplate; 01746 char *messageformat; 01747 int res = 0; 01748 char oldlocale[100]; 01749 const char *counter; 01750 01751 if (!ast_strlen_zero(vmu->attachfmt)) { 01752 if (strstr(format, vmu->attachfmt)) { 01753 format = vmu->attachfmt; 01754 } else { 01755 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, format, vmu->username, vmu->domain); 01756 } 01757 } 01758 01759 etemplate = message_template_find(vmu->etemplate); 01760 if (!etemplate) 01761 etemplate = message_template_find(templatename); 01762 if (!etemplate) 01763 etemplate = message_template_find("email-default"); 01764 01765 /* Attach only the first format */ 01766 stringp = messageformat = ast_strdupa(format); 01767 strsep(&stringp, "|"); 01768 01769 if (!ast_strlen_zero(etemplate->locale)) { 01770 char *new_locale; 01771 ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale)); 01772 ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale); 01773 new_locale = setlocale(LC_TIME, etemplate->locale); 01774 if (new_locale == NULL) { 01775 ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale); 01776 } 01777 } 01778 01779 01780 01781 /* Read counter if available */ 01782 ast_channel_lock(chan); 01783 if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) { 01784 counter = ast_strdupa(counter); 01785 } 01786 ast_channel_unlock(chan); 01787 01788 if (ast_strlen_zero(counter)) { 01789 ast_debug(2, "MVM_COUNTER not found\n"); 01790 } else { 01791 ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter); 01792 } 01793 01794 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter); 01795 01796 if (res == 0 && !ast_strlen_zero(vmu->pager)) { 01797 /* Find template for paging */ 01798 etemplate = message_template_find(vmu->ptemplate); 01799 if (!etemplate) 01800 etemplate = message_template_find("pager-default"); 01801 if (etemplate->locale) { 01802 ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale)); 01803 setlocale(LC_TIME, etemplate->locale); 01804 } 01805 01806 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter); 01807 } 01808 01809 manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter); 01810 01811 run_externnotify(chan, vmu); /* Run external notification */ 01812 01813 if (etemplate->locale) { 01814 setlocale(LC_TIME, oldlocale); /* Rest to old locale */ 01815 } 01816 return res; 01817 }
| static int play_record_review | ( | struct ast_channel * | chan, | |
| char * | playfile, | |||
| char * | recordfile, | |||
| int | maxtime, | |||
| char * | fmt, | |||
| int | outsidecaller, | |||
| struct minivm_account * | vmu, | |||
| int * | duration, | |||
| const char * | unlockdir, | |||
| signed char | record_gain | |||
| ) | [static] |
Definition at line 1592 of file app_minivm.c.
References acceptdtmf, ast_channel_setoption(), AST_DIGIT_ANY, ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_streamfile(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_waitstream(), global_maxsilence, global_silencethreshold, ast_channel::language, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and vm_delete().
Referenced by leave_voicemail(), minivm_accmess_exec(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
01595 { 01596 int cmd = 0; 01597 int max_attempts = 3; 01598 int attempts = 0; 01599 int recorded = 0; 01600 int message_exists = 0; 01601 signed char zero_gain = 0; 01602 char *acceptdtmf = "#"; 01603 char *canceldtmf = ""; 01604 01605 /* Note that urgent and private are for flagging messages as such in the future */ 01606 01607 /* barf if no pointer passed to store duration in */ 01608 if (duration == NULL) { 01609 ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n"); 01610 return -1; 01611 } 01612 01613 cmd = '3'; /* Want to start by recording */ 01614 01615 while ((cmd >= 0) && (cmd != 't')) { 01616 switch (cmd) { 01617 case '1': 01618 ast_verb(3, "Saving message as is\n"); 01619 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01620 cmd = 't'; 01621 break; 01622 case '2': 01623 /* Review */ 01624 ast_verb(3, "Reviewing the message\n"); 01625 ast_streamfile(chan, recordfile, chan->language); 01626 cmd = ast_waitstream(chan, AST_DIGIT_ANY); 01627 break; 01628 case '3': 01629 message_exists = 0; 01630 /* Record */ 01631 if (recorded == 1) 01632 ast_verb(3, "Re-recording the message\n"); 01633 else 01634 ast_verb(3, "Recording the message\n"); 01635 if (recorded && outsidecaller) 01636 cmd = ast_play_and_wait(chan, "beep"); 01637 recorded = 1; 01638 /* 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 */ 01639 if (record_gain) 01640 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 01641 if (ast_test_flag(vmu, MVM_OPERATOR)) 01642 canceldtmf = "0"; 01643 cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf); 01644 if (record_gain) 01645 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 01646 if (cmd == -1) /* User has hung up, no options to give */ 01647 return cmd; 01648 if (cmd == '0') 01649 break; 01650 else if (cmd == '*') 01651 break; 01652 else { 01653 /* If all is well, a message exists */ 01654 message_exists = 1; 01655 cmd = 0; 01656 } 01657 break; 01658 case '4': 01659 case '5': 01660 case '6': 01661 case '7': 01662 case '8': 01663 case '9': 01664 case '*': 01665 case '#': 01666 cmd = ast_play_and_wait(chan, "vm-sorry"); 01667 break; 01668 case '0': 01669 if(!ast_test_flag(vmu, MVM_OPERATOR)) { 01670 cmd = ast_play_and_wait(chan, "vm-sorry"); 01671 break; 01672 } 01673 if (message_exists || recorded) { 01674 cmd = ast_play_and_wait(chan, "vm-saveoper"); 01675 if (!cmd) 01676 cmd = ast_waitfordigit(chan, 3000); 01677 if (cmd == '1') { 01678 ast_play_and_wait(chan, "vm-msgsaved"); 01679 cmd = '0'; 01680 } else { 01681 ast_play_and_wait(chan, "vm-deleted"); 01682 vm_delete(recordfile); 01683 cmd = '0'; 01684 } 01685 } 01686 return cmd; 01687 default: 01688 /* If the caller is an ouside caller, and the review option is enabled, 01689 allow them to review the message, but let the owner of the box review 01690 their OGM's */ 01691 if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW)) 01692 return cmd; 01693 if (message_exists) { 01694 cmd = ast_play_and_wait(chan, "vm-review"); 01695 } else { 01696 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01697 if (!cmd) 01698 cmd = ast_waitfordigit(chan, 600); 01699 } 01700 01701 if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) { 01702 cmd = ast_play_and_wait(chan, "vm-reachoper"); 01703 if (!cmd) 01704 cmd = ast_waitfordigit(chan, 600); 01705 } 01706 if (!cmd) 01707 cmd = ast_waitfordigit(chan, 6000); 01708 if (!cmd) { 01709 attempts++; 01710 } 01711 if (attempts > max_attempts) { 01712 cmd = 't'; 01713 } 01714 } 01715 } 01716 if (outsidecaller) 01717 ast_play_and_wait(chan, "vm-goodbye"); 01718 if (cmd == 't') 01719 cmd = 0; 01720 return cmd; 01721 }
| static void populate_defaults | ( | struct minivm_account * | vmu | ) | [static] |
Definition at line 1012 of file app_minivm.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, minivm_account::attachfmt, default_vmformat, global_volgain, globalflags, and minivm_account::volgain.
Referenced by append_mailbox(), create_vmaccount(), find_user_realtime(), load_config(), and mvm_user_alloc().
01013 { 01014 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01015 ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt)); 01016 vmu->volgain = global_volgain; 01017 }
| static void prep_email_sub_vars | ( | struct ast_channel * | channel, | |
| const struct minivm_account * | vmu, | |||
| const char * | cidnum, | |||
| const char * | cidname, | |||
| const char * | dur, | |||
| const char * | date, | |||
| const char * | counter | |||
| ) | [static] |
Definition at line 983 of file app_minivm.c.
References ast_callerid_merge(), ast_log(), ast_strlen_zero(), minivm_account::chanvars, minivm_account::domain, minivm_account::fullname, LOG_ERROR, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), minivm_account::username, ast_variable::value, and var.
Referenced by make_email_file(), sendmail(), and sendpage().
00984 { 00985 char callerid[256]; 00986 struct ast_variable *var; 00987 00988 if (!channel) { 00989 ast_log(LOG_ERROR, "No allocated channel, giving up...\n"); 00990 return; 00991 } 00992 00993 for (var = vmu->chanvars ; var ; var = var->next) { 00994 pbx_builtin_setvar_helper(channel, var->name, var->value); 00995 } 00996 00997 /* Prepare variables for substition in email body and subject */ 00998 pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname); 00999 pbx_builtin_setvar_helper(channel, "MVM_DUR", dur); 01000 pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain); 01001 pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username); 01002 pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller")); 01003 pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller")); 01004 pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller")); 01005 pbx_builtin_setvar_helper(channel, "MVM_DATE", date); 01006 if (!ast_strlen_zero(counter)) 01007 pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter); 01008 }
| static void queue_mwi_event | ( | const char * | mbx, | |
| const char * | ctx, | |||
| int | urgent, | |||
| int | new, | |||
| int | old | |||
| ) | [static] |
Definition at line 1991 of file app_minivm.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, ast_strlen_zero(), context, and mailbox.
Referenced by append_mailbox(), minivm_mwi_exec(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
01992 { 01993 struct ast_event *event; 01994 char *mailbox, *context; 01995 01996 mailbox = ast_strdupa(mbx); 01997 context = ast_strdupa(ctx); 01998 if (ast_strlen_zero(context)) { 01999 context = "default"; 02000 } 02001 02002 if (!(event = ast_event_new(AST_EVENT_MWI, 02003 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 02004 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 02005 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 02006 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 02007 AST_EVENT_IE_END))) { 02008 return; 02009 } 02010 02011 ast_event_queue_and_cache(event); 02012 }
| static int reload | ( | void | ) | [static] |
Reload mini voicemail module.
Definition at line 3493 of file app_minivm.c.
References load_config().
03494 { 03495 return(load_config(1)); 03496 }
| static void run_externnotify | ( | struct ast_channel * | chan, | |
| struct minivm_account * | vmu | |||
| ) | [static] |
Run external notification for voicemail message.
Definition at line 1724 of file app_minivm.c.
References ast_debug, ast_safe_system(), ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, minivm_account::domain, minivm_account::externnotify, global_externnotify, and minivm_account::username.
Referenced by forward_message(), notify_new_message(), and vm_execmain().
01725 { 01726 char arguments[BUFSIZ]; 01727 01728 if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify)) 01729 return; 01730 01731 snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&", 01732 ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify, 01733 vmu->username, vmu->domain, 01734 chan->cid.cid_name, chan->cid.cid_num); 01735 01736 ast_debug(1, "Executing: %s\n", arguments); 01737 ast_safe_system(arguments); 01738 }
| static int sendmail | ( | struct minivm_template * | template, | |
| struct minivm_account * | vmu, | |||
| char * | cidnum, | |||
| char * | cidname, | |||
| const char * | filename, | |||
| char * | format, | |||
| int | duration, | |||
| int | attach_user_voicemail, | |||
| enum mvm_messagetype | type, | |||
| const char * | counter | |||
| ) | [static] |
Definition at line 1216 of file app_minivm.c.
References ast_channel_release(), ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_tvnow(), base_encode(), check_mime(), minivm_account::domain, minivm_account::email, minivm_account::fullname, global_mailcmd, LOG_WARNING, MAXHOSTNAMELEN, MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_zone::name, option_debug, minivm_account::pager, prep_email_sub_vars(), minivm_account::serveremail, minivm_zone::timezone, minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.
Referenced by forward_message(), and notify_new_message().
01217 { 01218 FILE *p = NULL; 01219 int pfd; 01220 char email[256] = ""; 01221 char who[256] = ""; 01222 char date[256]; 01223 char bound[256]; 01224 char fname[PATH_MAX]; 01225 char dur[PATH_MAX]; 01226 char tmp[80] = "/tmp/astmail-XXXXXX"; 01227 char tmp2[PATH_MAX]; 01228 struct timeval now; 01229 struct ast_tm tm; 01230 struct minivm_zone *the_zone = NULL; 01231 struct ast_channel *ast; 01232 char *finalfilename; 01233 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 01234 char *fromaddress; 01235 char *fromemail; 01236 01237 if (!str1 || !str2) { 01238 ast_free(str1); 01239 ast_free(str2); 01240 return -1; 01241 } 01242 01243 if (type == MVM_MESSAGE_EMAIL) { 01244 if (vmu && !ast_strlen_zero(vmu->email)) { 01245 ast_copy_string(email, vmu->email, sizeof(email)); 01246 } else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain)) 01247 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 01248 } else if (type == MVM_MESSAGE_PAGE) { 01249 ast_copy_string(email, vmu->pager, sizeof(email)); 01250 } 01251 01252 if (ast_strlen_zero(email)) { 01253 ast_log(LOG_WARNING, "No address to send message to.\n"); 01254 return -1; 01255 } 01256 01257 ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name); 01258 01259 if (!strcmp(format, "wav49")) 01260 format = "WAV"; 01261 01262 01263 /* If we have a gain option, process it now with sox */ 01264 if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) { 01265 char newtmp[PATH_MAX]; 01266 char tmpcmd[PATH_MAX]; 01267 int tmpfd; 01268 01269 ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp)); 01270 ast_debug(3, "newtmp: %s\n", newtmp); 01271 tmpfd = mkstemp(newtmp); 01272 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format); 01273 ast_safe_system(tmpcmd); 01274 finalfilename = newtmp; 01275 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username); 01276 } else { 01277 finalfilename = ast_strdupa(filename); 01278 } 01279 01280 /* Create file name */ 01281 snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format); 01282 01283 if (template->attachment) 01284 ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail); 01285 01286 /* Make a temporary file instead of piping directly to sendmail, in case the mail 01287 command hangs */ 01288 pfd = mkstemp(tmp); 01289 if (pfd > -1) { 01290 p = fdopen(pfd, "w"); 01291 if (!p) { 01292 close(pfd); 01293 pfd = -1; 01294 } 01295 ast_debug(1, "Opening temp file for e-mail: %s\n", tmp); 01296 } 01297 if (!p) { 01298 ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp); 01299 return -1; 01300 } 01301 /* Allocate channel used for chanvar substitution */ 01302 ast = ast_dummy_channel_alloc(); 01303 01304 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 01305 01306 /* Does this user have a timezone specified? */ 01307 if (!ast_strlen_zero(vmu->zonetag)) { 01308 /* Find the zone in the list */ 01309 struct minivm_zone *z; 01310 AST_LIST_LOCK(&minivm_zones); 01311 AST_LIST_TRAVERSE(&minivm_zones, z, list) { 01312 if (strcmp(z->name, vmu->zonetag)) 01313 continue; 01314 the_zone = z; 01315 } 01316 AST_LIST_UNLOCK(&minivm_zones); 01317 } 01318 01319 now = ast_tvnow(); 01320 ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL); 01321 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm); 01322 01323 /* Start printing the email to the temporary file */ 01324 fprintf(p, "Date: %s\n", date); 01325 01326 /* Set date format for voicemail mail */ 01327 ast_strftime(date, sizeof(date), template->dateformat, &tm); 01328 01329 01330 /* Populate channel with channel variables for substitution */ 01331 prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter); 01332 01333 /* Find email address to use */ 01334 /* If there's a server e-mail adress in the account, user that, othterwise template */ 01335 fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail; 01336 01337 /* Find name to user for server e-mail */ 01338 fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress; 01339 01340 /* If needed, add hostname as domain */ 01341 if (ast_strlen_zero(fromemail)) 01342 fromemail = "asterisk"; 01343 01344 if (strchr(fromemail, '@')) 01345 ast_copy_string(who, fromemail, sizeof(who)); 01346 else { 01347 char host[MAXHOSTNAMELEN]; 01348 gethostname(host, sizeof(host)-1); 01349 snprintf(who, sizeof(who), "%s@%s", fromemail, host); 01350 } 01351 01352 if (ast_strlen_zero(fromaddress)) { 01353 fprintf(p, "From: Asterisk PBX <%s>\n", who); 01354 } else { 01355 ast_debug(4, "Fromaddress template: %s\n", fromaddress); 01356 ast_str_substitute_variables(&str1, 0, ast, fromaddress); 01357 if (check_mime(ast_str_buffer(str1))) { 01358 int first_line = 1; 01359 char *ptr; 01360 ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 01361 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01362 *ptr = '\0'; 01363 fprintf(p, "%s %s\n", first_line ? "From:" : "", ast_str_buffer(str2)); 01364 first_line = 0; 01365 /* Substring is smaller, so this will never grow */ 01366 ast_str_set(&str2, 0, "%s", ptr + 1); 01367 } 01368 fprintf(p, "%s %s <%s>\n", first_line ? "From:" : "", ast_str_buffer(str2), who); 01369 } else { 01370 fprintf(p, "From: %s <%s>\n", ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 01371 } 01372 } 01373 01374 fprintf(p, "Message-ID: <Asterisk-%d-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who); 01375 01376 if (ast_strlen_zero(vmu->email)) { 01377 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 01378 } else { 01379 ast_copy_string(email, vmu->email, sizeof(email)); 01380 } 01381 01382 if (check_mime(vmu->fullname)) { 01383 int first_line = 1; 01384 char *ptr; 01385 ast_str_encode_mime(&str2, 0, template->charset, vmu->fullname, strlen("To: "), strlen(email) + 3); 01386 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01387 *ptr = '\0'; 01388 fprintf(p, "%s %s\n", first_line ? "To:" : "", ast_str_buffer(str2)); 01389 first_line = 0; 01390 /* Substring is smaller, so this will never grow */ 01391 ast_str_set(&str2, 0, "%s", ptr + 1); 01392 } 01393 fprintf(p, "%s %s <%s>\n", first_line ? "To:" : "", ast_str_buffer(str2), email); 01394 } else { 01395 fprintf(p, "To: %s <%s>\n", ast_str_quote(&str2, 0, vmu->fullname), email); 01396 } 01397 01398 if (!ast_strlen_zero(template->subject)) { 01399 ast_str_substitute_variables(&str1, 0, ast, template->subject); 01400 if (check_mime(ast_str_buffer(str1))) { 01401 int first_line = 1; 01402 char *ptr; 01403 ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("Subject: "), 0); 01404 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01405 *ptr = '\0'; 01406 fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2)); 01407 first_line = 0; 01408 /* Substring is smaller, so this will never grow */ 01409 ast_str_set(&str2, 0, "%s", ptr + 1); 01410 } 01411 fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2)); 01412 } else { 01413 fprintf(p, "Subject: %s\n", ast_str_buffer(str1)); 01414 } 01415 } else { 01416 fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain); 01417 ast_debug(1, "Using default subject for this email \n"); 01418 } 01419 01420 if (option_debug > 2) 01421 fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain); 01422 fprintf(p, "MIME-Version: 1.0\n"); 01423 01424 /* Something unique. */ 01425 snprintf(bound, sizeof(bound), "voicemail_%s%d%d", vmu->username, (int)getpid(), (unsigned int)ast_random()); 01426 01427 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound); 01428 01429 fprintf(p, "--%s\n", bound); 01430 fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", template->charset); 01431 if (!ast_strlen_zero(template->body)) { 01432 ast_str_substitute_variables(&str1, 0, ast, template->body); 01433 ast_debug(3, "Message now: %s\n-----\n", ast_str_buffer(str1)); 01434 fprintf(p, "%s\n", ast_str_buffer(str1)); 01435 } else { 01436 fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n" 01437 "in mailbox %s from %s, on %s so you might\n" 01438 "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, 01439 dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 01440 ast_debug(3, "Using default message body (no template)\n-----\n"); 01441 } 01442 /* Eww. We want formats to tell us their own MIME type */ 01443 if (template->attachment) { 01444 char *ctype = "audio/x-"; 01445 ast_debug(3, "Attaching file to message: %s\n", fname); 01446 if (!strcasecmp(format, "ogg")) 01447 ctype = "application/"; 01448 01449 fprintf(p, "--%s\n", bound); 01450 fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format); 01451 fprintf(p, "Content-Transfer-Encoding: base64\n"); 01452 fprintf(p, "Content-Description: Voicemail sound attachment.\n"); 01453 fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format); 01454 01455 base_encode(fname, p); 01456 fprintf(p, "\n\n--%s--\n.\n", bound); 01457 } 01458 fclose(p); 01459 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp); 01460 ast_safe_system(tmp2); 01461 ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : ""); 01462 ast_debug(3, "Actual command used: %s\n", tmp2); 01463 if (ast) 01464 ast = ast_channel_release(ast); 01465 ast_free(str1); 01466 ast_free(str2); 01467 return 0; 01468 }
| static int timezone_add | ( | const char * | zonename, | |
| const char * | config | |||
| ) | [static] |
Add time zone to memory list.
Definition at line 2636 of file app_minivm.c.
References ast_calloc, ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, global_stats, LOG_WARNING, minivm_zone::msg_format, minivm_zone::name, strsep(), minivm_zone::timezone, and minivm_stats::timezones.
Referenced by load_config().
02637 { 02638 struct minivm_zone *newzone; 02639 char *msg_format, *timezone_str; 02640 02641 newzone = ast_calloc(1, sizeof(*newzone)); 02642 if (newzone == NULL) 02643 return 0; 02644 02645 msg_format = ast_strdupa(config); 02646 if (msg_format == NULL) { 02647 ast_log(LOG_WARNING, "Out of memory.\n"); 02648 ast_free(newzone); 02649 return 0; 02650 } 02651 02652 timezone_str = strsep(&msg_format, "|"); 02653 if (!msg_format) { 02654 ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename); 02655 ast_free(newzone); 02656 return 0; 02657 } 02658 02659 ast_copy_string(newzone->name, zonename, sizeof(newzone->name)); 02660 ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone)); 02661 ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format)); 02662 02663 AST_LIST_LOCK(&minivm_zones); 02664 AST_LIST_INSERT_TAIL(&minivm_zones, newzone, list); 02665 AST_LIST_UNLOCK(&minivm_zones); 02666 02667 global_stats.timezones++; 02668 02669 return 0; 02670 }
| static void timezone_destroy_list | ( | void | ) | [static] |
Clear list of timezones.
Definition at line 2624 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by load_config(), and unload_module().
02625 { 02626 struct minivm_zone *this; 02627 02628 AST_LIST_LOCK(&minivm_zones); 02629 while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list))) 02630 free_zone(this); 02631 02632 AST_LIST_UNLOCK(&minivm_zones); 02633 }
| static int unload_module | ( | void | ) | [static] |
Unload mini voicemail module.
Definition at line 3519 of file app_minivm.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_unregister_application(), cli_minivm, message_destroy_list(), minivm_account_function, minivm_counter_function, timezone_destroy_list(), and vmaccounts_destroy_list().
03520 { 03521 int res; 03522 03523 res = ast_unregister_application(app_minivm_record); 03524 res |= ast_unregister_application(app_minivm_greet); 03525 res |= ast_unregister_application(app_minivm_notify); 03526 res |= ast_unregister_application(app_minivm_delete); 03527 res |= ast_unregister_application(app_minivm_accmess); 03528 res |= ast_unregister_application(app_minivm_mwi); 03529 03530 ast_cli_unregister_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03531 ast_custom_function_unregister(&minivm_account_function); 03532 ast_custom_function_unregister(&minivm_counter_function); 03533 03534 message_destroy_list(); /* Destroy list of voicemail message templates */ 03535 timezone_destroy_list(); /* Destroy list of timezones */ 03536 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 03537 03538 return res; 03539 }
| static int vm_delete | ( | char * | file | ) | [static] |
Definition at line 1578 of file app_minivm.c.
References ast_debug, and ast_filedelete().
Referenced by copy_message(), minivm_delete_exec(), notify_new_message(), and play_record_review().
01579 { 01580 int res; 01581 01582 ast_debug(1, "Deleting voicemail file %s\n", file); 01583 01584 res = unlink(file); /* Remove the meta data file */ 01585 res |= ast_filedelete(file, NULL); /* remove the media file */ 01586 return res; 01587 }
| static int vm_lock_path | ( | const char * | path | ) | [static] |
lock directory
only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason
Definition at line 3243 of file app_minivm.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by access_counter_file(), close_mailbox(), copy_message(), count_messages(), leave_voicemail(), open_mailbox(), and save_to_folder().
03244 { 03245 switch (ast_lock_path(path)) { 03246 case AST_LOCK_TIMEOUT: 03247 return -1; 03248 default: 03249 return 0; 03250 } 03251 }
| static void vmaccounts_destroy_list | ( | void | ) | [static] |
Definition at line 1036 of file app_minivm.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by load_config(), and unload_module().
01037 { 01038 struct minivm_account *this; 01039 AST_LIST_LOCK(&minivm_accounts); 01040 while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list))) 01041 ast_free(this); 01042 AST_LIST_UNLOCK(&minivm_accounts); 01043 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail 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] |
Definition at line 3546 of file app_minivm.c.
char* app_minivm_accmess = "MinivmAccMess" [static] |
Definition at line 546 of file app_minivm.c.
char* app_minivm_delete = "MinivmDelete" [static] |
Definition at line 545 of file app_minivm.c.
char* app_minivm_greet = "MinivmGreet" [static] |
Definition at line 543 of file app_minivm.c.
char* app_minivm_mwi = "MinivmMWI" [static] |
Definition at line 547 of file app_minivm.c.
char* app_minivm_notify = "MinivmNotify" [static] |
Definition at line 544 of file app_minivm.c.
char* app_minivm_record = "MinivmRecord" [static] |
Definition at line 542 of file app_minivm.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 3546 of file app_minivm.c.
struct ast_cli_entry cli_minivm[] [static] |
CLI commands for Mini-voicemail.
Definition at line 3444 of file app_minivm.c.
Referenced by load_module(), and unload_module().
char default_vmformat[80] [static] |
Definition at line 683 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), load_config(), minivm_accmess_exec(), and populate_defaults().
char global_externnotify[160] [static] |
External notification application
Definition at line 681 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and run_externnotify().
char global_logfile[PATH_MAX] [static] |
Global log file for messages
Definition at line 682 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), and load_config().
char global_mailcmd[160] [static] |
Configurable mail cmd
Definition at line 680 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and sendmail().
int global_maxgreet [static] |
Maximum length of prompts
Definition at line 678 of file app_minivm.c.
Referenced by apply_general_options(), load_config(), and minivm_accmess_exec().
int global_maxsilence [static] |
Maximum silence during recording
Definition at line 677 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
int global_saydurationminfo [static] |
int global_silencethreshold = 128 [static] |
Definition at line 679 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
struct minivm_stats global_stats [static] |
Statistics for voicemail.
Definition at line 668 of file app_minivm.c.
Referenced by create_vmaccount(), handle_minivm_show_stats(), leave_voicemail(), load_config(), message_template_build(), and timezone_add().
int global_vmmaxmessage [static] |
Maximum duration of message
Definition at line 676 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), and load_config().
int global_vmminmessage [static] |
Minimum duration of messages
Definition at line 675 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), and load_config().
double global_volgain [static] |
Volume gain for voicmemail via e-mail
Definition at line 688 of file app_minivm.c.
Referenced by populate_defaults().
struct ast_flags globalflags = {0} [static] |
Global voicemail flags
Definition at line 685 of file app_minivm.c.
Referenced by apply_general_options(), find_or_create(), find_user(), find_user_realtime(), forward_message(), handle_minivm_show_settings(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), sendmail(), and vm_execmain().
struct ast_app_option minivm_accmess_options[128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING },} [static] |
struct ast_custom_function minivm_account_function [static] |
Initial value:
{
.name = "MINIVMACCOUNT",
.read = minivm_account_func_read,
}
Definition at line 3459 of file app_minivm.c.
Referenced by load_module(), and unload_module().
struct ast_app_option minivm_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 },} [static] |
Definition at line 570 of file app_minivm.c.
Referenced by minivm_greet_exec(), and minivm_record_exec().
struct ast_custom_function minivm_counter_function [static] |
Initial value:
{
.name = "MINIVMCOUNTER",
.read = minivm_counter_func_read,
.write = minivm_counter_func_write,
}
Definition at line 3453 of file app_minivm.c.
Referenced by load_module(), and unload_module().
ast_mutex_t minivmlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Lock to protect voicemail system
Definition at line 670 of file app_minivm.c.
Referenced by load_config().
FILE* minivmlogfile [static] |
The minivm log file
Definition at line 673 of file app_minivm.c.
Referenced by leave_voicemail(), and load_config().
ast_mutex_t minivmloglock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Lock to protect voicemail system log file
Definition at line 671 of file app_minivm.c.
Referenced by leave_voicemail().
char MVM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 539 of file app_minivm.c.
1.5.6