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