MiniVoiceMail - A Minimal Voicemail System for Asterisk. More...
#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 |
| Structure for linked list of Mini-Voicemail users: minivm_accounts. More... | |
| struct | minivm_accounts |
| The list of e-mail accounts. More... | |
| struct | minivm_stats |
| Structure for gathering statistics. More... | |
| struct | minivm_template |
| Linked list of e-mail templates in various languages These are used as templates for e-mails, pager messages and jabber messages message_templates. More... | |
| 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" |
| Default dateformat, can be overridden in configuration file. | |
| #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 | { 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 | { OPT_ARG_RECORDGAIN = 0, OPT_ARG_ARRAY_SIZE = 1 } |
| 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 int | b64_inbuf (struct b64_baseio *bio, FILE *fi) |
| read buffer from file (base64 conversion) | |
| static int | b64_inchar (struct b64_baseio *bio, FILE *fi) |
| read character from file to buffer (base64 conversion) | |
| static int | b64_ochar (struct b64_baseio *bio, int c, FILE *so) |
| write buffer to file (base64 conversion) | |
| static int | base_encode (char *filename, FILE *so) |
| Encode file to base64 encoding for email attachment (base64 conversion). | |
| static int | check_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
| Checks if directory exists. Does not create directory, but builds string in dest. | |
| 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) |
| basically mkdir -p $dest/$domain/$username/$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) |
| Find user from static memory object list. | |
| static struct minivm_account * | find_user_realtime (const char *domain, const char *username) |
| Find user in realtime storage Returns pointer to minivm_account structure. | |
| static void | free_user (struct minivm_account *vmu) |
| Free user structure - if it's allocated. | |
| 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) |
| Play intro message before recording voicemail. | |
| static int | leave_voicemail (struct ast_channel *chan, char *username, struct leave_vm_options *options) |
| Record voicemail message, store into file prepared for sending e-mail. | |
| static int | load_config (int reload) |
| Load minivoicemail configuration. | |
| static int | load_module (void) |
| Load mini voicemail module. | |
| static char * | mailheader_quote (const char *from, char *to, size_t len) |
| Fix quote of mail headers for non-ascii characters. | |
| static int | make_dir (char *dest, int len, const char *domain, const char *username, const char *folder) |
| Create directory based on components. | |
| static void | message_destroy_list (void) |
| Clear list of templates. | |
| static int | message_template_build (const char *name, struct ast_variable *var) |
| Build message template from configuration. | |
| static struct minivm_template * | message_template_create (const char *name) |
| Create message template. | |
| static struct minivm_template * | message_template_find (const char *name) |
| Find named template. | |
| static void | message_template_free (struct minivm_template *template) |
| Release memory allocated by message 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, void *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, void *data) |
| Dialplan application to delete voicemail. | |
| static int | minivm_greet_exec (struct ast_channel *chan, void *data) |
| Play voicemail prompts - either generic or user specific. | |
| static int | minivm_mwi_exec (struct ast_channel *chan, void *data) |
| Send MWI using interal Asterisk event subsystem. | |
| static int | minivm_notify_exec (struct ast_channel *chan, void *data) |
| Notify voicemail account owners - either generic template or user specific. | |
| static int | minivm_record_exec (struct ast_channel *chan, void *data) |
| Dialplan function to record voicemail. | |
| static struct minivm_account * | mvm_user_alloc (void) |
| Allocate new vm user and set default values. | |
| 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) |
| Send message to voicemail account owner. | |
| 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) |
| Record voicemail message & let caller review or re-record it, or set options if applicable. | |
| static void | populate_defaults (struct minivm_account *vmu) |
| Set default values for Mini-Voicemail users. | |
| 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) |
| Prepare for voicemail template by adding channel variables to the channel. | |
| static void | queue_mwi_event (const char *mbx, const char *ctx, int urgent, int new, int old) |
| Queue a message waiting event. | |
| 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) |
| Send voicemail with audio file as an attachment. | |
| 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) |
| Delete media files and attribute file. | |
| static int | vm_lock_path (const char *path) |
| lock directory | |
| static void | vmaccounts_destroy_list (void) |
| Clear list of users. | |
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 = "0901e4e500243c855563a2d78b0c03e4" , .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_charset [32] |
| 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 |
| enum { ... } | minivm_option_args |
| enum { ... } | minivm_option_flags |
| static ast_mutex_t | minivmlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| FILE * | minivmlogfile |
| static ast_mutex_t | minivmloglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| static char | MVM_SPOOL_DIR [PATH_MAX] |
MiniVoiceMail - A Minimal Voicemail System for Asterisk.
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 437 of file app_minivm.c.
Referenced by load_config().
| #define B64_BASELINELEN 72 |
Line length for Base 64 endoded messages
Definition at line 427 of file app_minivm.c.
Referenced by b64_ochar().
| #define B64_BASEMAXINLINE 256 |
Buffer size for Base 64 attachment encoding
Definition at line 426 of file app_minivm.c.
Referenced by b64_inbuf(), and base_encode().
| #define DEFAULT_CHARSET "ISO-8859-1" |
Definition at line 597 of file app_minivm.c.
Referenced by message_template_create().
| #define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
Default dateformat, can be overridden in configuration file.
Definition at line 596 of file app_minivm.c.
Referenced by message_template_create().
| #define EOL "\r\n" |
Definition at line 428 of file app_minivm.c.
Referenced by b64_ochar(), and base_encode().
| #define ERROR_LOCK_PATH -100 |
Definition at line 433 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 409 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(), build_rpid(), cb_extensionstate(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), create_addr(), dialog_needdestroy(), do_monitor(), expire_register(), find_call_cb(), 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(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), 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(), transmit_t38(), tzload(), tzparse(), and update_call_counter().
| #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 430 of file app_minivm.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 431 of file app_minivm.c.
Referenced by load_config(), and play_message_callerid().
| #define MVM_ALLOCED (1 << 13) |
Definition at line 419 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 417 of file app_minivm.c.
| #define MVM_OPERATOR (1 << 1) |
Operator exit during voicemail recording
Definition at line 414 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 418 of file app_minivm.c.
| #define MVM_REALTIME (1 << 2) |
This user is a realtime account
Definition at line 415 of file app_minivm.c.
| #define MVM_REVIEW (1 << 0) |
Review message
Definition at line 413 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 416 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 423 of file app_minivm.c.
Referenced by load_config().
| #define SOUND_INTRO "vm-intro" |
Definition at line 425 of file app_minivm.c.
Referenced by minivm_greet_exec().
| #define TRUE 1 |
Definition at line 406 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(), build_rpid(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), cli_activate(), create_addr(), dialog_needdestroy(), find_account(), 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_invite(), handle_response_peerpoke(), interpret_t38_parameters(), leave_voicemail(), load_config(), local_attended_transfer(), 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(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), 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_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_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(), and update_call_counter().
| #define VOICEMAIL_CONFIG "minivm.conf" |
Definition at line 436 of file app_minivm.c.
| #define VOICEMAIL_DIR_MODE 0700 |
Definition at line 434 of file app_minivm.c.
Referenced by create_dirpath().
| anonymous enum |
| OPT_SILENT | |
| OPT_BUSY_GREETING | |
| OPT_UNAVAIL_GREETING | |
| OPT_TEMP_GREETING | |
| OPT_NAME_GREETING | |
| OPT_RECORDGAIN |
Definition at line 458 of file app_minivm.c.
00458 { 00459 OPT_SILENT = (1 << 0), 00460 OPT_BUSY_GREETING = (1 << 1), 00461 OPT_UNAVAIL_GREETING = (1 << 2), 00462 OPT_TEMP_GREETING = (1 << 3), 00463 OPT_NAME_GREETING = (1 << 4), 00464 OPT_RECORDGAIN = (1 << 5), 00465 } minivm_option_flags;
| anonymous enum |
Definition at line 467 of file app_minivm.c.
00467 { 00468 OPT_ARG_RECORDGAIN = 0, 00469 OPT_ARG_ARRAY_SIZE = 1, 00470 } minivm_option_args;
| enum mvm_messagetype |
Message types for notification.
Definition at line 440 of file app_minivm.c.
00440 { 00441 MVM_MESSAGE_EMAIL, 00442 MVM_MESSAGE_PAGE 00443 /* For trunk: MVM_MESSAGE_JABBER, */ 00444 };
| static void __reg_module | ( | void | ) | [static] |
Definition at line 3350 of file app_minivm.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 3350 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 3036 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().
03037 { 03038 char filename[BUFSIZ]; 03039 char readbuf[BUFSIZ]; 03040 FILE *counterfile; 03041 int old = 0, counter = 0; 03042 03043 /* Lock directory */ 03044 if (vm_lock_path(directory)) { 03045 return -1; /* Could not lock directory */ 03046 } 03047 snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername); 03048 if (operand != 1) { 03049 counterfile = fopen(filename, "r"); 03050 if (counterfile) { 03051 if(fgets(readbuf, sizeof(readbuf), counterfile)) { 03052 ast_debug(3, "Read this string from counter file: %s\n", readbuf); 03053 old = counter = atoi(readbuf); 03054 } 03055 fclose(counterfile); 03056 } 03057 } 03058 switch (operand) { 03059 case 0: /* Read only */ 03060 ast_unlock_path(directory); 03061 ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter); 03062 return counter; 03063 break; 03064 case 1: /* Set new value */ 03065 counter = value; 03066 break; 03067 case 2: /* Change value */ 03068 counter += value; 03069 if (counter < 0) /* Don't allow counters to fall below zero */ 03070 counter = 0; 03071 break; 03072 } 03073 03074 /* Now, write the new value to the file */ 03075 counterfile = fopen(filename, "w"); 03076 if (!counterfile) { 03077 ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno)); 03078 ast_unlock_path(directory); 03079 return -1; /* Could not open file for writing */ 03080 } 03081 fprintf(counterfile, "%d\n\n", counter); 03082 fclose(counterfile); 03083 ast_unlock_path(directory); 03084 ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter); 03085 return counter; 03086 }
| static int apply_general_options | ( | struct ast_variable * | var | ) | [static] |
Apply general configuration options.
Definition at line 2515 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().
02516 { 02517 int error = 0; 02518 02519 while (var) { 02520 /* Mail command */ 02521 if (!strcmp(var->name, "mailcmd")) { 02522 ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */ 02523 } else if (!strcmp(var->name, "maxgreet")) { 02524 global_maxgreet = atoi(var->value); 02525 } else if (!strcmp(var->name, "maxsilence")) { 02526 global_maxsilence = atoi(var->value); 02527 if (global_maxsilence > 0) 02528 global_maxsilence *= 1000; 02529 } else if (!strcmp(var->name, "logfile")) { 02530 if (!ast_strlen_zero(var->value) ) { 02531 if(*(var->value) == '/') 02532 ast_copy_string(global_logfile, var->value, sizeof(global_logfile)); 02533 else 02534 snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value); 02535 } 02536 } else if (!strcmp(var->name, "externnotify")) { 02537 /* External voicemail notify application */ 02538 ast_copy_string(global_externnotify, var->value, sizeof(global_externnotify)); 02539 } else if (!strcmp(var->name, "silencetreshold")) { 02540 /* Silence treshold */ 02541 global_silencethreshold = atoi(var->value); 02542 } else if (!strcmp(var->name, "maxmessage")) { 02543 int x; 02544 if (sscanf(var->value, "%30d", &x) == 1) { 02545 global_vmmaxmessage = x; 02546 } else { 02547 error ++; 02548 ast_log(LOG_WARNING, "Invalid max message time length\n"); 02549 } 02550 } else if (!strcmp(var->name, "minmessage")) { 02551 int x; 02552 if (sscanf(var->value, "%30d", &x) == 1) { 02553 global_vmminmessage = x; 02554 if (global_maxsilence <= global_vmminmessage) 02555 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 02556 } else { 02557 error ++; 02558 ast_log(LOG_WARNING, "Invalid min message time length\n"); 02559 } 02560 } else if (!strcmp(var->name, "format")) { 02561 ast_copy_string(default_vmformat, var->value, sizeof(default_vmformat)); 02562 } else if (!strcmp(var->name, "review")) { 02563 ast_set2_flag((&globalflags), ast_true(var->value), MVM_REVIEW); 02564 } else if (!strcmp(var->name, "operator")) { 02565 ast_set2_flag((&globalflags), ast_true(var->value), MVM_OPERATOR); 02566 } 02567 var = var->next; 02568 } 02569 return error; 02570 }
| static int b64_inbuf | ( | struct b64_baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
read buffer from file (base64 conversion)
Definition at line 729 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().
00730 { 00731 int l; 00732 00733 if (bio->ateof) 00734 return 0; 00735 00736 if ((l = fread(bio->iobuf, 1, B64_BASEMAXINLINE,fi)) <= 0) { 00737 if (ferror(fi)) 00738 return -1; 00739 00740 bio->ateof = 1; 00741 return 0; 00742 } 00743 00744 bio->iolen= l; 00745 bio->iocp= 0; 00746 00747 return 1; 00748 }
| static int b64_inchar | ( | struct b64_baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
read character from file to buffer (base64 conversion)
Definition at line 751 of file app_minivm.c.
References b64_inbuf(), b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by base_encode().
| static int b64_ochar | ( | struct b64_baseio * | bio, | |
| int | c, | |||
| FILE * | so | |||
| ) | [static] |
write buffer to file (base64 conversion)
Definition at line 762 of file app_minivm.c.
References B64_BASELINELEN, EOL, and b64_baseio::linelength.
Referenced by base_encode().
00763 { 00764 if (bio->linelength >= B64_BASELINELEN) { 00765 if (fputs(EOL,so) == EOF) 00766 return -1; 00767 00768 bio->linelength= 0; 00769 } 00770 00771 if (putc(((unsigned char) c), so) == EOF) 00772 return -1; 00773 00774 bio->linelength++; 00775 00776 return 1; 00777 }
| static int base_encode | ( | char * | filename, | |
| FILE * | so | |||
| ) | [static] |
Encode file to base64 encoding for email attachment (base64 conversion).
Definition at line 780 of file app_minivm.c.
References ast_log(), B64_BASEMAXINLINE, b64_inchar(), b64_ochar(), EOL, errno, b64_baseio::iocp, and LOG_WARNING.
Referenced by sendmail().
00781 { 00782 unsigned char dtable[B64_BASEMAXINLINE]; 00783 int i,hiteof= 0; 00784 FILE *fi; 00785 struct b64_baseio bio; 00786 00787 memset(&bio, 0, sizeof(bio)); 00788 bio.iocp = B64_BASEMAXINLINE; 00789 00790 if (!(fi = fopen(filename, "rb"))) { 00791 ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 00792 return -1; 00793 } 00794 00795 for (i= 0; i<9; i++) { 00796 dtable[i]= 'A'+i; 00797 dtable[i+9]= 'J'+i; 00798 dtable[26+i]= 'a'+i; 00799 dtable[26+i+9]= 'j'+i; 00800 } 00801 for (i= 0; i < 8; i++) { 00802 dtable[i+18]= 'S'+i; 00803 dtable[26+i+18]= 's'+i; 00804 } 00805 for (i= 0; i < 10; i++) { 00806 dtable[52+i]= '0'+i; 00807 } 00808 dtable[62]= '+'; 00809 dtable[63]= '/'; 00810 00811 while (!hiteof){ 00812 unsigned char igroup[3], ogroup[4]; 00813 int c,n; 00814 00815 igroup[0]= igroup[1]= igroup[2]= 0; 00816 00817 for (n= 0; n < 3; n++) { 00818 if ((c = b64_inchar(&bio, fi)) == EOF) { 00819 hiteof= 1; 00820 break; 00821 } 00822 igroup[n]= (unsigned char)c; 00823 } 00824 00825 if (n> 0) { 00826 ogroup[0]= dtable[igroup[0]>>2]; 00827 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 00828 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 00829 ogroup[3]= dtable[igroup[2]&0x3F]; 00830 00831 if (n<3) { 00832 ogroup[3]= '='; 00833 00834 if (n<2) 00835 ogroup[2]= '='; 00836 } 00837 00838 for (i= 0;i<4;i++) 00839 b64_ochar(&bio, ogroup[i], so); 00840 } 00841 } 00842 00843 /* Put end of line - line feed */ 00844 if (fputs(EOL, so) == EOF) 00845 return 0; 00846 00847 fclose(fi); 00848 00849 return 1; 00850 }
| static int check_dirpath | ( | char * | dest, | |
| int | len, | |||
| char * | domain, | |||
| char * | username, | |||
| char * | folder | |||
| ) | [static] |
Checks if directory exists. Does not create directory, but builds string in dest.
| dest | String. base directory. | |
| len | Int. Length base directory string. | |
| domain | String. Ignored if is null or empty string. | |
| username | String. Ignored if is null or empty string. | |
| folder | String. Ignored if is null or empty string. |
Definition at line 1276 of file app_minivm.c.
References FALSE, make_dir(), and TRUE.
Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().
| static char* complete_minivm_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 2755 of file app_minivm.c.
References AST_LIST_TRAVERSE, ast_strdup, and minivm_account::domain.
Referenced by handle_minivm_show_users().
02756 { 02757 int which = 0; 02758 int wordlen; 02759 struct minivm_account *vmu; 02760 const char *domain = ""; 02761 02762 /* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */ 02763 if (pos > 4) 02764 return NULL; 02765 if (pos == 3) 02766 return (state == 0) ? ast_strdup("for") : NULL; 02767 wordlen = strlen(word); 02768 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 02769 if (!strncasecmp(word, vmu->domain, wordlen)) { 02770 if (domain && strcmp(domain, vmu->domain) && ++which > state) 02771 return ast_strdup(vmu->domain); 02772 /* ignore repeated domains ? */ 02773 domain = vmu->domain; 02774 } 02775 } 02776 return NULL; 02777 }
| static int create_dirpath | ( | char * | dest, | |
| int | len, | |||
| char * | domain, | |||
| char * | username, | |||
| char * | folder | |||
| ) | [static] |
basically mkdir -p $dest/$domain/$username/$folder
| dest | String. base directory. | |
| len | Length of directory string | |
| domain | String. Ignored if is null or empty string. | |
| folder | String. Ignored if is null or empty string. | |
| username | String. Ignored if is null or empty string. |
Definition at line 1294 of file app_minivm.c.
References ast_debug, ast_log(), ast_mkdir(), LOG_WARNING, and make_dir().
Referenced by leave_voicemail(), minivm_counter_func_read(), and minivm_counter_func_write().
01295 { 01296 int res; 01297 make_dir(dest, len, domain, username, folder); 01298 if ((res = ast_mkdir(dest, 0777))) { 01299 ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01300 return -1; 01301 } 01302 ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest); 01303 return 0; 01304 }
| 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 2299 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_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().
02300 { 02301 struct minivm_account *vmu; 02302 char *domain; 02303 char *username; 02304 char accbuf[BUFSIZ]; 02305 02306 ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name); 02307 02308 ast_copy_string(accbuf, name, sizeof(accbuf)); 02309 username = accbuf; 02310 domain = strchr(accbuf, '@'); 02311 if (domain) { 02312 *domain = '\0'; 02313 domain++; 02314 } 02315 if (ast_strlen_zero(domain)) { 02316 ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name); 02317 return 0; 02318 } 02319 02320 ast_debug(3, "Creating static account for user %s domain %s\n", username, domain); 02321 02322 /* Allocate user account */ 02323 vmu = ast_calloc(1, sizeof(*vmu)); 02324 if (!vmu) 02325 return 0; 02326 02327 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 02328 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 02329 02330 populate_defaults(vmu); 02331 02332 ast_debug(3, "...Configuring account %s\n", name); 02333 02334 while (var) { 02335 ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name); 02336 if (!strcasecmp(var->name, "serveremail")) { 02337 ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail)); 02338 } else if (!strcasecmp(var->name, "email")) { 02339 ast_copy_string(vmu->email, var->value, sizeof(vmu->email)); 02340 } else if (!strcasecmp(var->name, "accountcode")) { 02341 ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode)); 02342 } else if (!strcasecmp(var->name, "pincode")) { 02343 ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode)); 02344 } else if (!strcasecmp(var->name, "domain")) { 02345 ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain)); 02346 } else if (!strcasecmp(var->name, "language")) { 02347 ast_copy_string(vmu->language, var->value, sizeof(vmu->language)); 02348 } else if (!strcasecmp(var->name, "timezone")) { 02349 ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag)); 02350 } else if (!strcasecmp(var->name, "externnotify")) { 02351 ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify)); 02352 } else if (!strcasecmp(var->name, "etemplate")) { 02353 ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate)); 02354 } else if (!strcasecmp(var->name, "ptemplate")) { 02355 ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate)); 02356 } else if (!strcasecmp(var->name, "fullname")) { 02357 ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname)); 02358 } else if (!strcasecmp(var->name, "setvar")) { 02359 char *varval; 02360 char *varname = ast_strdupa(var->value); 02361 struct ast_variable *tmpvar; 02362 02363 if (varname && (varval = strchr(varname, '='))) { 02364 *varval = '\0'; 02365 varval++; 02366 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 02367 tmpvar->next = vmu->chanvars; 02368 vmu->chanvars = tmpvar; 02369 } 02370 } 02371 } else if (!strcasecmp(var->name, "pager")) { 02372 ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager)); 02373 } else if (!strcasecmp(var->name, "volgain")) { 02374 sscanf(var->value, "%30lf", &vmu->volgain); 02375 } else { 02376 ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name); 02377 } 02378 var = var->next; 02379 } 02380 ast_debug(3, "...Linking account %s\n", name); 02381 02382 AST_LIST_LOCK(&minivm_accounts); 02383 AST_LIST_INSERT_TAIL(&minivm_accounts, vmu, list); 02384 AST_LIST_UNLOCK(&minivm_accounts); 02385 02386 global_stats.voicemailaccounts++; 02387 02388 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)" : ""); 02389 return 0; 02390 }
| static struct minivm_account* find_account | ( | const char * | domain, | |
| const char * | username, | |||
| int | createtemp | |||
| ) | [static, read] |
Find user from static memory object list.
Definition at line 955 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().
00956 { 00957 struct minivm_account *vmu = NULL, *cur; 00958 00959 00960 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 00961 ast_log(LOG_NOTICE, "No username or domain? \n"); 00962 return NULL; 00963 } 00964 ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain); 00965 00966 AST_LIST_LOCK(&minivm_accounts); 00967 AST_LIST_TRAVERSE(&minivm_accounts, cur, list) { 00968 /* Is this the voicemail account we're looking for? */ 00969 if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username)) 00970 break; 00971 } 00972 AST_LIST_UNLOCK(&minivm_accounts); 00973 00974 if (cur) { 00975 ast_debug(3, "Found account for %s@%s\n", username, domain); 00976 vmu = cur; 00977 00978 } else 00979 vmu = find_user_realtime(domain, username); 00980 00981 if (createtemp && !vmu) { 00982 /* Create a temporary user, send e-mail and be gone */ 00983 vmu = mvm_user_alloc(); 00984 ast_set2_flag(vmu, TRUE, MVM_ALLOCED); 00985 if (vmu) { 00986 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 00987 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 00988 ast_debug(1, "Created temporary account\n"); 00989 } 00990 00991 } 00992 return vmu; 00993 }
| static struct minivm_account * find_user_realtime | ( | const char * | domain, | |
| const char * | username | |||
| ) | [static, read] |
Find user in realtime storage Returns pointer to minivm_account structure.
Definition at line 998 of file app_minivm.c.
References ast_copy_string(), ast_free, ast_load_realtime(), ast_variables_destroy(), create_vmaccount(), mvm_user_alloc(), populate_defaults(), SENTINEL, TRUE, minivm_account::username, and var.
Referenced by find_account().
00999 { 01000 struct ast_variable *var; 01001 struct minivm_account *retval; 01002 char name[MAXHOSTNAMELEN]; 01003 01004 retval = mvm_user_alloc(); 01005 if (!retval) 01006 return NULL; 01007 01008 if (username) 01009 ast_copy_string(retval->username, username, sizeof(retval->username)); 01010 01011 populate_defaults(retval); 01012 var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL); 01013 01014 if (!var) { 01015 ast_free(retval); 01016 return NULL; 01017 } 01018 01019 snprintf(name, sizeof(name), "%s@%s", username, domain); 01020 create_vmaccount(name, var, TRUE); 01021 01022 ast_variables_destroy(var); 01023 return retval; 01024 }
| static void free_user | ( | struct minivm_account * | vmu | ) | [static] |
Free user structure - if it's allocated.
Definition at line 863 of file app_minivm.c.
References ast_free, ast_variables_destroy(), and minivm_account::chanvars.
Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), and minivm_notify_exec().
00864 { 00865 if (vmu->chanvars) 00866 ast_variables_destroy(vmu->chanvars); 00867 ast_free(vmu); 00868 }
| static void free_zone | ( | struct minivm_zone * | z | ) | [static] |
Free Mini Voicemail timezone.
Definition at line 2393 of file app_minivm.c.
References ast_free.
Referenced by timezone_destroy_list().
02394 { 02395 ast_free(z); 02396 }
| static int get_date | ( | char * | s, | |
| int | len | |||
| ) | [static] |
Definition at line 852 of file app_minivm.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
00853 { 00854 struct ast_tm tm; 00855 struct timeval now = ast_tvnow(); 00856 00857 ast_localtime(&now, &tm, NULL); 00858 return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm); 00859 }
| 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 2714 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.
02715 { 02716 struct minivm_template *this; 02717 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" 02718 int count = 0; 02719 02720 switch (cmd) { 02721 case CLI_INIT: 02722 e->command = "minivm list templates"; 02723 e->usage = 02724 "Usage: minivm list templates\n" 02725 " Lists message templates for e-mail, paging and IM\n"; 02726 return NULL; 02727 case CLI_GENERATE: 02728 return NULL; 02729 } 02730 02731 if (a->argc > 3) 02732 return CLI_SHOWUSAGE; 02733 02734 AST_LIST_LOCK(&message_templates); 02735 if (AST_LIST_EMPTY(&message_templates)) { 02736 ast_cli(a->fd, "There are no message templates defined\n"); 02737 AST_LIST_UNLOCK(&message_templates); 02738 return CLI_FAILURE; 02739 } 02740 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject"); 02741 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------"); 02742 AST_LIST_TRAVERSE(&message_templates, this, list) { 02743 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name, 02744 this->charset ? this->charset : "-", 02745 this->locale ? this->locale : "-", 02746 this->attachment ? "Yes" : "No", 02747 this->subject ? this->subject : "-"); 02748 count++; 02749 } 02750 AST_LIST_UNLOCK(&message_templates); 02751 ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count); 02752 return CLI_SUCCESS; 02753 }
| static char * handle_minivm_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Reload cofiguration.
Definition at line 3303 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.
03304 { 03305 03306 switch (cmd) { 03307 case CLI_INIT: 03308 e->command = "minivm reload"; 03309 e->usage = 03310 "Usage: minivm reload\n" 03311 " Reload mini-voicemail configuration and reset statistics\n"; 03312 return NULL; 03313 case CLI_GENERATE: 03314 return NULL; 03315 } 03316 03317 reload(); 03318 ast_cli(a->fd, "\n-- Mini voicemail re-configured \n"); 03319 return CLI_SUCCESS; 03320 }
| 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 2865 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.
02866 { 02867 switch (cmd) { 02868 case CLI_INIT: 02869 e->command = "minivm show settings"; 02870 e->usage = 02871 "Usage: minivm show settings\n" 02872 " Display Mini-Voicemail general settings\n"; 02873 return NULL; 02874 case CLI_GENERATE: 02875 return NULL; 02876 } 02877 02878 ast_cli(a->fd, "* Mini-Voicemail general settings\n"); 02879 ast_cli(a->fd, " -------------------------------\n"); 02880 ast_cli(a->fd, "\n"); 02881 ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd); 02882 ast_cli(a->fd, " Max silence: %d\n", global_maxsilence); 02883 ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold); 02884 ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage); 02885 ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage); 02886 ast_cli(a->fd, " Default format: %s\n", default_vmformat); 02887 ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify); 02888 ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>"); 02889 ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No"); 02890 ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No"); 02891 02892 ast_cli(a->fd, "\n"); 02893 return CLI_SUCCESS; 02894 }
| static char* handle_minivm_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show stats.
Definition at line 2897 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.
02898 { 02899 struct ast_tm timebuf; 02900 char buf[BUFSIZ]; 02901 02902 switch (cmd) { 02903 02904 case CLI_INIT: 02905 e->command = "minivm show stats"; 02906 e->usage = 02907 "Usage: minivm show stats\n" 02908 " Display Mini-Voicemail counters\n"; 02909 return NULL; 02910 case CLI_GENERATE: 02911 return NULL; 02912 } 02913 02914 ast_cli(a->fd, "* Mini-Voicemail statistics\n"); 02915 ast_cli(a->fd, " -------------------------\n"); 02916 ast_cli(a->fd, "\n"); 02917 ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts); 02918 ast_cli(a->fd, " Templates: %5d\n", global_stats.templates); 02919 ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones); 02920 if (global_stats.receivedmessages == 0) { 02921 ast_cli(a->fd, " Received messages since last reset: <none>\n"); 02922 } else { 02923 ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages); 02924 ast_localtime(&global_stats.lastreceived, &timebuf, NULL); 02925 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 02926 ast_cli(a->fd, " Last received voicemail: %s\n", buf); 02927 } 02928 ast_localtime(&global_stats.reset, &timebuf, NULL); 02929 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 02930 ast_cli(a->fd, " Last reset: %s\n", buf); 02931 02932 ast_cli(a->fd, "\n"); 02933 return CLI_SUCCESS; 02934 }
| 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 2780 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.
02781 { 02782 struct minivm_account *vmu; 02783 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" 02784 int count = 0; 02785 02786 switch (cmd) { 02787 case CLI_INIT: 02788 e->command = "minivm list accounts"; 02789 e->usage = 02790 "Usage: minivm list accounts\n" 02791 " Lists all mailboxes currently set up\n"; 02792 return NULL; 02793 case CLI_GENERATE: 02794 return complete_minivm_show_users(a->line, a->word, a->pos, a->n); 02795 } 02796 02797 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 02798 return CLI_SHOWUSAGE; 02799 if ((a->argc == 5) && strcmp(a->argv[3],"for")) 02800 return CLI_SHOWUSAGE; 02801 02802 AST_LIST_LOCK(&minivm_accounts); 02803 if (AST_LIST_EMPTY(&minivm_accounts)) { 02804 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 02805 AST_LIST_UNLOCK(&minivm_accounts); 02806 return CLI_FAILURE; 02807 } 02808 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name"); 02809 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------"); 02810 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 02811 char tmp[256] = ""; 02812 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) { 02813 count++; 02814 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain); 02815 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-", 02816 vmu->ptemplate ? vmu->ptemplate : "-", 02817 vmu->zonetag ? vmu->zonetag : "-", 02818 vmu->attachfmt ? vmu->attachfmt : "-", 02819 vmu->fullname); 02820 } 02821 } 02822 AST_LIST_UNLOCK(&minivm_accounts); 02823 ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count); 02824 return CLI_SUCCESS; 02825 }
| 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 2828 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.
02829 { 02830 struct minivm_zone *zone; 02831 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 02832 char *res = CLI_SUCCESS; 02833 02834 switch (cmd) { 02835 case CLI_INIT: 02836 e->command = "minivm list zones"; 02837 e->usage = 02838 "Usage: minivm list zones\n" 02839 " Lists zone message formats\n"; 02840 return NULL; 02841 case CLI_GENERATE: 02842 return NULL; 02843 } 02844 02845 if (a->argc != e->args) 02846 return CLI_SHOWUSAGE; 02847 02848 AST_LIST_LOCK(&minivm_zones); 02849 if (!AST_LIST_EMPTY(&minivm_zones)) { 02850 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 02851 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------"); 02852 AST_LIST_TRAVERSE(&minivm_zones, zone, list) { 02853 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 02854 } 02855 } else { 02856 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 02857 res = CLI_FAILURE; 02858 } 02859 AST_LIST_UNLOCK(&minivm_zones); 02860 02861 return res; 02862 }
| static int invent_message | ( | struct ast_channel * | chan, | |
| char * | domain, | |||
| char * | username, | |||
| int | busy, | |||
| char * | ecodes | |||
| ) | [static] |
Play intro message before recording voicemail.
Definition at line 1309 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 minivm_greet_exec().
01310 { 01311 int res; 01312 char fn[PATH_MAX]; 01313 01314 ast_debug(2, "Still preparing to play message ...\n"); 01315 01316 snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username); 01317 01318 if (ast_fileexists(fn, NULL, NULL) > 0) { 01319 res = ast_streamfile(chan, fn, chan->language); 01320 if (res) 01321 return -1; 01322 res = ast_waitstream(chan, ecodes); 01323 if (res) 01324 return res; 01325 } else { 01326 int numericusername = 1; 01327 char *i = username; 01328 01329 ast_debug(2, "No personal prompts. Using default prompt set for language\n"); 01330 01331 while (*i) { 01332 ast_debug(2, "Numeric? Checking %c\n", *i); 01333 if (!isdigit(*i)) { 01334 numericusername = FALSE; 01335 break; 01336 } 01337 i++; 01338 } 01339 01340 if (numericusername) { 01341 if(ast_streamfile(chan, "vm-theperson", chan->language)) 01342 return -1; 01343 if ((res = ast_waitstream(chan, ecodes))) 01344 return res; 01345 01346 res = ast_say_digit_str(chan, username, ecodes, chan->language); 01347 if (res) 01348 return res; 01349 } else { 01350 if(ast_streamfile(chan, "vm-theextensionis", chan->language)) 01351 return -1; 01352 if ((res = ast_waitstream(chan, ecodes))) 01353 return res; 01354 } 01355 } 01356 01357 res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language); 01358 if (res) 01359 return -1; 01360 res = ast_waitstream(chan, ecodes); 01361 return res; 01362 }
| static int leave_voicemail | ( | struct ast_channel * | chan, | |
| char * | username, | |||
| struct leave_vm_options * | options | |||
| ) | [static] |
Record voicemail message, store into file prepared for sending e-mail.
Definition at line 1604 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 minivm_record_exec().
01605 { 01606 char tmptxtfile[PATH_MAX]; 01607 char callerid[256]; 01608 FILE *txt; 01609 int res = 0, txtdes; 01610 int msgnum; 01611 int duration = 0; 01612 char date[256]; 01613 char tmpdir[PATH_MAX]; 01614 char ext_context[256] = ""; 01615 char fmt[80]; 01616 char *domain; 01617 char tmp[256] = ""; 01618 struct minivm_account *vmu; 01619 int userdir; 01620 01621 ast_copy_string(tmp, username, sizeof(tmp)); 01622 username = tmp; 01623 domain = strchr(tmp, '@'); 01624 if (domain) { 01625 *domain = '\0'; 01626 domain++; 01627 } 01628 01629 if (!(vmu = find_account(domain, username, TRUE))) { 01630 /* We could not find user, let's exit */ 01631 ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain); 01632 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01633 return 0; 01634 } 01635 01636 /* Setup pre-file if appropriate */ 01637 if (strcmp(vmu->domain, "localhost")) 01638 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 01639 else 01640 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 01641 01642 /* The meat of recording the message... All the announcements and beeps have been played*/ 01643 if (ast_strlen_zero(vmu->attachfmt)) 01644 ast_copy_string(fmt, default_vmformat, sizeof(fmt)); 01645 else 01646 ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt)); 01647 01648 if (ast_strlen_zero(fmt)) { 01649 ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat); 01650 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01651 return res; 01652 } 01653 msgnum = 0; 01654 01655 userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp"); 01656 01657 /* If we have no user directory, use generic temporary directory */ 01658 if (!userdir) { 01659 create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", ""); 01660 ast_debug(3, "Creating temporary directory %s\n", tmpdir); 01661 } 01662 01663 01664 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 01665 01666 01667 /* XXX This file needs to be in temp directory */ 01668 txtdes = mkstemp(tmptxtfile); 01669 if (txtdes < 0) { 01670 ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno)); 01671 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 01672 if (!res) 01673 res = ast_waitstream(chan, ""); 01674 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01675 return res; 01676 } 01677 01678 if (res >= 0) { 01679 /* Unless we're *really* silent, try to send the beep */ 01680 res = ast_streamfile(chan, "beep", chan->language); 01681 if (!res) 01682 res = ast_waitstream(chan, ""); 01683 } 01684 01685 /* OEJ XXX Maybe this can be turned into a log file? Hmm. */ 01686 /* Store information */ 01687 ast_debug(2, "Open file for metadata: %s\n", tmptxtfile); 01688 01689 res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain); 01690 01691 txt = fdopen(txtdes, "w+"); 01692 if (!txt) { 01693 ast_log(LOG_WARNING, "Error opening text file for output\n"); 01694 } else { 01695 struct ast_tm tm; 01696 struct timeval now = ast_tvnow(); 01697 char timebuf[30]; 01698 char logbuf[BUFSIZ]; 01699 get_date(date, sizeof(date)); 01700 ast_localtime(&now, &tm, NULL); 01701 ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm); 01702 01703 snprintf(logbuf, sizeof(logbuf), 01704 /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */ 01705 "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n", 01706 username, 01707 chan->context, 01708 chan->macrocontext, 01709 chan->exten, 01710 chan->priority, 01711 chan->name, 01712 ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), 01713 date, 01714 timebuf, 01715 duration, 01716 duration < global_vmminmessage ? "IGNORED" : "OK", 01717 vmu->accountcode 01718 ); 01719 fprintf(txt, "%s", logbuf); 01720 if (minivmlogfile) { 01721 ast_mutex_lock(&minivmloglock); 01722 fprintf(minivmlogfile, "%s", logbuf); 01723 ast_mutex_unlock(&minivmloglock); 01724 } 01725 01726 if (duration < global_vmminmessage) { 01727 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, global_vmminmessage); 01728 fclose(txt); 01729 ast_filedelete(tmptxtfile, NULL); 01730 unlink(tmptxtfile); 01731 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01732 return 0; 01733 } 01734 fclose(txt); /* Close log file */ 01735 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01736 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 01737 unlink(tmptxtfile); 01738 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01739 if(ast_test_flag(vmu, MVM_ALLOCED)) 01740 free_user(vmu); 01741 return 0; 01742 } 01743 01744 /* Set channel variables for the notify application */ 01745 pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile); 01746 snprintf(timebuf, sizeof(timebuf), "%d", duration); 01747 pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf); 01748 pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt); 01749 01750 } 01751 global_stats.lastreceived = ast_tvnow(); 01752 global_stats.receivedmessages++; 01753 // /* Go ahead and delete audio files from system, they're not needed any more */ 01754 // if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01755 // ast_filedelete(tmptxtfile, NULL); 01756 // /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */ 01757 // ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile); 01758 // } 01759 01760 if (res > 0) 01761 res = 0; 01762 01763 if(ast_test_flag(vmu, MVM_ALLOCED)) 01764 free_user(vmu); 01765 01766 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 01767 return res; 01768 }
| static int load_config | ( | int | reload | ) | [static] |
Load minivoicemail configuration.
Definition at line 2573 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_charset, 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.
Referenced by load_module(), and reload().
02574 { 02575 struct ast_config *cfg; 02576 struct ast_variable *var; 02577 char *cat; 02578 const char *chanvar; 02579 int error = 0; 02580 struct minivm_template *template; 02581 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 02582 02583 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 02584 if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 02585 return 0; 02586 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02587 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 02588 return 0; 02589 } 02590 02591 ast_mutex_lock(&minivmlock); 02592 02593 /* Destroy lists to reconfigure */ 02594 message_destroy_list(); /* Destroy list of voicemail message templates */ 02595 timezone_destroy_list(); /* Destroy list of timezones */ 02596 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 02597 ast_debug(2, "Destroyed memory objects...\n"); 02598 02599 /* First, set some default settings */ 02600 global_externnotify[0] = '\0'; 02601 global_logfile[0] = '\0'; 02602 global_vmmaxmessage = 2000; 02603 global_maxgreet = 2000; 02604 global_vmminmessage = 0; 02605 strcpy(global_mailcmd, SENDMAIL); 02606 global_maxsilence = 0; 02607 global_saydurationminfo = 2; 02608 ast_copy_string(default_vmformat, "wav", sizeof(default_vmformat)); 02609 ast_set2_flag((&globalflags), FALSE, MVM_REVIEW); 02610 ast_set2_flag((&globalflags), FALSE, MVM_OPERATOR); 02611 strcpy(global_charset, "ISO-8859-1"); 02612 /* Reset statistics */ 02613 memset(&global_stats, 0, sizeof(global_stats)); 02614 global_stats.reset = ast_tvnow(); 02615 02616 global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 02617 02618 /* Make sure we could load configuration file */ 02619 if (!cfg) { 02620 ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n"); 02621 ast_mutex_unlock(&minivmlock); 02622 return 0; 02623 } 02624 02625 ast_debug(2, "Loaded configuration file, now parsing\n"); 02626 02627 /* General settings */ 02628 02629 cat = ast_category_browse(cfg, NULL); 02630 while (cat) { 02631 ast_debug(3, "Found configuration section [%s]\n", cat); 02632 if (!strcasecmp(cat, "general")) { 02633 /* Nothing right now */ 02634 error += apply_general_options(ast_variable_browse(cfg, cat)); 02635 } else if (!strncasecmp(cat, "template-", 9)) { 02636 /* Template */ 02637 char *name = cat + 9; 02638 02639 /* Now build and link template to list */ 02640 error += message_template_build(name, ast_variable_browse(cfg, cat)); 02641 } else { 02642 var = ast_variable_browse(cfg, cat); 02643 if (!strcasecmp(cat, "zonemessages")) { 02644 /* Timezones in this context */ 02645 while (var) { 02646 timezone_add(var->name, var->value); 02647 var = var->next; 02648 } 02649 } else { 02650 /* Create mailbox from this */ 02651 error += create_vmaccount(cat, var, FALSE); 02652 } 02653 } 02654 /* Find next section in configuration file */ 02655 cat = ast_category_browse(cfg, cat); 02656 } 02657 02658 /* Configure the default email template */ 02659 message_template_build("email-default", NULL); 02660 template = message_template_find("email-default"); 02661 02662 /* Load date format config for voicemail mail */ 02663 if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat"))) 02664 ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat)); 02665 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring"))) 02666 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02667 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress"))) 02668 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02669 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset"))) 02670 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02671 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject"))) 02672 ast_copy_string(template->subject, chanvar, sizeof(template->subject)); 02673 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody"))) 02674 template->body = message_template_parse_emailbody(chanvar); 02675 template->attachment = TRUE; 02676 02677 message_template_build("pager-default", NULL); 02678 template = message_template_find("pager-default"); 02679 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 02680 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02681 if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress"))) 02682 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02683 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset"))) 02684 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02685 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject"))) 02686 ast_copy_string(template->subject, chanvar,sizeof(template->subject)); 02687 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody"))) 02688 template->body = message_template_parse_emailbody(chanvar); 02689 template->attachment = FALSE; 02690 02691 if (error) 02692 ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error); 02693 02694 ast_mutex_unlock(&minivmlock); 02695 ast_config_destroy(cfg); 02696 02697 /* Close log file if it's open and disabled */ 02698 if(minivmlogfile) 02699 fclose(minivmlogfile); 02700 02701 /* Open log file if it's enabled */ 02702 if(!ast_strlen_zero(global_logfile)) { 02703 minivmlogfile = fopen(global_logfile, "a"); 02704 if(!minivmlogfile) 02705 ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno)); 02706 if (minivmlogfile) 02707 ast_debug(3, "Opened log file %s \n", global_logfile); 02708 } 02709 02710 return 0; 02711 }
| static int load_module | ( | void | ) | [static] |
Load mini voicemail module.
Definition at line 3269 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().
03270 { 03271 int res; 03272 03273 res = ast_register_application_xml(app_minivm_record, minivm_record_exec); 03274 res = ast_register_application_xml(app_minivm_greet, minivm_greet_exec); 03275 res = ast_register_application_xml(app_minivm_notify, minivm_notify_exec); 03276 res = ast_register_application_xml(app_minivm_delete, minivm_delete_exec); 03277 res = ast_register_application_xml(app_minivm_accmess, minivm_accmess_exec); 03278 res = ast_register_application_xml(app_minivm_mwi, minivm_mwi_exec); 03279 03280 ast_custom_function_register(&minivm_account_function); 03281 ast_custom_function_register(&minivm_counter_function); 03282 if (res) 03283 return(res); 03284 03285 if ((res = load_config(0))) 03286 return(res); 03287 03288 ast_cli_register_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03289 03290 /* compute the location of the voicemail spool directory */ 03291 snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 03292 03293 return res; 03294 }
| static char* mailheader_quote | ( | const char * | from, | |
| char * | to, | |||
| size_t | len | |||
| ) | [static] |
Fix quote of mail headers for non-ascii characters.
Definition at line 911 of file app_minivm.c.
Referenced by sendmail().
00912 { 00913 char *ptr = to; 00914 *ptr++ = '"'; 00915 for (; ptr < to + len - 1; from++) { 00916 if (*from == '"') 00917 *ptr++ = '\\'; 00918 else if (*from == '\0') 00919 break; 00920 *ptr++ = *from; 00921 } 00922 if (ptr < to + len - 1) 00923 *ptr++ = '"'; 00924 *ptr = '\0'; 00925 return to; 00926 }
| static int make_dir | ( | char * | dest, | |
| int | len, | |||
| const char * | domain, | |||
| const char * | username, | |||
| const char * | folder | |||
| ) | [static] |
Create directory based on components.
Definition at line 1263 of file app_minivm.c.
References ast_strlen_zero().
Referenced by check_dirpath(), and create_dirpath().
01264 { 01265 return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : ""); 01266 }
| static void message_destroy_list | ( | void | ) | [static] |
Clear list of templates.
Definition at line 718 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().
00719 { 00720 struct minivm_template *this; 00721 AST_LIST_LOCK(&message_templates); 00722 while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list))) 00723 message_template_free(this); 00724 00725 AST_LIST_UNLOCK(&message_templates); 00726 }
| static int message_template_build | ( | const char * | name, | |
| struct ast_variable * | var | |||
| ) | [static] |
Build message template from configuration.
Definition at line 635 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().
00636 { 00637 struct minivm_template *template; 00638 int error = 0; 00639 00640 template = message_template_create(name); 00641 if (!template) { 00642 ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name); 00643 return -1; 00644 } 00645 00646 while (var) { 00647 ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name); 00648 if (!strcasecmp(var->name, "fromaddress")) { 00649 ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress)); 00650 } else if (!strcasecmp(var->name, "fromemail")) { 00651 ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail)); 00652 } else if (!strcasecmp(var->name, "subject")) { 00653 ast_copy_string(template->subject, var->value, sizeof(template->subject)); 00654 } else if (!strcasecmp(var->name, "locale")) { 00655 ast_copy_string(template->locale, var->value, sizeof(template->locale)); 00656 } else if (!strcasecmp(var->name, "attachmedia")) { 00657 template->attachment = ast_true(var->value); 00658 } else if (!strcasecmp(var->name, "dateformat")) { 00659 ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat)); 00660 } else if (!strcasecmp(var->name, "charset")) { 00661 ast_copy_string(template->charset, var->value, sizeof(template->charset)); 00662 } else if (!strcasecmp(var->name, "templatefile")) { 00663 if (template->body) 00664 ast_free(template->body); 00665 template->body = message_template_parse_filebody(var->value); 00666 if (!template->body) { 00667 ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value); 00668 error++; 00669 } 00670 } else if (!strcasecmp(var->name, "messagebody")) { 00671 if (template->body) 00672 ast_free(template->body); 00673 template->body = message_template_parse_emailbody(var->value); 00674 if (!template->body) { 00675 ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value); 00676 error++; 00677 } 00678 } else { 00679 ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value); 00680 error++; 00681 } 00682 var = var->next; 00683 } 00684 if (error) 00685 ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name); 00686 00687 AST_LIST_LOCK(&message_templates); 00688 AST_LIST_INSERT_TAIL(&message_templates, template, list); 00689 AST_LIST_UNLOCK(&message_templates); 00690 00691 global_stats.templates++; 00692 00693 return error; 00694 }
| static struct minivm_template* message_template_create | ( | const char * | name | ) | [static, read] |
Create message template.
Definition at line 607 of file app_minivm.c.
References ast_calloc, ast_copy_string(), DEFAULT_CHARSET, DEFAULT_DATEFORMAT, and TRUE.
Referenced by message_template_build().
00608 { 00609 struct minivm_template *template; 00610 00611 template = ast_calloc(1, sizeof(*template)); 00612 if (!template) 00613 return NULL; 00614 00615 /* Set some defaults for templates */ 00616 ast_copy_string(template->name, name, sizeof(template->name)); 00617 ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat)); 00618 ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset)); 00619 ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject)); 00620 template->attachment = TRUE; 00621 00622 return template; 00623 }
| static struct minivm_template* message_template_find | ( | const char * | name | ) | [static, read] |
Find named template.
Definition at line 697 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().
00698 { 00699 struct minivm_template *this, *res = NULL; 00700 00701 if (ast_strlen_zero(name)) 00702 return NULL; 00703 00704 AST_LIST_LOCK(&message_templates); 00705 AST_LIST_TRAVERSE(&message_templates, this, list) { 00706 if (!strcasecmp(this->name, name)) { 00707 res = this; 00708 break; 00709 } 00710 } 00711 AST_LIST_UNLOCK(&message_templates); 00712 00713 return res; 00714 }
| static void message_template_free | ( | struct minivm_template * | template | ) | [static] |
Release memory allocated by message template.
Definition at line 626 of file app_minivm.c.
References ast_free.
Referenced by message_destroy_list().
| static char * message_template_parse_emailbody | ( | const char * | body | ) | [static] |
Parse emailbody template from configuration file.
Definition at line 2488 of file app_minivm.c.
References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.
Referenced by load_config(), and message_template_build().
02489 { 02490 char *tmpread, *tmpwrite; 02491 char *emailbody = ast_strdup(configuration); 02492 02493 /* substitute strings \t and \n into the apropriate characters */ 02494 tmpread = tmpwrite = emailbody; 02495 while ((tmpwrite = strchr(tmpread,'\\'))) { 02496 int len = strlen("\n"); 02497 switch (tmpwrite[1]) { 02498 case 'n': 02499 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02500 strncpy(tmpwrite, "\n", len); 02501 break; 02502 case 't': 02503 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02504 strncpy(tmpwrite, "\t", len); 02505 break; 02506 default: 02507 ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]); 02508 } 02509 tmpread = tmpwrite + len; 02510 } 02511 return emailbody; 02512 }
| static char * message_template_parse_filebody | ( | const char * | filename | ) | [static] |
Read message template from file.
Definition at line 2448 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().
02448 { 02449 char buf[BUFSIZ * 6]; 02450 char readbuf[BUFSIZ]; 02451 char filenamebuf[BUFSIZ]; 02452 char *writepos; 02453 char *messagebody; 02454 FILE *fi; 02455 int lines = 0; 02456 02457 if (ast_strlen_zero(filename)) 02458 return NULL; 02459 if (*filename == '/') 02460 ast_copy_string(filenamebuf, filename, sizeof(filenamebuf)); 02461 else 02462 snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 02463 02464 if (!(fi = fopen(filenamebuf, "r"))) { 02465 ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf); 02466 return NULL; 02467 } 02468 writepos = buf; 02469 while (fgets(readbuf, sizeof(readbuf), fi)) { 02470 lines ++; 02471 if (writepos != buf) { 02472 *writepos = '\n'; /* Replace EOL with new line */ 02473 writepos++; 02474 } 02475 ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf)); 02476 writepos += strlen(readbuf) - 1; 02477 } 02478 fclose(fi); 02479 messagebody = ast_calloc(1, strlen(buf + 1)); 02480 ast_copy_string(messagebody, buf, strlen(buf) + 1); 02481 ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) ); 02482 ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody); 02483 02484 return messagebody; 02485 }
| static int minivm_accmess_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Record specific messages for voicemail account.
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_string(), ast_debug, ast_log(), AST_STATE_UP, 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().
02196 { 02197 int argc = 0; 02198 char *argv[2]; 02199 char filename[PATH_MAX]; 02200 char tmp[PATH_MAX]; 02201 char *domain; 02202 char *tmpptr = NULL; 02203 struct minivm_account *vmu; 02204 char *username = argv[0]; 02205 struct ast_flags flags = { 0 }; 02206 char *opts[OPT_ARG_ARRAY_SIZE]; 02207 int error = FALSE; 02208 char *message = NULL; 02209 char *prompt = NULL; 02210 int duration; 02211 int cmd; 02212 02213 if (ast_strlen_zero(data)) { 02214 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02215 error = TRUE; 02216 } else 02217 tmpptr = ast_strdupa((char *)data); 02218 if (!error) { 02219 if (!tmpptr) { 02220 ast_log(LOG_ERROR, "Out of memory\n"); 02221 error = TRUE; 02222 } else 02223 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02224 } 02225 02226 if (argc <=1) { 02227 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02228 error = TRUE; 02229 } 02230 if (!error && strlen(argv[1]) > 1) { 02231 ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]); 02232 error = TRUE; 02233 } 02234 02235 if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) { 02236 ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]); 02237 error = TRUE; 02238 } 02239 02240 if (error) { 02241 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02242 return -1; 02243 } 02244 02245 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02246 username = tmp; 02247 domain = strchr(tmp, '@'); 02248 if (domain) { 02249 *domain = '\0'; 02250 domain++; 02251 } 02252 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02253 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02254 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02255 return -1; 02256 } 02257 02258 if(!(vmu = find_account(domain, username, TRUE))) { 02259 /* We could not find user, let's exit */ 02260 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02261 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02262 return -1; 02263 } 02264 02265 /* Answer channel if it's not already answered */ 02266 if (chan->_state != AST_STATE_UP) 02267 ast_answer(chan); 02268 02269 /* Here's where the action is */ 02270 if (ast_test_flag(&flags, OPT_BUSY_GREETING)) { 02271 message = "busy"; 02272 prompt = "vm-rec-busy"; 02273 } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) { 02274 message = "unavailable"; 02275 prompt = "vm-rec-unv"; 02276 } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) { 02277 message = "temp"; 02278 prompt = "vm-rec-temp"; 02279 } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) { 02280 message = "greet"; 02281 prompt = "vm-rec-name"; 02282 } 02283 snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message); 02284 /* Maybe we should check the result of play_record_review ? */ 02285 cmd = play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, FALSE); 02286 02287 ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration); 02288 02289 if(ast_test_flag(vmu, MVM_ALLOCED)) 02290 free_user(vmu); 02291 02292 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS"); 02293 02294 /* Ok, we're ready to rock and roll. Return to dialplan */ 02295 return 0; 02296 }
| 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 2937 of file app_minivm.c.
References minivm_account::accountcode, ast_copy_string(), ast_log(), 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.
02938 { 02939 struct minivm_account *vmu; 02940 char *username, *domain, *colname; 02941 02942 if (!(username = ast_strdupa(data))) { 02943 ast_log(LOG_ERROR, "Memory Error!\n"); 02944 return -1; 02945 } 02946 02947 if ((colname = strchr(username, ':'))) { 02948 *colname = '\0'; 02949 colname++; 02950 } else { 02951 colname = "path"; 02952 } 02953 if ((domain = strchr(username, '@'))) { 02954 *domain = '\0'; 02955 domain++; 02956 } 02957 if (ast_strlen_zero(username) || ast_strlen_zero(domain)) { 02958 ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n"); 02959 return 0; 02960 } 02961 02962 if (!(vmu = find_account(domain, username, TRUE))) 02963 return 0; 02964 02965 if (!strcasecmp(colname, "hasaccount")) { 02966 ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len); 02967 } else if (!strcasecmp(colname, "fullname")) { 02968 ast_copy_string(buf, vmu->fullname, len); 02969 } else if (!strcasecmp(colname, "email")) { 02970 if (!ast_strlen_zero(vmu->email)) 02971 ast_copy_string(buf, vmu->email, len); 02972 else 02973 snprintf(buf, len, "%s@%s", vmu->username, vmu->domain); 02974 } else if (!strcasecmp(colname, "pager")) { 02975 ast_copy_string(buf, vmu->pager, len); 02976 } else if (!strcasecmp(colname, "etemplate")) { 02977 if (!ast_strlen_zero(vmu->etemplate)) 02978 ast_copy_string(buf, vmu->etemplate, len); 02979 else 02980 ast_copy_string(buf, "email-default", len); 02981 } else if (!strcasecmp(colname, "language")) { 02982 ast_copy_string(buf, vmu->language, len); 02983 } else if (!strcasecmp(colname, "timezone")) { 02984 ast_copy_string(buf, vmu->zonetag, len); 02985 } else if (!strcasecmp(colname, "ptemplate")) { 02986 if (!ast_strlen_zero(vmu->ptemplate)) 02987 ast_copy_string(buf, vmu->ptemplate, len); 02988 else 02989 ast_copy_string(buf, "email-default", len); 02990 } else if (!strcasecmp(colname, "accountcode")) { 02991 ast_copy_string(buf, vmu->accountcode, len); 02992 } else if (!strcasecmp(colname, "pincode")) { 02993 ast_copy_string(buf, vmu->pincode, len); 02994 } else if (!strcasecmp(colname, "path")) { 02995 check_dirpath(buf, len, vmu->domain, vmu->username, NULL); 02996 } else { /* Look in channel variables */ 02997 struct ast_variable *var; 02998 int found = 0; 02999 03000 for (var = vmu->chanvars ; var ; var = var->next) 03001 if (!strcmp(var->name, colname)) { 03002 ast_copy_string(buf, var->value, len); 03003 found = 1; 03004 break; 03005 } 03006 } 03007 03008 if(ast_test_flag(vmu, MVM_ALLOCED)) 03009 free_user(vmu); 03010 03011 return 0; 03012 }
| 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 3089 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strlen_zero(), create_dirpath(), FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
03090 { 03091 char *username, *domain, *countername; 03092 struct minivm_account *vmu = NULL; 03093 char userpath[BUFSIZ]; 03094 int res; 03095 03096 *buf = '\0'; 03097 03098 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03099 ast_log(LOG_WARNING, "Memory error!\n"); 03100 return -1; 03101 } 03102 if ((countername = strchr(username, ':'))) { 03103 *countername = '\0'; 03104 countername++; 03105 } 03106 03107 if ((domain = strchr(username, '@'))) { 03108 *domain = '\0'; 03109 domain++; 03110 } 03111 03112 /* If we have neither username nor domain now, let's give up */ 03113 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03114 ast_log(LOG_ERROR, "No account given\n"); 03115 return -1; 03116 } 03117 03118 if (ast_strlen_zero(countername)) { 03119 ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n"); 03120 return -1; 03121 } 03122 03123 /* We only have a domain, no username */ 03124 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03125 domain = username; 03126 username = NULL; 03127 } 03128 03129 /* If we can't find account or if the account is temporary, return. */ 03130 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03131 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03132 return 0; 03133 } 03134 03135 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03136 03137 /* We have the path, now read the counter file */ 03138 res = access_counter_file(userpath, countername, 0, 0); 03139 if (res >= 0) 03140 snprintf(buf, len, "%d", res); 03141 return 0; 03142 }
| 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 3145 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strlen_zero(), create_dirpath(), FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
03146 { 03147 char *username, *domain, *countername, *operand; 03148 char userpath[BUFSIZ]; 03149 struct minivm_account *vmu; 03150 int change = 0; 03151 int operation = 0; 03152 03153 if(!value) 03154 return -1; 03155 change = atoi(value); 03156 03157 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03158 ast_log(LOG_WARNING, "Memory error!\n"); 03159 return -1; 03160 } 03161 03162 if ((countername = strchr(username, ':'))) { 03163 *countername = '\0'; 03164 countername++; 03165 } 03166 if ((operand = strchr(countername, ':'))) { 03167 *operand = '\0'; 03168 operand++; 03169 } 03170 03171 if ((domain = strchr(username, '@'))) { 03172 *domain = '\0'; 03173 domain++; 03174 } 03175 03176 /* If we have neither username nor domain now, let's give up */ 03177 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03178 ast_log(LOG_ERROR, "No account given\n"); 03179 return -1; 03180 } 03181 03182 /* We only have a domain, no username */ 03183 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03184 domain = username; 03185 username = NULL; 03186 } 03187 03188 if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) { 03189 ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n"); 03190 return -1; 03191 } 03192 03193 /* If we can't find account or if the account is temporary, return. */ 03194 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03195 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03196 return 0; 03197 } 03198 03199 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03200 /* Now, find out our operator */ 03201 if (*operand == 'i') /* Increment */ 03202 operation = 2; 03203 else if (*operand == 'd') { 03204 change = change * -1; 03205 operation = 2; 03206 } else if (*operand == 's') 03207 operation = 1; 03208 else { 03209 ast_log(LOG_ERROR, "Unknown operator: %s\n", operand); 03210 return -1; 03211 } 03212 03213 /* We have the path, now read the counter file */ 03214 access_counter_file(userpath, countername, change, operation); 03215 return 0; 03216 }
| static int minivm_delete_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Dialplan application to delete voicemail.
Definition at line 2157 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().
02158 { 02159 int res = 0; 02160 char filename[BUFSIZ]; 02161 02162 if (!ast_strlen_zero(data)) { 02163 ast_copy_string(filename, (char *) data, sizeof(filename)); 02164 } else { 02165 ast_channel_lock(chan); 02166 ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename)); 02167 ast_channel_unlock(chan); 02168 } 02169 02170 if (ast_strlen_zero(filename)) { 02171 ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n"); 02172 return res; 02173 } 02174 02175 /* Go ahead and delete audio files from system, they're not needed any more */ 02176 /* We should look for both audio and text files here */ 02177 if (ast_fileexists(filename, NULL, NULL) > 0) { 02178 res = vm_delete(filename); 02179 if (res) { 02180 ast_debug(2, "Can't delete file: %s\n", filename); 02181 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02182 } else { 02183 ast_debug(2, "Deleted voicemail file :: %s \n", filename); 02184 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS"); 02185 } 02186 } else { 02187 ast_debug(2, "Filename does not exist: %s\n", filename); 02188 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02189 } 02190 02191 return res; 02192 }
| static int minivm_greet_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Play voicemail prompts - either generic or user specific.
Definition at line 1971 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_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().
01972 { 01973 struct leave_vm_options leave_options = { 0, '\0'}; 01974 int argc; 01975 char *argv[2]; 01976 struct ast_flags flags = { 0 }; 01977 char *opts[OPT_ARG_ARRAY_SIZE]; 01978 int res = 0; 01979 int ausemacro = 0; 01980 int ousemacro = 0; 01981 int ouseexten = 0; 01982 char tmp[PATH_MAX]; 01983 char dest[PATH_MAX]; 01984 char prefile[PATH_MAX] = ""; 01985 char tempfile[PATH_MAX] = ""; 01986 char ext_context[256] = ""; 01987 char *domain; 01988 char ecodes[16] = "#"; 01989 char *tmpptr; 01990 struct minivm_account *vmu; 01991 char *username = argv[0]; 01992 01993 if (ast_strlen_zero(data)) { 01994 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01995 return -1; 01996 } 01997 tmpptr = ast_strdupa((char *)data); 01998 if (!tmpptr) { 01999 ast_log(LOG_ERROR, "Out of memory\n"); 02000 return -1; 02001 } 02002 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02003 02004 if (argc == 2) { 02005 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) 02006 return -1; 02007 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02008 } 02009 02010 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02011 username = tmp; 02012 domain = strchr(tmp, '@'); 02013 if (domain) { 02014 *domain = '\0'; 02015 domain++; 02016 } 02017 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02018 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]); 02019 return -1; 02020 } 02021 ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain); 02022 02023 if (!(vmu = find_account(domain, username, TRUE))) { 02024 ast_log(LOG_ERROR, "Could not allocate memory. \n"); 02025 return -1; 02026 } 02027 02028 /* Answer channel if it's not already answered */ 02029 if (chan->_state != AST_STATE_UP) 02030 ast_answer(chan); 02031 02032 /* Setup pre-file if appropriate */ 02033 if (strcmp(vmu->domain, "localhost")) 02034 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 02035 else 02036 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 02037 02038 if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) { 02039 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy"); 02040 if (res) 02041 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username); 02042 } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) { 02043 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail"); 02044 if (res) 02045 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username); 02046 } 02047 /* Check for temporary greeting - it overrides busy and unavail */ 02048 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username); 02049 if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) { 02050 ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile); 02051 ast_copy_string(prefile, tempfile, sizeof(prefile)); 02052 } 02053 ast_debug(2, "Preparing to play message ...\n"); 02054 02055 /* Check current or macro-calling context for special extensions */ 02056 if (ast_test_flag(vmu, MVM_OPERATOR)) { 02057 if (!ast_strlen_zero(vmu->exit)) { 02058 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 02059 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02060 ouseexten = 1; 02061 } 02062 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 02063 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02064 ouseexten = 1; 02065 } 02066 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 02067 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02068 ousemacro = 1; 02069 } 02070 } 02071 02072 if (!ast_strlen_zero(vmu->exit)) { 02073 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 02074 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02075 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 02076 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02077 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 02078 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02079 ausemacro = 1; 02080 } 02081 02082 res = 0; /* Reset */ 02083 /* Play the beginning intro if desired */ 02084 if (!ast_strlen_zero(prefile)) { 02085 if (ast_streamfile(chan, prefile, chan->language) > -1) 02086 res = ast_waitstream(chan, ecodes); 02087 } else { 02088 ast_debug(2, "%s doesn't exist, doing what we can\n", prefile); 02089 res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes); 02090 } 02091 if (res < 0) { 02092 ast_debug(2, "Hang up during prefile playback\n"); 02093 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02094 if(ast_test_flag(vmu, MVM_ALLOCED)) 02095 free_user(vmu); 02096 return -1; 02097 } 02098 if (res == '#') { 02099 /* On a '#' we skip the instructions */ 02100 ast_set_flag(&leave_options, OPT_SILENT); 02101 res = 0; 02102 } 02103 if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) { 02104 res = ast_streamfile(chan, SOUND_INTRO, chan->language); 02105 if (!res) 02106 res = ast_waitstream(chan, ecodes); 02107 if (res == '#') { 02108 ast_set_flag(&leave_options, OPT_SILENT); 02109 res = 0; 02110 } 02111 } 02112 if (res > 0) 02113 ast_stopstream(chan); 02114 /* Check for a '*' here in case the caller wants to escape from voicemail to something 02115 other than the operator -- an automated attendant or mailbox login for example */ 02116 if (res == '*') { 02117 chan->exten[0] = 'a'; 02118 chan->exten[1] = '\0'; 02119 if (!ast_strlen_zero(vmu->exit)) { 02120 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02121 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 02122 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02123 } 02124 chan->priority = 0; 02125 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02126 res = 0; 02127 } else if (res == '0') { /* Check for a '0' here */ 02128 if(ouseexten || ousemacro) { 02129 chan->exten[0] = 'o'; 02130 chan->exten[1] = '\0'; 02131 if (!ast_strlen_zero(vmu->exit)) { 02132 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02133 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 02134 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02135 } 02136 ast_play_and_wait(chan, "transfer"); 02137 chan->priority = 0; 02138 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02139 } 02140 res = 0; 02141 } else if (res < 0) { 02142 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02143 res = -1; 02144 } else 02145 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS"); 02146 02147 if(ast_test_flag(vmu, MVM_ALLOCED)) 02148 free_user(vmu); 02149 02150 02151 /* Ok, we're ready to rock and roll. Return to dialplan */ 02152 return res; 02153 02154 }
| static int minivm_mwi_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Send MWI using interal Asterisk event subsystem.
Definition at line 1795 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args, ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_ERROR, mailbox, and queue_mwi_event().
Referenced by load_module().
01796 { 01797 int argc; 01798 char *argv[4]; 01799 int res = 0; 01800 char *tmpptr; 01801 char tmp[PATH_MAX]; 01802 char *mailbox; 01803 char *domain; 01804 if (ast_strlen_zero(data)) { 01805 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01806 return -1; 01807 } 01808 tmpptr = ast_strdupa((char *)data); 01809 if (!tmpptr) { 01810 ast_log(LOG_ERROR, "Out of memory\n"); 01811 return -1; 01812 } 01813 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 01814 if (argc < 4) { 01815 ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc); 01816 return -1; 01817 } 01818 ast_copy_string(tmp, argv[0], sizeof(tmp)); 01819 mailbox = tmp; 01820 domain = strchr(tmp, '@'); 01821 if (domain) { 01822 *domain = '\0'; 01823 domain++; 01824 } 01825 if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) { 01826 ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]); 01827 return -1; 01828 } 01829 queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); 01830 01831 return res; 01832 }
| static int minivm_notify_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Notify voicemail account owners - either generic template or user specific.
Definition at line 1836 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), 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().
01837 { 01838 int argc; 01839 char *argv[2]; 01840 int res = 0; 01841 char tmp[PATH_MAX]; 01842 char *domain; 01843 char *tmpptr; 01844 struct minivm_account *vmu; 01845 char *username = argv[0]; 01846 const char *template = ""; 01847 const char *filename; 01848 const char *format; 01849 const char *duration_string; 01850 01851 if (ast_strlen_zero(data)) { 01852 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01853 return -1; 01854 } 01855 tmpptr = ast_strdupa((char *)data); 01856 if (!tmpptr) { 01857 ast_log(LOG_ERROR, "Out of memory\n"); 01858 return -1; 01859 } 01860 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 01861 01862 if (argc == 2 && !ast_strlen_zero(argv[1])) 01863 template = argv[1]; 01864 01865 ast_copy_string(tmp, argv[0], sizeof(tmp)); 01866 username = tmp; 01867 domain = strchr(tmp, '@'); 01868 if (domain) { 01869 *domain = '\0'; 01870 domain++; 01871 } 01872 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 01873 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 01874 return -1; 01875 } 01876 01877 if(!(vmu = find_account(domain, username, TRUE))) { 01878 /* We could not find user, let's exit */ 01879 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 01880 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED"); 01881 return -1; 01882 } 01883 01884 ast_channel_lock(chan); 01885 if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) { 01886 filename = ast_strdupa(filename); 01887 } 01888 ast_channel_unlock(chan); 01889 /* Notify of new message to e-mail and pager */ 01890 if (!ast_strlen_zero(filename)) { 01891 ast_channel_lock(chan); 01892 if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) { 01893 format = ast_strdupa(format); 01894 } 01895 if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) { 01896 duration_string = ast_strdupa(duration_string); 01897 } 01898 ast_channel_unlock(chan); 01899 res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name); 01900 } 01901 01902 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED"); 01903 01904 01905 if(ast_test_flag(vmu, MVM_ALLOCED)) 01906 free_user(vmu); 01907 01908 /* Ok, we're ready to rock and roll. Return to dialplan */ 01909 01910 return res; 01911 01912 }
| static int minivm_record_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Dialplan function to record voicemail.
Definition at line 1915 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_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().
01916 { 01917 int res = 0; 01918 char *tmp; 01919 struct leave_vm_options leave_options; 01920 int argc; 01921 char *argv[2]; 01922 struct ast_flags flags = { 0 }; 01923 char *opts[OPT_ARG_ARRAY_SIZE]; 01924 01925 memset(&leave_options, 0, sizeof(leave_options)); 01926 01927 /* Answer channel if it's not already answered */ 01928 if (chan->_state != AST_STATE_UP) 01929 ast_answer(chan); 01930 01931 if (ast_strlen_zero(data)) { 01932 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01933 return -1; 01934 } 01935 tmp = ast_strdupa((char *)data); 01936 if (!tmp) { 01937 ast_log(LOG_ERROR, "Out of memory\n"); 01938 return -1; 01939 } 01940 argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv)); 01941 if (argc == 2) { 01942 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) { 01943 return -1; 01944 } 01945 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 01946 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 01947 int gain; 01948 01949 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 01950 ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 01951 return -1; 01952 } else 01953 leave_options.record_gain = (signed char) gain; 01954 } 01955 } 01956 01957 /* Now run the appliation and good luck to you! */ 01958 res = leave_voicemail(chan, argv[0], &leave_options); 01959 01960 if (res == ERROR_LOCK_PATH) { 01961 ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 01962 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01963 res = 0; 01964 } 01965 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 01966 01967 return res; 01968 }
| static struct minivm_account* mvm_user_alloc | ( | void | ) | [static, read] |
Allocate new vm user and set default values.
Definition at line 930 of file app_minivm.c.
References ast_calloc, and populate_defaults().
Referenced by find_account(), and find_user_realtime().
00931 { 00932 struct minivm_account *new; 00933 00934 new = ast_calloc(1, sizeof(*new)); 00935 if (!new) 00936 return NULL; 00937 populate_defaults(new); 00938 00939 return new; 00940 }
| 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] |
Send message to voicemail account owner.
Definition at line 1527 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_log(), 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(), and minivm_account::username.
Referenced by minivm_notify_exec().
01528 { 01529 char *stringp; 01530 struct minivm_template *etemplate; 01531 char *messageformat; 01532 int res = 0; 01533 char oldlocale[100]; 01534 const char *counter; 01535 01536 if (!ast_strlen_zero(vmu->attachfmt)) { 01537 if (strstr(format, vmu->attachfmt)) { 01538 format = vmu->attachfmt; 01539 } else 01540 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); 01541 } 01542 01543 etemplate = message_template_find(vmu->etemplate); 01544 if (!etemplate) 01545 etemplate = message_template_find(templatename); 01546 if (!etemplate) 01547 etemplate = message_template_find("email-default"); 01548 01549 /* Attach only the first format */ 01550 stringp = messageformat = ast_strdupa(format); 01551 strsep(&stringp, "|"); 01552 01553 if (!ast_strlen_zero(etemplate->locale)) { 01554 char *new_locale; 01555 ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale)); 01556 ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale); 01557 new_locale = setlocale(LC_TIME, etemplate->locale); 01558 if (new_locale == NULL) { 01559 ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale); 01560 } 01561 } 01562 01563 01564 01565 /* Read counter if available */ 01566 ast_channel_lock(chan); 01567 if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) { 01568 counter = ast_strdupa(counter); 01569 } 01570 ast_channel_unlock(chan); 01571 01572 if (ast_strlen_zero(counter)) { 01573 ast_debug(2, "MVM_COUNTER not found\n"); 01574 } else { 01575 ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter); 01576 } 01577 01578 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter); 01579 01580 if (res == 0 && !ast_strlen_zero(vmu->pager)) { 01581 /* Find template for paging */ 01582 etemplate = message_template_find(vmu->ptemplate); 01583 if (!etemplate) 01584 etemplate = message_template_find("pager-default"); 01585 if (etemplate->locale) { 01586 ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale)); 01587 setlocale(LC_TIME, etemplate->locale); 01588 } 01589 01590 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter); 01591 } 01592 01593 manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter); 01594 01595 run_externnotify(chan, vmu); /* Run external notification */ 01596 01597 if (etemplate->locale) 01598 setlocale(LC_TIME, oldlocale); /* Rest to old locale */ 01599 return res; 01600 }
| 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] |
Record voicemail message & let caller review or re-record it, or set options if applicable.
Definition at line 1378 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(), and minivm_accmess_exec().
01381 { 01382 int cmd = 0; 01383 int max_attempts = 3; 01384 int attempts = 0; 01385 int recorded = 0; 01386 int message_exists = 0; 01387 signed char zero_gain = 0; 01388 char *acceptdtmf = "#"; 01389 char *canceldtmf = ""; 01390 01391 /* Note that urgent and private are for flagging messages as such in the future */ 01392 01393 /* barf if no pointer passed to store duration in */ 01394 if (duration == NULL) { 01395 ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n"); 01396 return -1; 01397 } 01398 01399 cmd = '3'; /* Want to start by recording */ 01400 01401 while ((cmd >= 0) && (cmd != 't')) { 01402 switch (cmd) { 01403 case '1': 01404 ast_verb(3, "Saving message as is\n"); 01405 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01406 cmd = 't'; 01407 break; 01408 case '2': 01409 /* Review */ 01410 ast_verb(3, "Reviewing the message\n"); 01411 ast_streamfile(chan, recordfile, chan->language); 01412 cmd = ast_waitstream(chan, AST_DIGIT_ANY); 01413 break; 01414 case '3': 01415 message_exists = 0; 01416 /* Record */ 01417 if (recorded == 1) 01418 ast_verb(3, "Re-recording the message\n"); 01419 else 01420 ast_verb(3, "Recording the message\n"); 01421 if (recorded && outsidecaller) 01422 cmd = ast_play_and_wait(chan, "beep"); 01423 recorded = 1; 01424 /* 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 */ 01425 if (record_gain) 01426 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 01427 if (ast_test_flag(vmu, MVM_OPERATOR)) 01428 canceldtmf = "0"; 01429 cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf); 01430 if (record_gain) 01431 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 01432 if (cmd == -1) /* User has hung up, no options to give */ 01433 return cmd; 01434 if (cmd == '0') 01435 break; 01436 else if (cmd == '*') 01437 break; 01438 else { 01439 /* If all is well, a message exists */ 01440 message_exists = 1; 01441 cmd = 0; 01442 } 01443 break; 01444 case '4': 01445 case '5': 01446 case '6': 01447 case '7': 01448 case '8': 01449 case '9': 01450 case '*': 01451 case '#': 01452 cmd = ast_play_and_wait(chan, "vm-sorry"); 01453 break; 01454 case '0': 01455 if(!ast_test_flag(vmu, MVM_OPERATOR)) { 01456 cmd = ast_play_and_wait(chan, "vm-sorry"); 01457 break; 01458 } 01459 if (message_exists || recorded) { 01460 cmd = ast_play_and_wait(chan, "vm-saveoper"); 01461 if (!cmd) 01462 cmd = ast_waitfordigit(chan, 3000); 01463 if (cmd == '1') { 01464 ast_play_and_wait(chan, "vm-msgsaved"); 01465 cmd = '0'; 01466 } else { 01467 ast_play_and_wait(chan, "vm-deleted"); 01468 vm_delete(recordfile); 01469 cmd = '0'; 01470 } 01471 } 01472 return cmd; 01473 default: 01474 /* If the caller is an ouside caller, and the review option is enabled, 01475 allow them to review the message, but let the owner of the box review 01476 their OGM's */ 01477 if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW)) 01478 return cmd; 01479 if (message_exists) { 01480 cmd = ast_play_and_wait(chan, "vm-review"); 01481 } else { 01482 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01483 if (!cmd) 01484 cmd = ast_waitfordigit(chan, 600); 01485 } 01486 01487 if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) { 01488 cmd = ast_play_and_wait(chan, "vm-reachoper"); 01489 if (!cmd) 01490 cmd = ast_waitfordigit(chan, 600); 01491 } 01492 if (!cmd) 01493 cmd = ast_waitfordigit(chan, 6000); 01494 if (!cmd) { 01495 attempts++; 01496 } 01497 if (attempts > max_attempts) { 01498 cmd = 't'; 01499 } 01500 } 01501 } 01502 if (outsidecaller) 01503 ast_play_and_wait(chan, "vm-goodbye"); 01504 if (cmd == 't') 01505 cmd = 0; 01506 return cmd; 01507 }
| static void populate_defaults | ( | struct minivm_account * | vmu | ) | [static] |
Set default values for Mini-Voicemail users.
Definition at line 903 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 create_vmaccount(), find_user_realtime(), and mvm_user_alloc().
00904 { 00905 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00906 ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt)); 00907 vmu->volgain = global_volgain; 00908 }
| 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] |
Prepare for voicemail template by adding channel variables to the channel.
Definition at line 875 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 sendmail().
00876 { 00877 char callerid[256]; 00878 struct ast_variable *var; 00879 00880 if (!channel) { 00881 ast_log(LOG_ERROR, "No allocated channel, giving up...\n"); 00882 return; 00883 } 00884 00885 for (var = vmu->chanvars ; var ; var = var->next) { 00886 pbx_builtin_setvar_helper(channel, var->name, var->value); 00887 } 00888 00889 /* Prepare variables for substition in email body and subject */ 00890 pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname); 00891 pbx_builtin_setvar_helper(channel, "MVM_DUR", dur); 00892 pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain); 00893 pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username); 00894 pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller")); 00895 pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller")); 00896 pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller")); 00897 pbx_builtin_setvar_helper(channel, "MVM_DATE", date); 00898 if (!ast_strlen_zero(counter)) 00899 pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter); 00900 }
| static void queue_mwi_event | ( | const char * | mbx, | |
| const char * | ctx, | |||
| int | urgent, | |||
| int | new, | |||
| int | old | |||
| ) | [static] |
Queue a message waiting event.
Definition at line 1771 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_strlen_zero(), context, and mailbox.
Referenced by minivm_mwi_exec().
01772 { 01773 struct ast_event *event; 01774 char *mailbox, *context; 01775 01776 mailbox = ast_strdupa(mbx); 01777 context = ast_strdupa(ctx); 01778 if (ast_strlen_zero(context)) { 01779 context = "default"; 01780 } 01781 01782 if (!(event = ast_event_new(AST_EVENT_MWI, 01783 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 01784 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 01785 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 01786 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 01787 AST_EVENT_IE_END))) { 01788 return; 01789 } 01790 01791 ast_event_queue_and_cache(event); 01792 }
| static int reload | ( | void | ) | [static] |
Reload mini voicemail module.
Definition at line 3297 of file app_minivm.c.
References load_config().
03298 { 03299 return(load_config(1)); 03300 }
| static void run_externnotify | ( | struct ast_channel * | chan, | |
| struct minivm_account * | vmu | |||
| ) | [static] |
Run external notification for voicemail message.
Definition at line 1510 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 notify_new_message().
01511 { 01512 char arguments[BUFSIZ]; 01513 01514 if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify)) 01515 return; 01516 01517 snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&", 01518 ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify, 01519 vmu->username, vmu->domain, 01520 chan->cid.cid_name, chan->cid.cid_num); 01521 01522 ast_debug(1, "Executing: %s\n", arguments); 01523 ast_safe_system(arguments); 01524 }
| 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] |
Send voicemail with audio file as an attachment.
Definition at line 1027 of file app_minivm.c.
References ast_channel_alloc, ast_channel_free(), ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strftime(), ast_strlen_zero(), ast_tvnow(), base_encode(), minivm_account::domain, minivm_account::email, minivm_account::fullname, global_charset, global_mailcmd, LOG_WARNING, mailheader_quote(), MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_zone::name, option_debug, minivm_account::pager, pbx_substitute_variables_helper(), prep_email_sub_vars(), minivm_account::serveremail, minivm_zone::timezone, minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.
Referenced by notify_new_message().
01028 { 01029 FILE *p = NULL; 01030 int pfd; 01031 char email[256] = ""; 01032 char who[256] = ""; 01033 char date[256]; 01034 char bound[256]; 01035 char fname[PATH_MAX]; 01036 char dur[PATH_MAX]; 01037 char tmp[80] = "/tmp/astmail-XXXXXX"; 01038 char tmp2[PATH_MAX]; 01039 struct timeval now; 01040 struct ast_tm tm; 01041 struct minivm_zone *the_zone = NULL; 01042 int len_passdata; 01043 struct ast_channel *ast; 01044 char *finalfilename; 01045 char *passdata = NULL; 01046 char *passdata2 = NULL; 01047 char *fromaddress; 01048 char *fromemail; 01049 01050 if (type == MVM_MESSAGE_EMAIL) { 01051 if (vmu && !ast_strlen_zero(vmu->email)) { 01052 ast_copy_string(email, vmu->email, sizeof(email)); 01053 } else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain)) 01054 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 01055 } else if (type == MVM_MESSAGE_PAGE) { 01056 ast_copy_string(email, vmu->pager, sizeof(email)); 01057 } 01058 01059 if (ast_strlen_zero(email)) { 01060 ast_log(LOG_WARNING, "No address to send message to.\n"); 01061 return -1; 01062 } 01063 01064 ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name); 01065 01066 if (!strcmp(format, "wav49")) 01067 format = "WAV"; 01068 01069 01070 /* If we have a gain option, process it now with sox */ 01071 if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) { 01072 char newtmp[PATH_MAX]; 01073 char tmpcmd[PATH_MAX]; 01074 int tmpfd; 01075 01076 ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp)); 01077 ast_debug(3, "newtmp: %s\n", newtmp); 01078 tmpfd = mkstemp(newtmp); 01079 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format); 01080 ast_safe_system(tmpcmd); 01081 finalfilename = newtmp; 01082 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username); 01083 } else { 01084 finalfilename = ast_strdupa(filename); 01085 } 01086 01087 /* Create file name */ 01088 snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format); 01089 01090 if (template->attachment) 01091 ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail); 01092 01093 /* Make a temporary file instead of piping directly to sendmail, in case the mail 01094 command hangs */ 01095 pfd = mkstemp(tmp); 01096 if (pfd > -1) { 01097 p = fdopen(pfd, "w"); 01098 if (!p) { 01099 close(pfd); 01100 pfd = -1; 01101 } 01102 ast_debug(1, "Opening temp file for e-mail: %s\n", tmp); 01103 } 01104 if (!p) { 01105 ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp); 01106 return -1; 01107 } 01108 /* Allocate channel used for chanvar substitution */ 01109 ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 01110 01111 01112 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 01113 01114 /* Does this user have a timezone specified? */ 01115 if (!ast_strlen_zero(vmu->zonetag)) { 01116 /* Find the zone in the list */ 01117 struct minivm_zone *z; 01118 AST_LIST_LOCK(&minivm_zones); 01119 AST_LIST_TRAVERSE(&minivm_zones, z, list) { 01120 if (strcmp(z->name, vmu->zonetag)) 01121 continue; 01122 the_zone = z; 01123 } 01124 AST_LIST_UNLOCK(&minivm_zones); 01125 } 01126 01127 now = ast_tvnow(); 01128 ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL); 01129 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm); 01130 01131 /* Start printing the email to the temporary file */ 01132 fprintf(p, "Date: %s\n", date); 01133 01134 /* Set date format for voicemail mail */ 01135 ast_strftime(date, sizeof(date), template->dateformat, &tm); 01136 01137 01138 /* Populate channel with channel variables for substitution */ 01139 prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter); 01140 01141 /* Find email address to use */ 01142 /* If there's a server e-mail adress in the account, user that, othterwise template */ 01143 fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail; 01144 01145 /* Find name to user for server e-mail */ 01146 fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress; 01147 01148 /* If needed, add hostname as domain */ 01149 if (ast_strlen_zero(fromemail)) 01150 fromemail = "asterisk"; 01151 01152 if (strchr(fromemail, '@')) 01153 ast_copy_string(who, fromemail, sizeof(who)); 01154 else { 01155 char host[MAXHOSTNAMELEN]; 01156 gethostname(host, sizeof(host)-1); 01157 snprintf(who, sizeof(who), "%s@%s", fromemail, host); 01158 } 01159 01160 if (ast_strlen_zero(fromaddress)) { 01161 fprintf(p, "From: Asterisk PBX <%s>\n", who); 01162 } else { 01163 /* Allocate a buffer big enough for variable substitution */ 01164 int vmlen = strlen(fromaddress) * 3 + 200; 01165 01166 ast_debug(4, "Fromaddress template: %s\n", fromaddress); 01167 if ((passdata = alloca(vmlen))) { 01168 pbx_substitute_variables_helper(ast, fromaddress, passdata, vmlen); 01169 len_passdata = strlen(passdata) * 2 + 3; 01170 passdata2 = alloca(len_passdata); 01171 fprintf(p, "From: %s <%s>\n", mailheader_quote(passdata, passdata2, len_passdata), who); 01172 } else { 01173 ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); 01174 fclose(p); 01175 return -1; 01176 } 01177 } 01178 ast_debug(4, "Fromstring now: %s\n", ast_strlen_zero(passdata) ? "-default-" : passdata); 01179 01180 fprintf(p, "Message-ID: <Asterisk-%d-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who); 01181 len_passdata = strlen(vmu->fullname) * 2 + 3; 01182 passdata2 = alloca(len_passdata); 01183 if (!ast_strlen_zero(vmu->email)) 01184 fprintf(p, "To: %s <%s>\n", mailheader_quote(vmu->fullname, passdata2, len_passdata), vmu->email); 01185 else 01186 fprintf(p, "To: %s <%s@%s>\n", mailheader_quote(vmu->fullname, passdata2, len_passdata), vmu->username, vmu->domain); 01187 01188 if (!ast_strlen_zero(template->subject)) { 01189 char *pass_data; 01190 int vmlen = strlen(template->subject) * 3 + 200; 01191 if ((pass_data = alloca(vmlen))) { 01192 pbx_substitute_variables_helper(ast, template->subject, pass_data, vmlen); 01193 fprintf(p, "Subject: %s\n", pass_data); 01194 } else { 01195 ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); 01196 fclose(p); 01197 return -1; 01198 } 01199 01200 ast_debug(4, "Subject now: %s\n", pass_data); 01201 01202 } else { 01203 fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain); 01204 ast_debug(1, "Using default subject for this email \n"); 01205 } 01206 01207 01208 if (option_debug > 2) 01209 fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain); 01210 fprintf(p, "MIME-Version: 1.0\n"); 01211 01212 /* Something unique. */ 01213 snprintf(bound, sizeof(bound), "voicemail_%s%d%d", vmu->username, (int)getpid(), (unsigned int)ast_random()); 01214 01215 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound); 01216 01217 fprintf(p, "--%s\n", bound); 01218 fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", global_charset); 01219 if (!ast_strlen_zero(template->body)) { 01220 char *pass_data; 01221 int vmlen = strlen(template->body)*3 + 200; 01222 if ((pass_data = alloca(vmlen))) { 01223 pbx_substitute_variables_helper(ast, template->body, pass_data, vmlen); 01224 ast_debug(3, "Message now: %s\n-----\n", pass_data); 01225 fprintf(p, "%s\n", pass_data); 01226 } else 01227 ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); 01228 } else { 01229 fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n" 01230 01231 "in mailbox %s from %s, on %s so you might\n" 01232 "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, 01233 dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 01234 ast_debug(3, "Using default message body (no template)\n-----\n"); 01235 } 01236 /* Eww. We want formats to tell us their own MIME type */ 01237 if (template->attachment) { 01238 char *ctype = "audio/x-"; 01239 ast_debug(3, "Attaching file to message: %s\n", fname); 01240 if (!strcasecmp(format, "ogg")) 01241 ctype = "application/"; 01242 01243 fprintf(p, "--%s\n", bound); 01244 fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format); 01245 fprintf(p, "Content-Transfer-Encoding: base64\n"); 01246 fprintf(p, "Content-Description: Voicemail sound attachment.\n"); 01247 fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format); 01248 01249 base_encode(fname, p); 01250 fprintf(p, "\n\n--%s--\n.\n", bound); 01251 } 01252 fclose(p); 01253 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp); 01254 ast_safe_system(tmp2); 01255 ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : ""); 01256 ast_debug(3, "Actual command used: %s\n", tmp2); 01257 if (ast) 01258 ast_channel_free(ast); 01259 return 0; 01260 }
| static int timezone_add | ( | const char * | zonename, | |
| const char * | config | |||
| ) | [static] |
Add time zone to memory list.
Definition at line 2411 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(), global_stats, LOG_WARNING, minivm_zone::msg_format, minivm_zone::name, minivm_zone::timezone, and minivm_stats::timezones.
Referenced by load_config().
02412 { 02413 struct minivm_zone *newzone; 02414 char *msg_format, *timezone_str; 02415 02416 newzone = ast_calloc(1, sizeof(*newzone)); 02417 if (newzone == NULL) 02418 return 0; 02419 02420 msg_format = ast_strdupa(config); 02421 if (msg_format == NULL) { 02422 ast_log(LOG_WARNING, "Out of memory.\n"); 02423 ast_free(newzone); 02424 return 0; 02425 } 02426 02427 timezone_str = strsep(&msg_format, "|"); 02428 if (!msg_format) { 02429 ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename); 02430 ast_free(newzone); 02431 return 0; 02432 } 02433 02434 ast_copy_string(newzone->name, zonename, sizeof(newzone->name)); 02435 ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone)); 02436 ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format)); 02437 02438 AST_LIST_LOCK(&minivm_zones); 02439 AST_LIST_INSERT_TAIL(&minivm_zones, newzone, list); 02440 AST_LIST_UNLOCK(&minivm_zones); 02441 02442 global_stats.timezones++; 02443 02444 return 0; 02445 }
| static void timezone_destroy_list | ( | void | ) | [static] |
Clear list of timezones.
Definition at line 2399 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().
02400 { 02401 struct minivm_zone *this; 02402 02403 AST_LIST_LOCK(&minivm_zones); 02404 while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list))) 02405 free_zone(this); 02406 02407 AST_LIST_UNLOCK(&minivm_zones); 02408 }
| static int unload_module | ( | void | ) | [static] |
Unload mini voicemail module.
Definition at line 3323 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().
03324 { 03325 int res; 03326 03327 res = ast_unregister_application(app_minivm_record); 03328 res |= ast_unregister_application(app_minivm_greet); 03329 res |= ast_unregister_application(app_minivm_notify); 03330 res |= ast_unregister_application(app_minivm_delete); 03331 res |= ast_unregister_application(app_minivm_accmess); 03332 res |= ast_unregister_application(app_minivm_mwi); 03333 03334 ast_cli_unregister_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03335 ast_custom_function_unregister(&minivm_account_function); 03336 ast_custom_function_unregister(&minivm_counter_function); 03337 03338 message_destroy_list(); /* Destroy list of voicemail message templates */ 03339 timezone_destroy_list(); /* Destroy list of timezones */ 03340 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 03341 03342 return res; 03343 }
| static int vm_delete | ( | char * | file | ) | [static] |
Delete media files and attribute file.
Definition at line 1365 of file app_minivm.c.
References ast_debug, and ast_filedelete().
Referenced by minivm_delete_exec(), and play_record_review().
01366 { 01367 int res; 01368 01369 ast_debug(1, "Deleting voicemail file %s\n", file); 01370 01371 res = unlink(file); /* Remove the meta data file */ 01372 res |= ast_filedelete(file, NULL); /* remove the media file */ 01373 return res; 01374 }
| 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 3019 of file app_minivm.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by access_counter_file().
03020 { 03021 switch (ast_lock_path(path)) { 03022 case AST_LOCK_TIMEOUT: 03023 return -1; 03024 default: 03025 return 0; 03026 } 03027 }
| static void vmaccounts_destroy_list | ( | void | ) | [static] |
Clear list of users.
Definition at line 944 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().
00945 { 00946 struct minivm_account *this; 00947 AST_LIST_LOCK(&minivm_accounts); 00948 while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list))) 00949 ast_free(this); 00950 AST_LIST_UNLOCK(&minivm_accounts); 00951 }
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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3350 of file app_minivm.c.
char* app_minivm_accmess = "MinivmAccMess" [static] |
Definition at line 453 of file app_minivm.c.
char* app_minivm_delete = "MinivmDelete" [static] |
Definition at line 452 of file app_minivm.c.
char* app_minivm_greet = "MinivmGreet" [static] |
Definition at line 450 of file app_minivm.c.
char* app_minivm_mwi = "MinivmMWI" [static] |
Definition at line 454 of file app_minivm.c.
char* app_minivm_notify = "MinivmNotify" [static] |
Definition at line 451 of file app_minivm.c.
char* app_minivm_record = "MinivmRecord" [static] |
Definition at line 449 of file app_minivm.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 3350 of file app_minivm.c.
struct ast_cli_entry cli_minivm[] [static] |
CLI commands for Mini-voicemail.
Definition at line 3220 of file app_minivm.c.
Referenced by load_module(), and unload_module().
char default_vmformat[80] [static] |
Definition at line 587 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_charset[32] [static] |
Global charset in messages
Definition at line 591 of file app_minivm.c.
Referenced by load_config(), and sendmail().
char global_externnotify[160] [static] |
External notification application
Definition at line 585 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 586 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 584 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 582 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 581 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
int global_saydurationminfo [static] |
Definition at line 590 of file app_minivm.c.
Referenced by load_config().
int global_silencethreshold = 128 [static] |
Definition at line 583 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 572 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 580 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 579 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 593 of file app_minivm.c.
Referenced by populate_defaults().
struct ast_flags globalflags = {0} [static] |
Global voicemail flags
Definition at line 589 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and populate_defaults().
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] |
Definition at line 484 of file app_minivm.c.
Referenced by minivm_accmess_exec().
struct ast_custom_function minivm_account_function [static] |
Definition at line 3248 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 477 of file app_minivm.c.
Referenced by minivm_greet_exec(), and minivm_record_exec().
struct ast_custom_function minivm_counter_function [static] |
Definition at line 3229 of file app_minivm.c.
Referenced by load_module(), and unload_module().
| enum { ... } minivm_option_args |
| enum { ... } minivm_option_flags |
ast_mutex_t minivmlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Lock to protect voicemail system
Definition at line 574 of file app_minivm.c.
Referenced by load_config().
| FILE* minivmlogfile |
The minivm log file
Definition at line 577 of file app_minivm.c.
Referenced by leave_voicemail(), and load_config().
ast_mutex_t minivmloglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Lock to protect voicemail system log file
Definition at line 575 of file app_minivm.c.
Referenced by leave_voicemail().
char MVM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 446 of file app_minivm.c.
1.6.2