MiniVoiceMail - A Minimal Voicemail System for Asterisk. More...
#include "asterisk.h"#include <ctype.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/mman.h>#include <time.h>#include <dirent.h>#include <locale.h>#include "asterisk/paths.h"#include "asterisk/lock.h"#include "asterisk/file.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/config.h"#include "asterisk/say.h"#include "asterisk/module.h"#include "asterisk/app.h"#include "asterisk/manager.h"#include "asterisk/dsp.h"#include "asterisk/localtime.h"#include "asterisk/cli.h"#include "asterisk/utils.h"#include "asterisk/linkedlists.h"#include "asterisk/callerid.h"#include "asterisk/event.h"
Go to the source code of this file.
Data Structures | |
| struct | b64_baseio |
| Structure for base64 encoding. More... | |
| struct | leave_vm_options |
| Options for leaving voicemail with the voicemail() application. More... | |
| struct | message_templates |
| The list of e-mail templates. More... | |
| struct | minivm_account |
| Structure for linked list of Mini-Voicemail users: minivm_accounts. More... | |
| struct | minivm_accounts |
| The list of e-mail accounts. More... | |
| struct | minivm_stats |
| Structure for gathering statistics. More... | |
| struct | minivm_template |
| Linked list of e-mail templates in various languages These are used as templates for e-mails, pager messages and jabber messages message_templates. More... | |
| struct | minivm_zone |
| Voicemail time zones. More... | |
| struct | minivm_zones |
| The list of e-mail time zones. More... | |
Defines | |
| #define | ASTERISK_USERNAME "asterisk" |
| #define | B64_BASELINELEN 72 |
| #define | B64_BASEMAXINLINE 256 |
| #define | DEFAULT_CHARSET "ISO-8859-1" |
| #define | DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
| Default dateformat, can be overridden in configuration file. | |
| #define | EOL "\r\n" |
| #define | ERROR_LOCK_PATH -100 |
| #define | FALSE 0 |
| #define | HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" |
| #define | HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
| #define | HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" |
| #define | MAX_DATETIME_FORMAT 512 |
| #define | MAX_NUM_CID_CONTEXTS 10 |
| #define | MVM_ALLOCED (1 << 13) |
| #define | MVM_ENVELOPE (1 << 4) |
| #define | MVM_OPERATOR (1 << 1) |
| #define | MVM_PBXSKIP (1 << 9) |
| #define | MVM_REALTIME (1 << 2) |
| #define | MVM_REVIEW (1 << 0) |
| #define | MVM_SVMAIL (1 << 3) |
| #define | SENDMAIL "/usr/sbin/sendmail -t" |
| Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf. | |
| #define | SOUND_INTRO "vm-intro" |
| #define | TRUE 1 |
| #define | VOICEMAIL_CONFIG "minivm.conf" |
| #define | VOICEMAIL_DIR_MODE 0700 |
Enumerations | |
| enum | { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_TEMP_GREETING = (1 << 3), OPT_NAME_GREETING = (1 << 4), OPT_RECORDGAIN = (1 << 5) } |
| enum | { OPT_ARG_RECORDGAIN = 0, OPT_ARG_ARRAY_SIZE = 1 } |
| enum | mvm_messagetype { MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE } |
Message types for notification. More... | |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | access_counter_file (char *directory, char *countername, int value, int operand) |
| Access counter file, lock directory, read and possibly write it again changed. | |
| static int | apply_general_options (struct ast_variable *var) |
| Apply general configuration options. | |
| static int | b64_inbuf (struct b64_baseio *bio, FILE *fi) |
| read buffer from file (base64 conversion) | |
| static int | b64_inchar (struct b64_baseio *bio, FILE *fi) |
| read character from file to buffer (base64 conversion) | |
| static int | b64_ochar (struct b64_baseio *bio, int c, FILE *so) |
| write buffer to file (base64 conversion) | |
| static int | base_encode (char *filename, FILE *so) |
| Encode file to base64 encoding for email attachment (base64 conversion) | |
| static int | check_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
| Checks if directory exists. Does not create directory, but builds string in dest. | |
| static char * | complete_minivm_show_users (const char *line, const char *word, int pos, int state) |
| static int | create_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
| basically mkdir -p $dest/$domain/$username/$folder | |
| static int | create_vmaccount (char *name, struct ast_variable *var, int realtime) |
| Append new mailbox to mailbox list from configuration file. | |
| static struct minivm_account * | find_account (const char *domain, const char *username, int createtemp) |
| Find user from static memory object list. | |
| static struct minivm_account * | find_user_realtime (const char *domain, const char *username) |
| Find user in realtime storage Returns pointer to minivm_account structure. | |
| static void | free_user (struct minivm_account *vmu) |
| Free user structure - if it's allocated. | |
| static void | free_zone (struct minivm_zone *z) |
| Free Mini Voicemail timezone. | |
| static int | get_date (char *s, int len) |
| static char * | handle_minivm_list_templates (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI routine for listing templates. | |
| static char * | handle_minivm_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Reload cofiguration. | |
| static char * | handle_minivm_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI Show settings. | |
| static char * | handle_minivm_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show stats. | |
| static char * | handle_minivm_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command to list voicemail accounts. | |
| static char * | handle_minivm_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show a list of voicemail zones in the CLI. | |
| static int | invent_message (struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes) |
| Play intro message before recording voicemail. | |
| static int | leave_voicemail (struct ast_channel *chan, char *username, struct leave_vm_options *options) |
| Record voicemail message, store into file prepared for sending e-mail. | |
| static int | load_config (int reload) |
| Load minivoicemail configuration. | |
| static int | load_module (void) |
| Load mini voicemail module. | |
| static char * | mailheader_quote (const char *from, char *to, size_t len) |
| Fix quote of mail headers for non-ascii characters. | |
| static int | make_dir (char *dest, int len, const char *domain, const char *username, const char *folder) |
| Create directory based on components. | |
| static void | message_destroy_list (void) |
| Clear list of templates. | |
| static int | message_template_build (const char *name, struct ast_variable *var) |
| Build message template from configuration. | |
| static struct minivm_template * | message_template_create (const char *name) |
| Create message template. | |
| static struct minivm_template * | message_template_find (const char *name) |
| Find named template. | |
| static void | message_template_free (struct minivm_template *template) |
| Release memory allocated by message template. | |
| static char * | message_template_parse_emailbody (const char *configuration) |
| Parse emailbody template from configuration file. | |
| static char * | message_template_parse_filebody (const char *filename) |
| Read message template from file. | |
| static int | minivm_accmess_exec (struct ast_channel *chan, void *data) |
| Record specific messages for voicemail account. | |
| static int | minivm_account_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${MINIVMACCOUNT()} Dialplan function - reads account data | |
| static int | minivm_counter_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| ${MINIVMCOUNTER()} Dialplan function - read counters | |
| static int | minivm_counter_func_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
| ${MINIVMCOUNTER()} Dialplan function - changes counter data | |
| static int | minivm_delete_exec (struct ast_channel *chan, void *data) |
| Dialplan application to delete voicemail. | |
| static int | minivm_greet_exec (struct ast_channel *chan, void *data) |
| Play voicemail prompts - either generic or user specific. | |
| static int | minivm_mwi_exec (struct ast_channel *chan, void *data) |
| Send MWI using interal Asterisk event subsystem. | |
| static int | minivm_notify_exec (struct ast_channel *chan, void *data) |
| Notify voicemail account owners - either generic template or user specific. | |
| static int | minivm_record_exec (struct ast_channel *chan, void *data) |
| Dialplan function to record voicemail. | |
| static struct minivm_account * | mvm_user_alloc (void) |
| Allocate new vm user and set default values. | |
| static int | notify_new_message (struct ast_channel *chan, const char *templatename, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname) |
| Send message to voicemail account owner. | |
| static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct minivm_account *vmu, int *duration, const char *unlockdir, signed char record_gain) |
| Record voicemail message & let caller review or re-record it, or set options if applicable. | |
| static void | populate_defaults (struct minivm_account *vmu) |
| Set default values for Mini-Voicemail users. | |
| static void | prep_email_sub_vars (struct ast_channel *channel, const struct minivm_account *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date, const char *counter) |
| Prepare for voicemail template by adding channel variables to the channel. | |
| static void | queue_mwi_event (const char *mbx, const char *ctx, int urgent, int new, int old) |
| Queue a message waiting event. | |
| static int | reload (void) |
| Reload mini voicemail module. | |
| static void | run_externnotify (struct ast_channel *chan, struct minivm_account *vmu) |
| Run external notification for voicemail message. | |
| static int | sendmail (struct minivm_template *template, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type, const char *counter) |
| Send voicemail with audio file as an attachment. | |
| static int | timezone_add (const char *zonename, const char *config) |
| Add time zone to memory list. | |
| static void | timezone_destroy_list (void) |
| Clear list of timezones. | |
| static int | unload_module (void) |
| Unload mini voicemail module. | |
| static int | vm_delete (char *file) |
| Delete media files and attribute file. | |
| static int | vm_lock_path (const char *path) |
| lock directory | |
| static void | vmaccounts_destroy_list (void) |
| Clear list of users. | |
Variables | |
| static struct ast_module_info __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| static char * | app_minivm_accmess = "MinivmAccMess" |
| static char * | app_minivm_delete = "MinivmDelete" |
| static char * | app_minivm_greet = "MinivmGreet" |
| static char * | app_minivm_mwi = "MinivmMWI" |
| static char * | app_minivm_notify = "MinivmNotify" |
| static char * | app_minivm_record = "MinivmRecord" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_cli_entry | cli_minivm [] |
| CLI commands for Mini-voicemail. | |
| static char | default_vmformat [80] |
| static char | global_charset [32] |
| static char | global_externnotify [160] |
| static char | global_logfile [PATH_MAX] |
| static char | global_mailcmd [160] |
| static int | global_maxgreet |
| static int | global_maxsilence |
| static int | global_saydurationminfo |
| static int | global_silencethreshold = 128 |
| static struct minivm_stats | global_stats |
| Statistics for voicemail. | |
| static int | global_vmmaxmessage |
| static int | global_vmminmessage |
| static double | global_volgain |
| static struct ast_flags | globalflags = {0} |
| static struct message_templates | message_templates |
| 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 minivm_accounts | minivm_accounts |
| static struct ast_app_option | minivm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 },} |
| static struct ast_custom_function | minivm_counter_function |
| enum { ... } | minivm_option_args |
| enum { ... } | minivm_option_flags |
| static struct minivm_zones | minivm_zones |
| static ast_mutex_t | minivmlock = AST_MUTEX_INIT_VALUE |
| FILE * | minivmlogfile |
| static ast_mutex_t | minivmloglock = AST_MUTEX_INIT_VALUE |
| static char | MVM_SPOOL_DIR [PATH_MAX] |
MiniVoiceMail - A Minimal Voicemail System for Asterisk.
A voicemail system in small building blocks, working together based on the Comedian Mail voicemail system (app_voicemail.c).
Definition in file app_minivm.c.
| #define ASTERISK_USERNAME "asterisk" |
Default username for sending mail is asterisk@localhost
Definition at line 437 of file app_minivm.c.
| #define B64_BASELINELEN 72 |
Line length for Base 64 endoded messages
Definition at line 427 of file app_minivm.c.
Referenced by b64_ochar().
| #define B64_BASEMAXINLINE 256 |
Buffer size for Base 64 attachment encoding
Definition at line 426 of file app_minivm.c.
Referenced by b64_inbuf(), and base_encode().
| #define DEFAULT_CHARSET "ISO-8859-1" |
Definition at line 597 of file app_minivm.c.
Referenced by message_template_create().
| #define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
Default dateformat, can be overridden in configuration file.
Definition at line 596 of file app_minivm.c.
Referenced by message_template_create().
| #define EOL "\r\n" |
Definition at line 428 of file app_minivm.c.
Referenced by b64_ochar(), and base_encode().
| #define ERROR_LOCK_PATH -100 |
Definition at line 433 of file app_minivm.c.
Referenced by minivm_record_exec().
| #define FALSE 0 |
Definition at line 409 of file app_minivm.c.
Referenced by ast_tzset(), check_dirpath(), invent_message(), load_config(), minivm_accmess_exec(), minivm_counter_func_read(), minivm_counter_func_write(), rcvfax_exec(), show_console(), sndfax_exec(), time1(), time2(), time2sub(), transmit_audio(), transmit_t38(), tzload(), and tzparse().
| #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" |
Referenced by handle_minivm_show_users().
| #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_minivm_show_zones().
| #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" |
Referenced by handle_minivm_list_templates().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 430 of file app_minivm.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 431 of file app_minivm.c.
| #define MVM_ALLOCED (1 << 13) |
Definition at line 419 of file app_minivm.c.
Referenced by find_account(), leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), and minivm_notify_exec().
| #define MVM_ENVELOPE (1 << 4) |
Definition at line 417 of file app_minivm.c.
| #define MVM_OPERATOR (1 << 1) |
Operator exit during voicemail recording
Definition at line 414 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), minivm_greet_exec(), and play_record_review().
| #define MVM_PBXSKIP (1 << 9) |
Definition at line 418 of file app_minivm.c.
| #define MVM_REALTIME (1 << 2) |
This user is a realtime account
Definition at line 415 of file app_minivm.c.
| #define MVM_REVIEW (1 << 0) |
Review message
Definition at line 413 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
| #define MVM_SVMAIL (1 << 3) |
Definition at line 416 of file app_minivm.c.
| #define SENDMAIL "/usr/sbin/sendmail -t" |
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
Definition at line 423 of file app_minivm.c.
Referenced by load_config().
| #define SOUND_INTRO "vm-intro" |
Definition at line 425 of file app_minivm.c.
Referenced by minivm_greet_exec().
| #define TRUE 1 |
Definition at line 406 of file app_minivm.c.
Referenced by ast_tzset(), check_dirpath(), cli_activate(), find_account(), find_user_realtime(), gmtload(), leave_voicemail(), load_config(), message_template_create(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), rcvfax_exec(), show_console(), sndfax_exec(), time1(), time2(), time2sub(), transmit_audio(), transmit_t38(), tzload(), and tzparse().
| #define VOICEMAIL_CONFIG "minivm.conf" |
Definition at line 436 of file app_minivm.c.
Referenced by load_config().
| #define VOICEMAIL_DIR_MODE 0700 |
Definition at line 434 of file app_minivm.c.
| anonymous enum |
| OPT_SILENT | |
| OPT_BUSY_GREETING | |
| OPT_UNAVAIL_GREETING | |
| OPT_TEMP_GREETING | |
| OPT_NAME_GREETING | |
| OPT_RECORDGAIN |
Definition at line 458 of file app_minivm.c.
{
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),
} minivm_option_flags;
| anonymous enum |
Definition at line 467 of file app_minivm.c.
{
OPT_ARG_RECORDGAIN = 0,
OPT_ARG_ARRAY_SIZE = 1,
} minivm_option_args;
| enum mvm_messagetype |
Message types for notification.
Definition at line 440 of file app_minivm.c.
{
MVM_MESSAGE_EMAIL,
MVM_MESSAGE_PAGE
/* For trunk: MVM_MESSAGE_JABBER, */
};
| static void __reg_module | ( | void | ) | [static] |
Definition at line 3350 of file app_minivm.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 3350 of file app_minivm.c.
| static int access_counter_file | ( | char * | directory, |
| char * | countername, | ||
| int | value, | ||
| int | operand | ||
| ) | [static] |
Access counter file, lock directory, read and possibly write it again changed.
| directory | Directory to crate file in |
| countername | filename |
| value | If set to zero, we only read the variable |
| operand | 0 to read, 1 to set new value, 2 to change |
Definition at line 3036 of file app_minivm.c.
References ast_debug, ast_log(), ast_unlock_path(), errno, LOG_ERROR, and vm_lock_path().
Referenced by minivm_counter_func_read(), and minivm_counter_func_write().
{
char filename[BUFSIZ];
char readbuf[BUFSIZ];
FILE *counterfile;
int old = 0, counter = 0;
/* Lock directory */
if (vm_lock_path(directory)) {
return -1; /* Could not lock directory */
}
snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername);
if (operand != 1) {
counterfile = fopen(filename, "r");
if (counterfile) {
if(fgets(readbuf, sizeof(readbuf), counterfile)) {
ast_debug(3, "Read this string from counter file: %s\n", readbuf);
old = counter = atoi(readbuf);
}
fclose(counterfile);
}
}
switch (operand) {
case 0: /* Read only */
ast_unlock_path(directory);
ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter);
return counter;
break;
case 1: /* Set new value */
counter = value;
break;
case 2: /* Change value */
counter += value;
if (counter < 0) /* Don't allow counters to fall below zero */
counter = 0;
break;
}
/* Now, write the new value to the file */
counterfile = fopen(filename, "w");
if (!counterfile) {
ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno));
ast_unlock_path(directory);
return -1; /* Could not open file for writing */
}
fprintf(counterfile, "%d\n\n", counter);
fclose(counterfile);
ast_unlock_path(directory);
ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter);
return counter;
}
| static int apply_general_options | ( | struct ast_variable * | var | ) | [static] |
Apply general configuration options.
Definition at line 2515 of file app_minivm.c.
References ast_config_AST_LOG_DIR, ast_copy_string(), ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), default_vmformat, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by load_config().
{
int error = 0;
while (var) {
/* Mail command */
if (!strcmp(var->name, "mailcmd")) {
ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */
} else if (!strcmp(var->name, "maxgreet")) {
global_maxgreet = atoi(var->value);
} else if (!strcmp(var->name, "maxsilence")) {
global_maxsilence = atoi(var->value);
if (global_maxsilence > 0)
global_maxsilence *= 1000;
} else if (!strcmp(var->name, "logfile")) {
if (!ast_strlen_zero(var->value) ) {
if(*(var->value) == '/')
ast_copy_string(global_logfile, var->value, sizeof(global_logfile));
else
snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value);
}
} else if (!strcmp(var->name, "externnotify")) {
/* External voicemail notify application */
ast_copy_string(global_externnotify, var->value, sizeof(global_externnotify));
} else if (!strcmp(var->name, "silencetreshold")) {
/* Silence treshold */
global_silencethreshold = atoi(var->value);
} else if (!strcmp(var->name, "maxmessage")) {
int x;
if (sscanf(var->value, "%30d", &x) == 1) {
global_vmmaxmessage = x;
} else {
error ++;
ast_log(LOG_WARNING, "Invalid max message time length\n");
}
} else if (!strcmp(var->name, "minmessage")) {
int x;
if (sscanf(var->value, "%30d", &x) == 1) {
global_vmminmessage = x;
if (global_maxsilence <= global_vmminmessage)
ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
} else {
error ++;
ast_log(LOG_WARNING, "Invalid min message time length\n");
}
} else if (!strcmp(var->name, "format")) {
ast_copy_string(default_vmformat, var->value, sizeof(default_vmformat));
} else if (!strcmp(var->name, "review")) {
ast_set2_flag((&globalflags), ast_true(var->value), MVM_REVIEW);
} else if (!strcmp(var->name, "operator")) {
ast_set2_flag((&globalflags), ast_true(var->value), MVM_OPERATOR);
}
var = var->next;
}
return error;
}
| static int b64_inbuf | ( | struct b64_baseio * | bio, |
| FILE * | fi | ||
| ) | [static] |
read buffer from file (base64 conversion)
Definition at line 729 of file app_minivm.c.
References b64_baseio::ateof, B64_BASEMAXINLINE, b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by b64_inchar().
| static int b64_inchar | ( | struct b64_baseio * | bio, |
| FILE * | fi | ||
| ) | [static] |
read character from file to buffer (base64 conversion)
Definition at line 751 of file app_minivm.c.
References b64_inbuf(), b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by base_encode().
| static int b64_ochar | ( | struct b64_baseio * | bio, |
| int | c, | ||
| FILE * | so | ||
| ) | [static] |
write buffer to file (base64 conversion)
Definition at line 762 of file app_minivm.c.
References B64_BASELINELEN, EOL, and b64_baseio::linelength.
Referenced by base_encode().
{
if (bio->linelength >= B64_BASELINELEN) {
if (fputs(EOL,so) == EOF)
return -1;
bio->linelength= 0;
}
if (putc(((unsigned char) c), so) == EOF)
return -1;
bio->linelength++;
return 1;
}
| static int base_encode | ( | char * | filename, |
| FILE * | so | ||
| ) | [static] |
Encode file to base64 encoding for email attachment (base64 conversion)
Definition at line 780 of file app_minivm.c.
References ast_log(), B64_BASEMAXINLINE, b64_inchar(), b64_ochar(), EOL, errno, b64_baseio::iocp, and LOG_WARNING.
Referenced by sendmail().
{
unsigned char dtable[B64_BASEMAXINLINE];
int i,hiteof= 0;
FILE *fi;
struct b64_baseio bio;
memset(&bio, 0, sizeof(bio));
bio.iocp = B64_BASEMAXINLINE;
if (!(fi = fopen(filename, "rb"))) {
ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
return -1;
}
for (i= 0; i<9; i++) {
dtable[i]= 'A'+i;
dtable[i+9]= 'J'+i;
dtable[26+i]= 'a'+i;
dtable[26+i+9]= 'j'+i;
}
for (i= 0; i < 8; i++) {
dtable[i+18]= 'S'+i;
dtable[26+i+18]= 's'+i;
}
for (i= 0; i < 10; i++) {
dtable[52+i]= '0'+i;
}
dtable[62]= '+';
dtable[63]= '/';
while (!hiteof){
unsigned char igroup[3], ogroup[4];
int c,n;
igroup[0]= igroup[1]= igroup[2]= 0;
for (n= 0; n < 3; n++) {
if ((c = b64_inchar(&bio, fi)) == EOF) {
hiteof= 1;
break;
}
igroup[n]= (unsigned char)c;
}
if (n> 0) {
ogroup[0]= dtable[igroup[0]>>2];
ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)];
ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)];
ogroup[3]= dtable[igroup[2]&0x3F];
if (n<3) {
ogroup[3]= '=';
if (n<2)
ogroup[2]= '=';
}
for (i= 0;i<4;i++)
b64_ochar(&bio, ogroup[i], so);
}
}
/* Put end of line - line feed */
if (fputs(EOL, so) == EOF)
return 0;
fclose(fi);
return 1;
}
| static int check_dirpath | ( | char * | dest, |
| int | len, | ||
| char * | domain, | ||
| char * | username, | ||
| char * | folder | ||
| ) | [static] |
Checks if directory exists. Does not create directory, but builds string in dest.
| dest | String. base directory. |
| len | Int. Length base directory string. |
| domain | String. Ignored if is null or empty string. |
| username | String. Ignored if is null or empty string. |
| folder | String. Ignored if is null or empty string. |
Definition at line 1276 of file app_minivm.c.
References FALSE, make_dir(), and TRUE.
Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().
| static char* complete_minivm_show_users | ( | const char * | line, |
| const char * | word, | ||
| int | pos, | ||
| int | state | ||
| ) | [static] |
Definition at line 2755 of file app_minivm.c.
References AST_LIST_TRAVERSE, ast_strdup, and minivm_account::domain.
Referenced by handle_minivm_show_users().
{
int which = 0;
int wordlen;
struct minivm_account *vmu;
const char *domain = "";
/* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */
if (pos > 4)
return NULL;
if (pos == 3)
return (state == 0) ? ast_strdup("for") : NULL;
wordlen = strlen(word);
AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) {
if (!strncasecmp(word, vmu->domain, wordlen)) {
if (domain && strcmp(domain, vmu->domain) && ++which > state)
return ast_strdup(vmu->domain);
/* ignore repeated domains ? */
domain = vmu->domain;
}
}
return NULL;
}
| static int create_dirpath | ( | char * | dest, |
| int | len, | ||
| char * | domain, | ||
| char * | username, | ||
| char * | folder | ||
| ) | [static] |
basically mkdir -p $dest/$domain/$username/$folder
| dest | String. base directory. |
| len | Length of directory string |
| domain | String. Ignored if is null or empty string. |
| folder | String. Ignored if is null or empty string. |
| username | String. Ignored if is null or empty string. |
Definition at line 1294 of file app_minivm.c.
References ast_debug, ast_log(), ast_mkdir(), LOG_WARNING, and make_dir().
Referenced by leave_voicemail(), minivm_counter_func_read(), and minivm_counter_func_write().
| static int create_vmaccount | ( | char * | name, |
| struct ast_variable * | var, | ||
| int | realtime | ||
| ) | [static] |
Append new mailbox to mailbox list from configuration file.
Definition at line 2299 of file app_minivm.c.
References minivm_account::accountcode, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_new(), minivm_account::chanvars, minivm_account::domain, minivm_account::email, minivm_account::etemplate, minivm_account::externnotify, minivm_account::fullname, global_stats, minivm_account::language, LOG_ERROR, ast_variable::name, ast_variable::next, minivm_account::pager, minivm_account::pincode, populate_defaults(), minivm_account::ptemplate, minivm_account::serveremail, minivm_account::username, ast_variable::value, minivm_stats::voicemailaccounts, minivm_account::volgain, and minivm_account::zonetag.
Referenced by find_user_realtime(), and load_config().
{
struct minivm_account *vmu;
char *domain;
char *username;
char accbuf[BUFSIZ];
ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name);
ast_copy_string(accbuf, name, sizeof(accbuf));
username = accbuf;
domain = strchr(accbuf, '@');
if (domain) {
*domain = '\0';
domain++;
}
if (ast_strlen_zero(domain)) {
ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name);
return 0;
}
ast_debug(3, "Creating static account for user %s domain %s\n", username, domain);
/* Allocate user account */
vmu = ast_calloc(1, sizeof(*vmu));
if (!vmu)
return 0;
ast_copy_string(vmu->domain, domain, sizeof(vmu->domain));
ast_copy_string(vmu->username, username, sizeof(vmu->username));
populate_defaults(vmu);
ast_debug(3, "...Configuring account %s\n", name);
while (var) {
ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name);
if (!strcasecmp(var->name, "serveremail")) {
ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail));
} else if (!strcasecmp(var->name, "email")) {
ast_copy_string(vmu->email, var->value, sizeof(vmu->email));
} else if (!strcasecmp(var->name, "accountcode")) {
ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode));
} else if (!strcasecmp(var->name, "pincode")) {
ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode));
} else if (!strcasecmp(var->name, "domain")) {
ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain));
} else if (!strcasecmp(var->name, "language")) {
ast_copy_string(vmu->language, var->value, sizeof(vmu->language));
} else if (!strcasecmp(var->name, "timezone")) {
ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag));
} else if (!strcasecmp(var->name, "externnotify")) {
ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify));
} else if (!strcasecmp(var->name, "etemplate")) {
ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate));
} else if (!strcasecmp(var->name, "ptemplate")) {
ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate));
} else if (!strcasecmp(var->name, "fullname")) {
ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname));
} else if (!strcasecmp(var->name, "setvar")) {
char *varval;
char *varname = ast_strdupa(var->value);
struct ast_variable *tmpvar;
if (varname && (varval = strchr(varname, '='))) {
*varval = '\0';
varval++;
if ((tmpvar = ast_variable_new(varname, varval, ""))) {
tmpvar->next = vmu->chanvars;
vmu->chanvars = tmpvar;
}
}
} else if (!strcasecmp(var->name, "pager")) {
ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager));
} else if (!strcasecmp(var->name, "volgain")) {
sscanf(var->value, "%30lf", &vmu->volgain);
} else {
ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name);
}
var = var->next;
}
ast_debug(3, "...Linking account %s\n", name);
AST_LIST_LOCK(&minivm_accounts);
AST_LIST_INSERT_TAIL(&minivm_accounts, vmu, list);
AST_LIST_UNLOCK(&minivm_accounts);
global_stats.voicemailaccounts++;
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)" : "");
return 0;
}
| static struct minivm_account* find_account | ( | const char * | domain, |
| const char * | username, | ||
| int | createtemp | ||
| ) | [static, read] |
Find user from static memory object list.
Definition at line 955 of file app_minivm.c.
References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set2_flag, ast_strlen_zero(), minivm_account::domain, find_user_realtime(), LOG_NOTICE, MVM_ALLOCED, mvm_user_alloc(), TRUE, and minivm_account::username.
Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_counter_func_read(), minivm_counter_func_write(), minivm_greet_exec(), and minivm_notify_exec().
{
struct minivm_account *vmu = NULL, *cur;
if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
ast_log(LOG_NOTICE, "No username or domain? \n");
return NULL;
}
ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain);
AST_LIST_LOCK(&minivm_accounts);
AST_LIST_TRAVERSE(&minivm_accounts, cur, list) {
/* Is this the voicemail account we're looking for? */
if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username))
break;
}
AST_LIST_UNLOCK(&minivm_accounts);
if (cur) {
ast_debug(3, "Found account for %s@%s\n", username, domain);
vmu = cur;
} else
vmu = find_user_realtime(domain, username);
if (createtemp && !vmu) {
/* Create a temporary user, send e-mail and be gone */
vmu = mvm_user_alloc();
ast_set2_flag(vmu, TRUE, MVM_ALLOCED);
if (vmu) {
ast_copy_string(vmu->username, username, sizeof(vmu->username));
ast_copy_string(vmu->domain, domain, sizeof(vmu->domain));
ast_debug(1, "Created temporary account\n");
}
}
return vmu;
}
| static struct minivm_account * find_user_realtime | ( | const char * | domain, |
| const char * | username | ||
| ) | [static, read] |
Find user in realtime storage Returns pointer to minivm_account structure.
Definition at line 998 of file app_minivm.c.
References ast_copy_string(), ast_free, ast_load_realtime(), ast_variables_destroy(), create_vmaccount(), MAXHOSTNAMELEN, mvm_user_alloc(), populate_defaults(), SENTINEL, TRUE, minivm_account::username, and var.
Referenced by find_account().
{
struct ast_variable *var;
struct minivm_account *retval;
char name[MAXHOSTNAMELEN];
retval = mvm_user_alloc();
if (!retval)
return NULL;
if (username)
ast_copy_string(retval->username, username, sizeof(retval->username));
populate_defaults(retval);
var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL);
if (!var) {
ast_free(retval);
return NULL;
}
snprintf(name, sizeof(name), "%s@%s", username, domain);
create_vmaccount(name, var, TRUE);
ast_variables_destroy(var);
return retval;
}
| static void free_user | ( | struct minivm_account * | vmu | ) | [static] |
Free user structure - if it's allocated.
Definition at line 863 of file app_minivm.c.
References ast_free, ast_variables_destroy(), and minivm_account::chanvars.
Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), and minivm_notify_exec().
{
if (vmu->chanvars)
ast_variables_destroy(vmu->chanvars);
ast_free(vmu);
}
| static void free_zone | ( | struct minivm_zone * | z | ) | [static] |
Free Mini Voicemail timezone.
Definition at line 2393 of file app_minivm.c.
References ast_free.
Referenced by timezone_destroy_list().
{
ast_free(z);
}
| static int get_date | ( | char * | s, |
| int | len | ||
| ) | [static] |
Definition at line 852 of file app_minivm.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail().
{
struct ast_tm tm;
struct timeval now = ast_tvnow();
ast_localtime(&now, &tm, NULL);
return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm);
}
| static char* handle_minivm_list_templates | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI routine for listing templates.
Definition at line 2714 of file app_minivm.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVLT_OUTPUT_FORMAT, and ast_cli_entry::usage.
{
struct minivm_template *this;
#define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n"
int count = 0;
switch (cmd) {
case CLI_INIT:
e->command = "minivm list templates";
e->usage =
"Usage: minivm list templates\n"
" Lists message templates for e-mail, paging and IM\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc > 3)
return CLI_SHOWUSAGE;
AST_LIST_LOCK(&message_templates);
if (AST_LIST_EMPTY(&message_templates)) {
ast_cli(a->fd, "There are no message templates defined\n");
AST_LIST_UNLOCK(&message_templates);
return CLI_FAILURE;
}
ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject");
ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------");
AST_LIST_TRAVERSE(&message_templates, this, list) {
ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name,
this->charset ? this->charset : "-",
this->locale ? this->locale : "-",
this->attachment ? "Yes" : "No",
this->subject ? this->subject : "-");
count++;
}
AST_LIST_UNLOCK(&message_templates);
ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count);
return CLI_SUCCESS;
}
| static char * handle_minivm_reload | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Reload cofiguration.
Definition at line 3303 of file app_minivm.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, reload, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "minivm reload";
e->usage =
"Usage: minivm reload\n"
" Reload mini-voicemail configuration and reset statistics\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
reload();
ast_cli(a->fd, "\n-- Mini voicemail re-configured \n");
return CLI_SUCCESS;
}
| static char* handle_minivm_show_settings | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI Show settings.
Definition at line 2865 of file app_minivm.c.
References ast_cli(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, default_vmformat, ast_cli_args::fd, global_externnotify, global_logfile, global_mailcmd, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, MVM_OPERATOR, MVM_REVIEW, and ast_cli_entry::usage.
{
switch (cmd) {
case CLI_INIT:
e->command = "minivm show settings";
e->usage =
"Usage: minivm show settings\n"
" Display Mini-Voicemail general settings\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, "* Mini-Voicemail general settings\n");
ast_cli(a->fd, " -------------------------------\n");
ast_cli(a->fd, "\n");
ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd);
ast_cli(a->fd, " Max silence: %d\n", global_maxsilence);
ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold);
ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage);
ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage);
ast_cli(a->fd, " Default format: %s\n", default_vmformat);
ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify);
ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>");
ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No");
ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No");
ast_cli(a->fd, "\n");
return CLI_SUCCESS;
}
| static char* handle_minivm_show_stats | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Show stats.
Definition at line 2897 of file app_minivm.c.
References ast_cli(), ast_localtime(), ast_strftime(), buf, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_stats, minivm_stats::lastreceived, minivm_stats::receivedmessages, minivm_stats::reset, minivm_stats::templates, minivm_stats::timezones, ast_cli_entry::usage, and minivm_stats::voicemailaccounts.
{
struct ast_tm timebuf;
char buf[BUFSIZ];
switch (cmd) {
case CLI_INIT:
e->command = "minivm show stats";
e->usage =
"Usage: minivm show stats\n"
" Display Mini-Voicemail counters\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
ast_cli(a->fd, "* Mini-Voicemail statistics\n");
ast_cli(a->fd, " -------------------------\n");
ast_cli(a->fd, "\n");
ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts);
ast_cli(a->fd, " Templates: %5d\n", global_stats.templates);
ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones);
if (global_stats.receivedmessages == 0) {
ast_cli(a->fd, " Received messages since last reset: <none>\n");
} else {
ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages);
ast_localtime(&global_stats.lastreceived, &timebuf, NULL);
ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf);
ast_cli(a->fd, " Last received voicemail: %s\n", buf);
}
ast_localtime(&global_stats.reset, &timebuf, NULL);
ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf);
ast_cli(a->fd, " Last reset: %s\n", buf);
ast_cli(a->fd, "\n");
return CLI_SUCCESS;
}
| static char* handle_minivm_show_users | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
CLI command to list voicemail accounts.
Definition at line 2780 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, minivm_account::attachfmt, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_minivm_show_users(), minivm_account::domain, minivm_account::etemplate, ast_cli_args::fd, minivm_account::fullname, HMSU_OUTPUT_FORMAT, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, minivm_account::ptemplate, ast_cli_entry::usage, minivm_account::username, ast_cli_args::word, and minivm_account::zonetag.
{
struct minivm_account *vmu;
#define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n"
int count = 0;
switch (cmd) {
case CLI_INIT:
e->command = "minivm list accounts";
e->usage =
"Usage: minivm list accounts\n"
" Lists all mailboxes currently set up\n";
return NULL;
case CLI_GENERATE:
return complete_minivm_show_users(a->line, a->word, a->pos, a->n);
}
if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
return CLI_SHOWUSAGE;
if ((a->argc == 5) && strcmp(a->argv[3],"for"))
return CLI_SHOWUSAGE;
AST_LIST_LOCK(&minivm_accounts);
if (AST_LIST_EMPTY(&minivm_accounts)) {
ast_cli(a->fd, "There are no voicemail users currently defined\n");
AST_LIST_UNLOCK(&minivm_accounts);
return CLI_FAILURE;
}
ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name");
ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------");
AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) {
char tmp[256] = "";
if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) {
count++;
snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain);
ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-",
vmu->ptemplate ? vmu->ptemplate : "-",
vmu->zonetag ? vmu->zonetag : "-",
vmu->attachfmt ? vmu->attachfmt : "-",
vmu->fullname);
}
}
AST_LIST_UNLOCK(&minivm_accounts);
ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count);
return CLI_SUCCESS;
}
| static char* handle_minivm_show_zones | ( | struct ast_cli_entry * | e, |
| int | cmd, | ||
| struct ast_cli_args * | a | ||
| ) | [static] |
Show a list of voicemail zones in the CLI.
Definition at line 2828 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HMSZ_OUTPUT_FORMAT, minivm_zone::msg_format, minivm_zone::name, minivm_zone::timezone, and ast_cli_entry::usage.
{
struct minivm_zone *zone;
#define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
char *res = CLI_SUCCESS;
switch (cmd) {
case CLI_INIT:
e->command = "minivm list zones";
e->usage =
"Usage: minivm list zones\n"
" Lists zone message formats\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != e->args)
return CLI_SHOWUSAGE;
AST_LIST_LOCK(&minivm_zones);
if (!AST_LIST_EMPTY(&minivm_zones)) {
ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format");
ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------");
AST_LIST_TRAVERSE(&minivm_zones, zone, list) {
ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format);
}
} else {
ast_cli(a->fd, "There are no voicemail zones currently defined\n");
res = CLI_FAILURE;
}
AST_LIST_UNLOCK(&minivm_zones);
return res;
}
| static int invent_message | ( | struct ast_channel * | chan, |
| char * | domain, | ||
| char * | username, | ||
| int | busy, | ||
| char * | ecodes | ||
| ) | [static] |
Play intro message before recording voicemail.
Definition at line 1309 of file app_minivm.c.
References ast_debug, ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), FALSE, ast_channel::language, and minivm_account::username.
Referenced by minivm_greet_exec().
{
int res;
char fn[PATH_MAX];
ast_debug(2, "Still preparing to play message ...\n");
snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username);
if (ast_fileexists(fn, NULL, NULL) > 0) {
res = ast_streamfile(chan, fn, chan->language);
if (res)
return -1;
res = ast_waitstream(chan, ecodes);
if (res)
return res;
} else {
int numericusername = 1;
char *i = username;
ast_debug(2, "No personal prompts. Using default prompt set for language\n");
while (*i) {
ast_debug(2, "Numeric? Checking %c\n", *i);
if (!isdigit(*i)) {
numericusername = FALSE;
break;
}
i++;
}
if (numericusername) {
if(ast_streamfile(chan, "vm-theperson", chan->language))
return -1;
if ((res = ast_waitstream(chan, ecodes)))
return res;
res = ast_say_digit_str(chan, username, ecodes, chan->language);
if (res)
return res;
} else {
if(ast_streamfile(chan, "vm-theextensionis", chan->language))
return -1;
if ((res = ast_waitstream(chan, ecodes)))
return res;
}
}
res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language);
if (res)
return -1;
res = ast_waitstream(chan, ecodes);
return res;
}
| static int leave_voicemail | ( | struct ast_channel * | chan, |
| char * | username, | ||
| struct leave_vm_options * | options | ||
| ) | [static] |
Record voicemail message, store into file prepared for sending e-mail.
Definition at line 1604 of file app_minivm.c.
References minivm_account::accountcode, ast_callerid_merge(), ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_localtime(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_streamfile(), ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_verb, ast_waitstream(), minivm_account::attachfmt, check_dirpath(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, create_dirpath(), default_vmformat, minivm_account::domain, errno, ast_channel::exten, find_account(), free_user(), get_date(), global_stats, global_vmmaxmessage, global_vmminmessage, ast_channel::language, minivm_stats::lastreceived, LOG_ERROR, LOG_WARNING, ast_channel::macrocontext, minivmlogfile, minivmloglock, MVM_ALLOCED, ast_channel::name, pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, minivm_stats::receivedmessages, leave_vm_options::record_gain, and TRUE.
Referenced by minivm_record_exec().
{
char tmptxtfile[PATH_MAX];
char callerid[256];
FILE *txt;
int res = 0, txtdes;
int msgnum;
int duration = 0;
char date[256];
char tmpdir[PATH_MAX];
char ext_context[256] = "";
char fmt[80];
char *domain;
char tmp[256] = "";
struct minivm_account *vmu;
int userdir;
ast_copy_string(tmp, username, sizeof(tmp));
username = tmp;
domain = strchr(tmp, '@');
if (domain) {
*domain = '\0';
domain++;
}
if (!(vmu = find_account(domain, username, TRUE))) {
/* We could not find user, let's exit */
ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain);
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
return 0;
}
/* Setup pre-file if appropriate */
if (strcmp(vmu->domain, "localhost"))
snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain);
else
ast_copy_string(ext_context, vmu->domain, sizeof(ext_context));
/* The meat of recording the message... All the announcements and beeps have been played*/
if (ast_strlen_zero(vmu->attachfmt))
ast_copy_string(fmt, default_vmformat, sizeof(fmt));
else
ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt));
if (ast_strlen_zero(fmt)) {
ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat);
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
return res;
}
msgnum = 0;
userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp");
/* If we have no user directory, use generic temporary directory */
if (!userdir) {
create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", "");
ast_debug(3, "Creating temporary directory %s\n", tmpdir);
}
snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
/* XXX This file needs to be in temp directory */
txtdes = mkstemp(tmptxtfile);
if (txtdes < 0) {
ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno));
res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
if (!res)
res = ast_waitstream(chan, "");
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
return res;
}
if (res >= 0) {
/* Unless we're *really* silent, try to send the beep */
res = ast_streamfile(chan, "beep", chan->language);
if (!res)
res = ast_waitstream(chan, "");
}
/* OEJ XXX Maybe this can be turned into a log file? Hmm. */
/* Store information */
ast_debug(2, "Open file for metadata: %s\n", tmptxtfile);
res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain);
txt = fdopen(txtdes, "w+");
if (!txt) {
ast_log(LOG_WARNING, "Error opening text file for output\n");
} else {
struct ast_tm tm;
struct timeval now = ast_tvnow();
char timebuf[30];
char logbuf[BUFSIZ];
get_date(date, sizeof(date));
ast_localtime(&now, &tm, NULL);
ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm);
snprintf(logbuf, sizeof(logbuf),
/* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
"%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
username,
chan->context,
chan->macrocontext,
chan->exten,
chan->priority,
chan->name,
ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"),
date,
timebuf,
duration,
duration < global_vmminmessage ? "IGNORED" : "OK",
vmu->accountcode
);
fprintf(txt, "%s", logbuf);
if (minivmlogfile) {
ast_mutex_lock(&minivmloglock);
fprintf(minivmlogfile, "%s", logbuf);
ast_mutex_unlock(&minivmloglock);
}
if (duration < global_vmminmessage) {
ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, global_vmminmessage);
fclose(txt);
ast_filedelete(tmptxtfile, NULL);
unlink(tmptxtfile);
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
return 0;
}
fclose(txt); /* Close log file */
if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
unlink(tmptxtfile);
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
return 0;
}
/* Set channel variables for the notify application */
pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile);
snprintf(timebuf, sizeof(timebuf), "%d", duration);
pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf);
pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt);
}
global_stats.lastreceived = ast_tvnow();
global_stats.receivedmessages++;
// /* Go ahead and delete audio files from system, they're not needed any more */
// if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
// ast_filedelete(tmptxtfile, NULL);
// /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */
// ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile);
// }
if (res > 0)
res = 0;
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS");
return res;
}
| static int load_config | ( | int | reload | ) | [static] |
Load minivoicemail configuration.
Definition at line 2573 of file app_minivm.c.
References apply_general_options(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set2_flag, ast_strlen_zero(), ast_tvnow(), ast_variable_browse(), ast_variable_retrieve(), chanvar, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, create_vmaccount(), default_vmformat, errno, FALSE, global_charset, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_saydurationminfo, global_silencethreshold, global_stats, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_ERROR, LOG_WARNING, message_destroy_list(), message_template_build(), message_template_find(), message_template_parse_emailbody(), minivmlock, minivmlogfile, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, minivm_stats::reset, SENDMAIL, THRESHOLD_SILENCE, timezone_add(), timezone_destroy_list(), TRUE, ast_variable::value, var, vmaccounts_destroy_list(), and VOICEMAIL_CONFIG.
Referenced by load_module(), and reload().
{
struct ast_config *cfg;
struct ast_variable *var;
char *cat;
const char *chanvar;
int error = 0;
struct minivm_template *template;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
return 0;
} else if (cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
return 0;
}
ast_mutex_lock(&minivmlock);
/* Destroy lists to reconfigure */
message_destroy_list(); /* Destroy list of voicemail message templates */
timezone_destroy_list(); /* Destroy list of timezones */
vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */
ast_debug(2, "Destroyed memory objects...\n");
/* First, set some default settings */
global_externnotify[0] = '\0';
global_logfile[0] = '\0';
global_vmmaxmessage = 2000;
global_maxgreet = 2000;
global_vmminmessage = 0;
strcpy(global_mailcmd, SENDMAIL);
global_maxsilence = 0;
global_saydurationminfo = 2;
ast_copy_string(default_vmformat, "wav", sizeof(default_vmformat));
ast_set2_flag((&globalflags), FALSE, MVM_REVIEW);
ast_set2_flag((&globalflags), FALSE, MVM_OPERATOR);
strcpy(global_charset, "ISO-8859-1");
/* Reset statistics */
memset(&global_stats, 0, sizeof(global_stats));
global_stats.reset = ast_tvnow();
global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
/* Make sure we could load configuration file */
if (!cfg) {
ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n");
ast_mutex_unlock(&minivmlock);
return 0;
}
ast_debug(2, "Loaded configuration file, now parsing\n");
/* General settings */
cat = ast_category_browse(cfg, NULL);
while (cat) {
ast_debug(3, "Found configuration section [%s]\n", cat);
if (!strcasecmp(cat, "general")) {
/* Nothing right now */
error += apply_general_options(ast_variable_browse(cfg, cat));
} else if (!strncasecmp(cat, "template-", 9)) {
/* Template */
char *name = cat + 9;
/* Now build and link template to list */
error += message_template_build(name, ast_variable_browse(cfg, cat));
} else {
var = ast_variable_browse(cfg, cat);
if (!strcasecmp(cat, "zonemessages")) {
/* Timezones in this context */
while (var) {
timezone_add(var->name, var->value);
var = var->next;
}
} else {
/* Create mailbox from this */
error += create_vmaccount(cat, var, FALSE);
}
}
/* Find next section in configuration file */
cat = ast_category_browse(cfg, cat);
}
/* Configure the default email template */
message_template_build("email-default", NULL);
template = message_template_find("email-default");
/* Load date format config for voicemail mail */
if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat")))
ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat));
if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring")))
ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress));
if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress")))
ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail));
if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset")))
ast_copy_string(template->charset, chanvar, sizeof(template->charset));
if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject")))
ast_copy_string(template->subject, chanvar, sizeof(template->subject));
if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody")))
template->body = message_template_parse_emailbody(chanvar);
template->attachment = TRUE;
message_template_build("pager-default", NULL);
template = message_template_find("pager-default");
if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress));
if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress")))
ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail));
if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset")))
ast_copy_string(template->charset, chanvar, sizeof(template->charset));
if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject")))
ast_copy_string(template->subject, chanvar,sizeof(template->subject));
if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody")))
template->body = message_template_parse_emailbody(chanvar);
template->attachment = FALSE;
if (error)
ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error);
ast_mutex_unlock(&minivmlock);
ast_config_destroy(cfg);
/* Close log file if it's open and disabled */
if(minivmlogfile)
fclose(minivmlogfile);
/* Open log file if it's enabled */
if(!ast_strlen_zero(global_logfile)) {
minivmlogfile = fopen(global_logfile, "a");
if(!minivmlogfile)
ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno));
if (minivmlogfile)
ast_debug(3, "Opened log file %s \n", global_logfile);
}
return 0;
}
| static int load_module | ( | void | ) | [static] |
Load mini voicemail module.
Definition at line 3269 of file app_minivm.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_register_application_xml, cli_minivm, load_config(), minivm_accmess_exec(), minivm_account_function, minivm_counter_function, minivm_delete_exec(), minivm_greet_exec(), minivm_mwi_exec(), minivm_notify_exec(), and minivm_record_exec().
{
int res;
res = ast_register_application_xml(app_minivm_record, minivm_record_exec);
res = ast_register_application_xml(app_minivm_greet, minivm_greet_exec);
res = ast_register_application_xml(app_minivm_notify, minivm_notify_exec);
res = ast_register_application_xml(app_minivm_delete, minivm_delete_exec);
res = ast_register_application_xml(app_minivm_accmess, minivm_accmess_exec);
res = ast_register_application_xml(app_minivm_mwi, minivm_mwi_exec);
ast_custom_function_register(&minivm_account_function);
ast_custom_function_register(&minivm_counter_function);
if (res)
return(res);
if ((res = load_config(0)))
return(res);
ast_cli_register_multiple(cli_minivm, ARRAY_LEN(cli_minivm));
/* compute the location of the voicemail spool directory */
snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
return res;
}
| static char* mailheader_quote | ( | const char * | from, |
| char * | to, | ||
| size_t | len | ||
| ) | [static] |
Fix quote of mail headers for non-ascii characters.
Definition at line 911 of file app_minivm.c.
Referenced by sendmail().
{
char *ptr = to;
*ptr++ = '"';
for (; ptr < to + len - 1; from++) {
if (*from == '"')
*ptr++ = '\\';
else if (*from == '\0')
break;
*ptr++ = *from;
}
if (ptr < to + len - 1)
*ptr++ = '"';
*ptr = '\0';
return to;
}
| static int make_dir | ( | char * | dest, |
| int | len, | ||
| const char * | domain, | ||
| const char * | username, | ||
| const char * | folder | ||
| ) | [static] |
Create directory based on components.
Definition at line 1263 of file app_minivm.c.
References ast_strlen_zero().
Referenced by check_dirpath(), and create_dirpath().
{
return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : "");
}
| static void message_destroy_list | ( | void | ) | [static] |
Clear list of templates.
Definition at line 718 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and message_template_free().
Referenced by load_config(), and unload_module().
{
struct minivm_template *this;
AST_LIST_LOCK(&message_templates);
while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list)))
message_template_free(this);
AST_LIST_UNLOCK(&message_templates);
}
| static int message_template_build | ( | const char * | name, |
| struct ast_variable * | var | ||
| ) | [static] |
Build message template from configuration.
Definition at line 635 of file app_minivm.c.
References ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_true(), global_stats, LOG_ERROR, message_template_create(), message_template_parse_emailbody(), message_template_parse_filebody(), ast_variable::name, ast_variable::next, minivm_stats::templates, and ast_variable::value.
Referenced by load_config().
{
struct minivm_template *template;
int error = 0;
template = message_template_create(name);
if (!template) {
ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name);
return -1;
}
while (var) {
ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name);
if (!strcasecmp(var->name, "fromaddress")) {
ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress));
} else if (!strcasecmp(var->name, "fromemail")) {
ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail));
} else if (!strcasecmp(var->name, "subject")) {
ast_copy_string(template->subject, var->value, sizeof(template->subject));
} else if (!strcasecmp(var->name, "locale")) {
ast_copy_string(template->locale, var->value, sizeof(template->locale));
} else if (!strcasecmp(var->name, "attachmedia")) {
template->attachment = ast_true(var->value);
} else if (!strcasecmp(var->name, "dateformat")) {
ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat));
} else if (!strcasecmp(var->name, "charset")) {
ast_copy_string(template->charset, var->value, sizeof(template->charset));
} else if (!strcasecmp(var->name, "templatefile")) {
if (template->body)
ast_free(template->body);
template->body = message_template_parse_filebody(var->value);
if (!template->body) {
ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value);
error++;
}
} else if (!strcasecmp(var->name, "messagebody")) {
if (template->body)
ast_free(template->body);
template->body = message_template_parse_emailbody(var->value);
if (!template->body) {
ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value);
error++;
}
} else {
ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value);
error++;
}
var = var->next;
}
if (error)
ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name);
AST_LIST_LOCK(&message_templates);
AST_LIST_INSERT_TAIL(&message_templates, template, list);
AST_LIST_UNLOCK(&message_templates);
global_stats.templates++;
return error;
}
| static struct minivm_template* message_template_create | ( | const char * | name | ) | [static, read] |
Create message template.
Definition at line 607 of file app_minivm.c.
References ast_calloc, ast_copy_string(), DEFAULT_CHARSET, DEFAULT_DATEFORMAT, and TRUE.
Referenced by message_template_build().
{
struct minivm_template *template;
template = ast_calloc(1, sizeof(*template));
if (!template)
return NULL;
/* Set some defaults for templates */
ast_copy_string(template->name, name, sizeof(template->name));
ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat));
ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset));
ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject));
template->attachment = TRUE;
return template;
}
| static struct minivm_template* message_template_find | ( | const char * | name | ) | [static, read] |
Find named template.
Definition at line 697 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by load_config(), and notify_new_message().
{
struct minivm_template *this, *res = NULL;
if (ast_strlen_zero(name))
return NULL;
AST_LIST_LOCK(&message_templates);
AST_LIST_TRAVERSE(&message_templates, this, list) {
if (!strcasecmp(this->name, name)) {
res = this;
break;
}
}
AST_LIST_UNLOCK(&message_templates);
return res;
}
| static void message_template_free | ( | struct minivm_template * | template | ) | [static] |
Release memory allocated by message template.
Definition at line 626 of file app_minivm.c.
References ast_free.
Referenced by message_destroy_list().
| static char * message_template_parse_emailbody | ( | const char * | body | ) | [static] |
Parse emailbody template from configuration file.
Definition at line 2488 of file app_minivm.c.
References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.
Referenced by load_config(), and message_template_build().
{
char *tmpread, *tmpwrite;
char *emailbody = ast_strdup(configuration);
/* substitute strings \t and \n into the apropriate characters */
tmpread = tmpwrite = emailbody;
while ((tmpwrite = strchr(tmpread,'\\'))) {
int len = strlen("\n");
switch (tmpwrite[1]) {
case 'n':
memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
strncpy(tmpwrite, "\n", len);
break;
case 't':
memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
strncpy(tmpwrite, "\t", len);
break;
default:
ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
}
tmpread = tmpwrite + len;
}
return emailbody;
}
| static char * message_template_parse_filebody | ( | const char * | filename | ) | [static] |
Read message template from file.
Definition at line 2448 of file app_minivm.c.
References ast_calloc, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), buf, and LOG_ERROR.
Referenced by message_template_build().
{
char buf[BUFSIZ * 6];
char readbuf[BUFSIZ];
char filenamebuf[BUFSIZ];
char *writepos;
char *messagebody;
FILE *fi;
int lines = 0;
if (ast_strlen_zero(filename))
return NULL;
if (*filename == '/')
ast_copy_string(filenamebuf, filename, sizeof(filenamebuf));
else
snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
if (!(fi = fopen(filenamebuf, "r"))) {
ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf);
return NULL;
}
writepos = buf;
while (fgets(readbuf, sizeof(readbuf), fi)) {
lines ++;
if (writepos != buf) {
*writepos = '\n'; /* Replace EOL with new line */
writepos++;
}
ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf));
writepos += strlen(readbuf) - 1;
}
fclose(fi);
messagebody = ast_calloc(1, strlen(buf + 1));
ast_copy_string(messagebody, buf, strlen(buf) + 1);
ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) );
ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody);
return messagebody;
}
| static int minivm_accmess_exec | ( | struct ast_channel * | chan, |
| void * | data | ||
| ) | [static] |
Record specific messages for voicemail account.
Definition at line 2195 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_copy_string(), ast_debug, ast_log(), AST_STATE_UP, ast_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().
{
int argc = 0;
char *argv[2];
char filename[PATH_MAX];
char tmp[PATH_MAX];
char *domain;
char *tmpptr = NULL;
struct minivm_account *vmu;
char *username = argv[0];
struct ast_flags flags = { 0 };
char *opts[OPT_ARG_ARRAY_SIZE];
int error = FALSE;
char *message = NULL;
char *prompt = NULL;
int duration;
int cmd;
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
error = TRUE;
} else
tmpptr = ast_strdupa((char *)data);
if (!error) {
if (!tmpptr) {
ast_log(LOG_ERROR, "Out of memory\n");
error = TRUE;
} else
argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
}
if (argc <=1) {
ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
error = TRUE;
}
if (!error && strlen(argv[1]) > 1) {
ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]);
error = TRUE;
}
if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) {
ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]);
error = TRUE;
}
if (error) {
pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
return -1;
}
ast_copy_string(tmp, argv[0], sizeof(tmp));
username = tmp;
domain = strchr(tmp, '@');
if (domain) {
*domain = '\0';
domain++;
}
if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
return -1;
}
if(!(vmu = find_account(domain, username, TRUE))) {
/* We could not find user, let's exit */
ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
return -1;
}
/* Answer channel if it's not already answered */
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
/* Here's where the action is */
if (ast_test_flag(&flags, OPT_BUSY_GREETING)) {
message = "busy";
prompt = "vm-rec-busy";
} else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) {
message = "unavailable";
prompt = "vm-rec-unv";
} else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) {
message = "temp";
prompt = "vm-rec-temp";
} else if (ast_test_flag(&flags, OPT_NAME_GREETING)) {
message = "greet";
prompt = "vm-rec-name";
}
snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message);
/* Maybe we should check the result of play_record_review ? */
cmd = play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, FALSE);
ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration);
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS");
/* Ok, we're ready to rock and roll. Return to dialplan */
return 0;
}
| static int minivm_account_func_read | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
${MINIVMACCOUNT()} Dialplan function - reads account data
Definition at line 2937 of file app_minivm.c.
References minivm_account::accountcode, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, minivm_account::chanvars, check_dirpath(), minivm_account::domain, minivm_account::email, minivm_account::etemplate, find_account(), free_user(), minivm_account::fullname, minivm_account::language, LOG_ERROR, MVM_ALLOCED, ast_variable::name, ast_variable::next, minivm_account::pager, minivm_account::pincode, minivm_account::ptemplate, TRUE, minivm_account::username, ast_variable::value, var, and minivm_account::zonetag.
{
struct minivm_account *vmu;
char *username, *domain, *colname;
if (!(username = ast_strdupa(data))) {
ast_log(LOG_ERROR, "Memory Error!\n");
return -1;
}
if ((colname = strchr(username, ':'))) {
*colname = '\0';
colname++;
} else {
colname = "path";
}
if ((domain = strchr(username, '@'))) {
*domain = '\0';
domain++;
}
if (ast_strlen_zero(username) || ast_strlen_zero(domain)) {
ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n");
return 0;
}
if (!(vmu = find_account(domain, username, TRUE)))
return 0;
if (!strcasecmp(colname, "hasaccount")) {
ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len);
} else if (!strcasecmp(colname, "fullname")) {
ast_copy_string(buf, vmu->fullname, len);
} else if (!strcasecmp(colname, "email")) {
if (!ast_strlen_zero(vmu->email))
ast_copy_string(buf, vmu->email, len);
else
snprintf(buf, len, "%s@%s", vmu->username, vmu->domain);
} else if (!strcasecmp(colname, "pager")) {
ast_copy_string(buf, vmu->pager, len);
} else if (!strcasecmp(colname, "etemplate")) {
if (!ast_strlen_zero(vmu->etemplate))
ast_copy_string(buf, vmu->etemplate, len);
else
ast_copy_string(buf, "email-default", len);
} else if (!strcasecmp(colname, "language")) {
ast_copy_string(buf, vmu->language, len);
} else if (!strcasecmp(colname, "timezone")) {
ast_copy_string(buf, vmu->zonetag, len);
} else if (!strcasecmp(colname, "ptemplate")) {
if (!ast_strlen_zero(vmu->ptemplate))
ast_copy_string(buf, vmu->ptemplate, len);
else
ast_copy_string(buf, "email-default", len);
} else if (!strcasecmp(colname, "accountcode")) {
ast_copy_string(buf, vmu->accountcode, len);
} else if (!strcasecmp(colname, "pincode")) {
ast_copy_string(buf, vmu->pincode, len);
} else if (!strcasecmp(colname, "path")) {
check_dirpath(buf, len, vmu->domain, vmu->username, NULL);
} else { /* Look in channel variables */
struct ast_variable *var;
int found = 0;
for (var = vmu->chanvars ; var ; var = var->next)
if (!strcmp(var->name, colname)) {
ast_copy_string(buf, var->value, len);
found = 1;
break;
}
}
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
return 0;
}
| static int minivm_counter_func_read | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| char * | buf, | ||
| size_t | len | ||
| ) | [static] |
${MINIVMCOUNTER()} Dialplan function - read counters
Definition at line 3089 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), minivm_account::domain, FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
{
char *username, *domain, *countername;
struct minivm_account *vmu = NULL;
char userpath[BUFSIZ];
int res;
*buf = '\0';
if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */
ast_log(LOG_WARNING, "Memory error!\n");
return -1;
}
if ((countername = strchr(username, ':'))) {
*countername = '\0';
countername++;
}
if ((domain = strchr(username, '@'))) {
*domain = '\0';
domain++;
}
/* If we have neither username nor domain now, let's give up */
if (ast_strlen_zero(username) && ast_strlen_zero(domain)) {
ast_log(LOG_ERROR, "No account given\n");
return -1;
}
if (ast_strlen_zero(countername)) {
ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n");
return -1;
}
/* We only have a domain, no username */
if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) {
domain = username;
username = NULL;
}
/* If we can't find account or if the account is temporary, return. */
if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) {
ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
return 0;
}
create_dirpath(userpath, sizeof(userpath), domain, username, NULL);
/* We have the path, now read the counter file */
res = access_counter_file(userpath, countername, 0, 0);
if (res >= 0)
snprintf(buf, len, "%d", res);
return 0;
}
| static int minivm_counter_func_write | ( | struct ast_channel * | chan, |
| const char * | cmd, | ||
| char * | data, | ||
| const char * | value | ||
| ) | [static] |
${MINIVMCOUNTER()} Dialplan function - changes counter data
Definition at line 3145 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), minivm_account::domain, FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
{
char *username, *domain, *countername, *operand;
char userpath[BUFSIZ];
struct minivm_account *vmu;
int change = 0;
int operation = 0;
if(!value)
return -1;
change = atoi(value);
if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */
ast_log(LOG_WARNING, "Memory error!\n");
return -1;
}
if ((countername = strchr(username, ':'))) {
*countername = '\0';
countername++;
}
if ((operand = strchr(countername, ':'))) {
*operand = '\0';
operand++;
}
if ((domain = strchr(username, '@'))) {
*domain = '\0';
domain++;
}
/* If we have neither username nor domain now, let's give up */
if (ast_strlen_zero(username) && ast_strlen_zero(domain)) {
ast_log(LOG_ERROR, "No account given\n");
return -1;
}
/* We only have a domain, no username */
if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) {
domain = username;
username = NULL;
}
if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) {
ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n");
return -1;
}
/* If we can't find account or if the account is temporary, return. */
if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) {
ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
return 0;
}
create_dirpath(userpath, sizeof(userpath), domain, username, NULL);
/* Now, find out our operator */
if (*operand == 'i') /* Increment */
operation = 2;
else if (*operand == 'd') {
change = change * -1;
operation = 2;
} else if (*operand == 's')
operation = 1;
else {
ast_log(LOG_ERROR, "Unknown operator: %s\n", operand);
return -1;
}
/* We have the path, now read the counter file */
access_counter_file(userpath, countername, change, operation);
return 0;
}
| static int minivm_delete_exec | ( | struct ast_channel * | chan, |
| void * | data | ||
| ) | [static] |
Dialplan application to delete voicemail.
Definition at line 2157 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_fileexists(), ast_log(), ast_strlen_zero(), LOG_ERROR, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and vm_delete().
Referenced by load_module().
{
int res = 0;
char filename[BUFSIZ];
if (!ast_strlen_zero(data)) {
ast_copy_string(filename, (char *) data, sizeof(filename));
} else {
ast_channel_lock(chan);
ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename));
ast_channel_unlock(chan);
}
if (ast_strlen_zero(filename)) {
ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n");
return res;
}
/* Go ahead and delete audio files from system, they're not needed any more */
/* We should look for both audio and text files here */
if (ast_fileexists(filename, NULL, NULL) > 0) {
res = vm_delete(filename);
if (res) {
ast_debug(2, "Can't delete file: %s\n", filename);
pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED");
} else {
ast_debug(2, "Deleted voicemail file :: %s \n", filename);
pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS");
}
} else {
ast_debug(2, "Filename does not exist: %s\n", filename);
pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED");
}
return res;
}
| static int minivm_greet_exec | ( | struct ast_channel * | chan, |
| void * | data | ||
| ) | [static] |
Play voicemail prompts - either generic or user specific.
Definition at line 1971 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_copy_flags, ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_play_and_wait(), ast_set_flag, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), check_dirpath(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, minivm_account::domain, minivm_account::exit, ast_channel::exten, find_account(), minivm_account::flags, free_user(), invent_message(), ast_channel::language, LOG_ERROR, ast_channel::macrocontext, minivm_app_options, MVM_ALLOCED, MVM_OPERATOR, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), ast_channel::priority, SOUND_INTRO, TRUE, and minivm_account::username.
Referenced by load_module().
{
struct leave_vm_options leave_options = { 0, '\0'};
int argc;
char *argv[2];
struct ast_flags flags = { 0 };
char *opts[OPT_ARG_ARRAY_SIZE];
int res = 0;
int ausemacro = 0;
int ousemacro = 0;
int ouseexten = 0;
char tmp[PATH_MAX];
char dest[PATH_MAX];
char prefile[PATH_MAX] = "";
char tempfile[PATH_MAX] = "";
char ext_context[256] = "";
char *domain;
char ecodes[16] = "#";
char *tmpptr;
struct minivm_account *vmu;
char *username = argv[0];
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
return -1;
}
tmpptr = ast_strdupa((char *)data);
if (!tmpptr) {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
}
argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
if (argc == 2) {
if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1]))
return -1;
ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
}
ast_copy_string(tmp, argv[0], sizeof(tmp));
username = tmp;
domain = strchr(tmp, '@');
if (domain) {
*domain = '\0';
domain++;
}
if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]);
return -1;
}
ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain);
if (!(vmu = find_account(domain, username, TRUE))) {
ast_log(LOG_ERROR, "Could not allocate memory. \n");
return -1;
}
/* Answer channel if it's not already answered */
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
/* Setup pre-file if appropriate */
if (strcmp(vmu->domain, "localhost"))
snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain);
else
ast_copy_string(ext_context, vmu->domain, sizeof(ext_context));
if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) {
res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy");
if (res)
snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username);
} else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) {
res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail");
if (res)
snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username);
}
/* Check for temporary greeting - it overrides busy and unavail */
snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username);
if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) {
ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile);
ast_copy_string(prefile, tempfile, sizeof(prefile));
}
ast_debug(2, "Preparing to play message ...\n");
/* Check current or macro-calling context for special extensions */
if (ast_test_flag(vmu, MVM_OPERATOR)) {
if (!ast_strlen_zero(vmu->exit)) {
if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
} else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ouseexten = 1;
}
else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) {
strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
ousemacro = 1;
}
}
if (!ast_strlen_zero(vmu->exit)) {
if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num))
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
} else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num))
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) {
strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
ausemacro = 1;
}
res = 0; /* Reset */
/* Play the beginning intro if desired */
if (!ast_strlen_zero(prefile)) {
if (ast_streamfile(chan, prefile, chan->language) > -1)
res = ast_waitstream(chan, ecodes);
} else {
ast_debug(2, "%s doesn't exist, doing what we can\n", prefile);
res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes);
}
if (res < 0) {
ast_debug(2, "Hang up during prefile playback\n");
pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED");
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
return -1;
}
if (res == '#') {
/* On a '#' we skip the instructions */
ast_set_flag(&leave_options, OPT_SILENT);
res = 0;
}
if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) {
res = ast_streamfile(chan, SOUND_INTRO, chan->language);
if (!res)
res = ast_waitstream(chan, ecodes);
if (res == '#') {
ast_set_flag(&leave_options, OPT_SILENT);
res = 0;
}
}
if (res > 0)
ast_stopstream(chan);
/* Check for a '*' here in case the caller wants to escape from voicemail to something
other than the operator -- an automated attendant or mailbox login for example */
if (res == '*') {
chan->exten[0] = 'a';
chan->exten[1] = '\0';
if (!ast_strlen_zero(vmu->exit)) {
ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
} else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
}
chan->priority = 0;
pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
res = 0;
} else if (res == '0') { /* Check for a '0' here */
if(ouseexten || ousemacro) {
chan->exten[0] = 'o';
chan->exten[1] = '\0';
if (!ast_strlen_zero(vmu->exit)) {
ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
} else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
}
ast_play_and_wait(chan, "transfer");
chan->priority = 0;
pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
}
res = 0;
} else if (res < 0) {
pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED");
res = -1;
} else
pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS");
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
/* Ok, we're ready to rock and roll. Return to dialplan */
return res;
}
| static int minivm_mwi_exec | ( | struct ast_channel * | chan, |
| void * | data | ||
| ) | [static] |
Send MWI using interal Asterisk event subsystem.
Definition at line 1795 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args(), ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), minivm_account::domain, LOG_ERROR, mailbox, and queue_mwi_event().
Referenced by load_module().
{
int argc;
char *argv[4];
int res = 0;
char *tmpptr;
char tmp[PATH_MAX];
char *mailbox;
char *domain;
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
return -1;
}
tmpptr = ast_strdupa((char *)data);
if (!tmpptr) {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
}
argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
if (argc < 4) {
ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc);
return -1;
}
ast_copy_string(tmp, argv[0], sizeof(tmp));
mailbox = tmp;
domain = strchr(tmp, '@');
if (domain) {
*domain = '\0';
domain++;
}
if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) {
ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]);
return -1;
}
queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
return res;
}
| static int minivm_notify_exec | ( | struct ast_channel * | chan, |
| void * | data | ||
| ) | [static] |
Notify voicemail account owners - either generic template or user specific.
Definition at line 1836 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, 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(), TRUE, and minivm_account::username.
Referenced by load_module().
{
int argc;
char *argv[2];
int res = 0;
char tmp[PATH_MAX];
char *domain;
char *tmpptr;
struct minivm_account *vmu;
char *username = argv[0];
const char *template = "";
const char *filename;
const char *format;
const char *duration_string;
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
return -1;
}
tmpptr = ast_strdupa((char *)data);
if (!tmpptr) {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
}
argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
if (argc == 2 && !ast_strlen_zero(argv[1]))
template = argv[1];
ast_copy_string(tmp, argv[0], sizeof(tmp));
username = tmp;
domain = strchr(tmp, '@');
if (domain) {
*domain = '\0';
domain++;
}
if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
return -1;
}
if(!(vmu = find_account(domain, username, TRUE))) {
/* We could not find user, let's exit */
ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED");
return -1;
}
ast_channel_lock(chan);
if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) {
filename = ast_strdupa(filename);
}
ast_channel_unlock(chan);
/* Notify of new message to e-mail and pager */
if (!ast_strlen_zero(filename)) {
ast_channel_lock(chan);
if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) {
format = ast_strdupa(format);
}
if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) {
duration_string = ast_strdupa(duration_string);
}
ast_channel_unlock(chan);
res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name);
}
pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED");
if(ast_test_flag(vmu, MVM_ALLOCED))
free_user(vmu);
/* Ok, we're ready to rock and roll. Return to dialplan */
return res;
}
| static int minivm_record_exec | ( | struct ast_channel * | chan, |
| void * | data | ||
| ) | [static] |
Dialplan function to record voicemail.
Definition at line 1915 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_copy_flags, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, minivm_account::flags, leave_voicemail(), LOG_ERROR, LOG_WARNING, minivm_app_options, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and leave_vm_options::record_gain.
Referenced by load_module().
{
int res = 0;
char *tmp;
struct leave_vm_options leave_options;
int argc;
char *argv[2];
struct ast_flags flags = { 0 };
char *opts[OPT_ARG_ARRAY_SIZE];
memset(&leave_options, 0, sizeof(leave_options));
/* Answer channel if it's not already answered */
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
if (ast_strlen_zero(data)) {
ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
return -1;
}
tmp = ast_strdupa((char *)data);
if (!tmp) {
ast_log(LOG_ERROR, "Out of memory\n");
return -1;
}
argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv));
if (argc == 2) {
if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
return -1;
}
ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
int gain;
if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
return -1;
} else
leave_options.record_gain = (signed char) gain;
}
}
/* Now run the appliation and good luck to you! */
res = leave_voicemail(chan, argv[0], &leave_options);
if (res == ERROR_LOCK_PATH) {
ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
res = 0;
}
pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS");
return res;
}
| static struct minivm_account* mvm_user_alloc | ( | void | ) | [static, read] |
Allocate new vm user and set default values.
Definition at line 930 of file app_minivm.c.
References ast_calloc, and populate_defaults().
Referenced by find_account(), and find_user_realtime().
{
struct minivm_account *new;
new = ast_calloc(1, sizeof(*new));
if (!new)
return NULL;
populate_defaults(new);
return new;
}
| static int notify_new_message | ( | struct ast_channel * | chan, |
| const char * | templatename, | ||
| struct minivm_account * | vmu, | ||
| const char * | filename, | ||
| long | duration, | ||
| const char * | format, | ||
| char * | cidnum, | ||
| char * | cidname | ||
| ) | [static] |
Send message to voicemail account owner.
Definition at line 1527 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), minivm_account::attachfmt, minivm_template::attachment, minivm_account::domain, minivm_account::etemplate, EVENT_FLAG_CALL, minivm_template::locale, LOG_WARNING, manager_event, message_template_find(), MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_account::pager, pbx_builtin_getvar_helper(), minivm_account::ptemplate, run_externnotify(), sendmail(), strsep(), and minivm_account::username.
Referenced by minivm_notify_exec().
{
char *stringp;
struct minivm_template *etemplate;
char *messageformat;
int res = 0;
char oldlocale[100];
const char *counter;
if (!ast_strlen_zero(vmu->attachfmt)) {
if (strstr(format, vmu->attachfmt)) {
format = vmu->attachfmt;
} else
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);
}
etemplate = message_template_find(vmu->etemplate);
if (!etemplate)
etemplate = message_template_find(templatename);
if (!etemplate)
etemplate = message_template_find("email-default");
/* Attach only the first format */
stringp = messageformat = ast_strdupa(format);
strsep(&stringp, "|");
if (!ast_strlen_zero(etemplate->locale)) {
char *new_locale;
ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale));
ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale);
new_locale = setlocale(LC_TIME, etemplate->locale);
if (new_locale == NULL) {
ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale);
}
}
/* Read counter if available */
ast_channel_lock(chan);
if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) {
counter = ast_strdupa(counter);
}
ast_channel_unlock(chan);
if (ast_strlen_zero(counter)) {
ast_debug(2, "MVM_COUNTER not found\n");
} else {
ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter);
}
res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter);
if (res == 0 && !ast_strlen_zero(vmu->pager)) {
/* Find template for paging */
etemplate = message_template_find(vmu->ptemplate);
if (!etemplate)
etemplate = message_template_find("pager-default");
if (etemplate->locale) {
ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale));
setlocale(LC_TIME, etemplate->locale);
}
res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter);
}
manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter);
run_externnotify(chan, vmu); /* Run external notification */
if (etemplate->locale)
setlocale(LC_TIME, oldlocale); /* Rest to old locale */
return res;
}
| static int play_record_review | ( | struct ast_channel * | chan, |
| char * | playfile, | ||
| char * | recordfile, | ||
| int | maxtime, | ||
| char * | fmt, | ||
| int | outsidecaller, | ||
| struct minivm_account * | vmu, | ||
| int * | duration, | ||
| const char * | unlockdir, | ||
| signed char | record_gain | ||
| ) | [static] |
Record voicemail message & let caller review or re-record it, or set options if applicable.
Definition at line 1378 of file app_minivm.c.
References acceptdtmf, ast_channel_setoption(), AST_DIGIT_ANY, ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_streamfile(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_waitstream(), global_maxsilence, global_silencethreshold, ast_channel::language, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and vm_delete().
Referenced by leave_voicemail(), and minivm_accmess_exec().
{
int cmd = 0;
int max_attempts = 3;
int attempts = 0;
int recorded = 0;
int message_exists = 0;
signed char zero_gain = 0;
char *acceptdtmf = "#";
char *canceldtmf = "";
/* Note that urgent and private are for flagging messages as such in the future */
/* barf if no pointer passed to store duration in */
if (duration == NULL) {
ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
return -1;
}
cmd = '3'; /* Want to start by recording */
while ((cmd >= 0) && (cmd != 't')) {
switch (cmd) {
case '1':
ast_verb(3, "Saving message as is\n");
ast_stream_and_wait(chan, "vm-msgsaved", "");
cmd = 't';
break;
case '2':
/* Review */
ast_verb(3, "Reviewing the message\n");
ast_streamfile(chan, recordfile, chan->language);
cmd = ast_waitstream(chan, AST_DIGIT_ANY);
break;
case '3':
message_exists = 0;
/* Record */
if (recorded == 1)
ast_verb(3, "Re-recording the message\n");
else
ast_verb(3, "Recording the message\n");
if (recorded && outsidecaller)
cmd = ast_play_and_wait(chan, "beep");
recorded = 1;
/* 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 */
if (record_gain)
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
if (ast_test_flag(vmu, MVM_OPERATOR))
canceldtmf = "0";
cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf);
if (record_gain)
ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
if (cmd == -1) /* User has hung up, no options to give */
return cmd;
if (cmd == '0')
break;
else if (cmd == '*')
break;
else {
/* If all is well, a message exists */
message_exists = 1;
cmd = 0;
}
break;
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '*':
case '#':
cmd = ast_play_and_wait(chan, "vm-sorry");
break;
case '0':
if(!ast_test_flag(vmu, MVM_OPERATOR)) {
cmd = ast_play_and_wait(chan, "vm-sorry");
break;
}
if (message_exists || recorded) {
cmd = ast_play_and_wait(chan, "vm-saveoper");
if (!cmd)
cmd = ast_waitfordigit(chan, 3000);
if (cmd == '1') {
ast_play_and_wait(chan, "vm-msgsaved");
cmd = '0';
} else {
ast_play_and_wait(chan, "vm-deleted");
vm_delete(recordfile);
cmd = '0';
}
}
return cmd;
default:
/* If the caller is an ouside caller, and the review option is enabled,
allow them to review the message, but let the owner of the box review
their OGM's */
if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW))
return cmd;
if (message_exists) {
cmd = ast_play_and_wait(chan, "vm-review");
} else {
cmd = ast_play_and_wait(chan, "vm-torerecord");
if (!cmd)
cmd = ast_waitfordigit(chan, 600);
}
if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) {
cmd = ast_play_and_wait(chan, "vm-reachoper");
if (!cmd)
cmd = ast_waitfordigit(chan, 600);
}
if (!cmd)
cmd = ast_waitfordigit(chan, 6000);
if (!cmd) {
attempts++;
}
if (attempts > max_attempts) {
cmd = 't';
}
}
}
if (outsidecaller)
ast_play_and_wait(chan, "vm-goodbye");
if (cmd == 't')
cmd = 0;
return cmd;
}
| static void populate_defaults | ( | struct minivm_account * | vmu | ) | [static] |
Set default values for Mini-Voicemail users.
Definition at line 903 of file app_minivm.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, minivm_account::attachfmt, default_vmformat, global_volgain, globalflags, and minivm_account::volgain.
Referenced by create_vmaccount(), find_user_realtime(), and mvm_user_alloc().
{
ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);
ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt));
vmu->volgain = global_volgain;
}
| static void prep_email_sub_vars | ( | struct ast_channel * | channel, |
| const struct minivm_account * | vmu, | ||
| const char * | cidnum, | ||
| const char * | cidname, | ||
| const char * | dur, | ||
| const char * | date, | ||
| const char * | counter | ||
| ) | [static] |
Prepare for voicemail template by adding channel variables to the channel.
Definition at line 875 of file app_minivm.c.
References ast_callerid_merge(), ast_log(), ast_strlen_zero(), minivm_account::chanvars, minivm_account::domain, minivm_account::fullname, LOG_ERROR, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), minivm_account::username, ast_variable::value, and var.
Referenced by sendmail().
{
char callerid[256];
struct ast_variable *var;
if (!channel) {
ast_log(LOG_ERROR, "No allocated channel, giving up...\n");
return;
}
for (var = vmu->chanvars ; var ; var = var->next) {
pbx_builtin_setvar_helper(channel, var->name, var->value);
}
/* Prepare variables for substition in email body and subject */
pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname);
pbx_builtin_setvar_helper(channel, "MVM_DUR", dur);
pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain);
pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username);
pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller"));
pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
pbx_builtin_setvar_helper(channel, "MVM_DATE", date);
if (!ast_strlen_zero(counter))
pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter);
}
| static void queue_mwi_event | ( | const char * | mbx, |
| const char * | ctx, | ||
| int | urgent, | ||
| int | new, | ||
| int | old | ||
| ) | [static] |
Queue a message waiting event.
Definition at line 1771 of file app_minivm.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, ast_strlen_zero(), context, and mailbox.
Referenced by minivm_mwi_exec().
{
struct ast_event *event;
char *mailbox, *context;
mailbox = ast_strdupa(mbx);
context = ast_strdupa(ctx);
if (ast_strlen_zero(context)) {
context = "default";
}
if (!(event = ast_event_new(AST_EVENT_MWI,
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent),
AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old,
AST_EVENT_IE_END))) {
return;
}
ast_event_queue_and_cache(event);
}
| static int reload | ( | void | ) | [static] |
Reload mini voicemail module.
Definition at line 3297 of file app_minivm.c.
References load_config().
{
return(load_config(1));
}
| static void run_externnotify | ( | struct ast_channel * | chan, |
| struct minivm_account * | vmu | ||
| ) | [static] |
Run external notification for voicemail message.
Definition at line 1510 of file app_minivm.c.
References ast_debug, ast_safe_system(), ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, minivm_account::domain, minivm_account::externnotify, global_externnotify, and minivm_account::username.
Referenced by notify_new_message().
{
char arguments[BUFSIZ];
if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify))
return;
snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&",
ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify,
vmu->username, vmu->domain,
chan->cid.cid_name, chan->cid.cid_num);
ast_debug(1, "Executing: %s\n", arguments);
ast_safe_system(arguments);
}
| static int sendmail | ( | struct minivm_template * | template, |
| struct minivm_account * | vmu, | ||
| char * | cidnum, | ||
| char * | cidname, | ||
| const char * | filename, | ||
| char * | format, | ||
| int | duration, | ||
| int | attach_user_voicemail, | ||
| enum mvm_messagetype | type, | ||
| const char * | counter | ||
| ) | [static] |
Send voicemail with audio file as an attachment.
Definition at line 1027 of file app_minivm.c.
References ast_channel_alloc(), ast_channel_free(), ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), AST_STATE_DOWN, ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_tvnow(), base_encode(), minivm_account::domain, minivm_account::email, minivm_account::fullname, global_charset, global_mailcmd, LOG_WARNING, mailheader_quote(), MAXHOSTNAMELEN, MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_zone::name, option_debug, minivm_account::pager, pbx_substitute_variables_helper(), prep_email_sub_vars(), minivm_account::serveremail, minivm_zone::timezone, minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.
Referenced by notify_new_message().
{
FILE *p = NULL;
int pfd;
char email[256] = "";
char who[256] = "";
char date[256];
char bound[256];
char fname[PATH_MAX];
char dur[PATH_MAX];
char tmp[80] = "/tmp/astmail-XXXXXX";
char tmp2[PATH_MAX];
struct timeval now;
struct ast_tm tm;
struct minivm_zone *the_zone = NULL;
int len_passdata;
struct ast_channel *ast;
char *finalfilename;
char *passdata = NULL;
char *passdata2 = NULL;
char *fromaddress;
char *fromemail;
if (type == MVM_MESSAGE_EMAIL) {
if (vmu && !ast_strlen_zero(vmu->email)) {
ast_copy_string(email, vmu->email, sizeof(email));
} else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain))
snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain);
} else if (type == MVM_MESSAGE_PAGE) {
ast_copy_string(email, vmu->pager, sizeof(email));
}
if (ast_strlen_zero(email)) {
ast_log(LOG_WARNING, "No address to send message to.\n");
return -1;
}
ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name);
if (!strcmp(format, "wav49"))
format = "WAV";
/* If we have a gain option, process it now with sox */
if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) {
char newtmp[PATH_MAX];
char tmpcmd[PATH_MAX];
int tmpfd;
ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp));
ast_debug(3, "newtmp: %s\n", newtmp);
tmpfd = mkstemp(newtmp);
snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
ast_safe_system(tmpcmd);
finalfilename = newtmp;
ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
} else {
finalfilename = ast_strdupa(filename);
}
/* Create file name */
snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format);
if (template->attachment)
ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail);
/* Make a temporary file instead of piping directly to sendmail, in case the mail
command hangs */
pfd = mkstemp(tmp);
if (pfd > -1) {
p = fdopen(pfd, "w");
if (!p) {
close(pfd);
pfd = -1;
}
ast_debug(1, "Opening temp file for e-mail: %s\n", tmp);
}
if (!p) {
ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp);
return -1;
}
/* Allocate channel used for chanvar substitution */
ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", "");
snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
/* Does this user have a timezone specified? */
if (!ast_strlen_zero(vmu->zonetag)) {
/* Find the zone in the list */
struct minivm_zone *z;
AST_LIST_LOCK(&minivm_zones);
AST_LIST_TRAVERSE(&minivm_zones, z, list) {
if (strcmp(z->name, vmu->zonetag))
continue;
the_zone = z;
}
AST_LIST_UNLOCK(&minivm_zones);
}
now = ast_tvnow();
ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL);
ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
/* Start printing the email to the temporary file */
fprintf(p, "Date: %s\n", date);
/* Set date format for voicemail mail */
ast_strftime(date, sizeof(date), template->dateformat, &tm);
/* Populate channel with channel variables for substitution */
prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter);
/* Find email address to use */
/* If there's a server e-mail adress in the account, user that, othterwise template */
fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail;
/* Find name to user for server e-mail */
fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress;
/* If needed, add hostname as domain */
if (ast_strlen_zero(fromemail))
fromemail = "asterisk";
if (strchr(fromemail, '@'))
ast_copy_string(who, fromemail, sizeof(who));
else {
char host[MAXHOSTNAMELEN];
gethostname(host, sizeof(host)-1);
snprintf(who, sizeof(who), "%s@%s", fromemail, host);
}
if (ast_strlen_zero(fromaddress)) {
fprintf(p, "From: Asterisk PBX <%s>\n", who);
} else {
/* Allocate a buffer big enough for variable substitution */
int vmlen = strlen(fromaddress) * 3 + 200;
ast_debug(4, "Fromaddress template: %s\n", fromaddress);
if ((passdata = alloca(vmlen))) {
pbx_substitute_variables_helper(ast, fromaddress, passdata, vmlen);
len_passdata = strlen(passdata) * 2 + 3;
passdata2 = alloca(len_passdata);
fprintf(p, "From: %s <%s>\n", mailheader_quote(passdata, passdata2, len_passdata), who);
} else {
ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
fclose(p);
return -1;
}
}
ast_debug(4, "Fromstring now: %s\n", ast_strlen_zero(passdata) ? "-default-" : passdata);
fprintf(p, "Message-ID: <Asterisk-%d-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who);
len_passdata = strlen(vmu->fullname) * 2 + 3;
passdata2 = alloca(len_passdata);
if (!ast_strlen_zero(vmu->email))
fprintf(p, "To: %s <%s>\n", mailheader_quote(vmu->fullname, passdata2, len_passdata), vmu->email);
else
fprintf(p, "To: %s <%s@%s>\n", mailheader_quote(vmu->fullname, passdata2, len_passdata), vmu->username, vmu->domain);
if (!ast_strlen_zero(template->subject)) {
char *pass_data;
int vmlen = strlen(template->subject) * 3 + 200;
if ((pass_data = alloca(vmlen))) {
pbx_substitute_variables_helper(ast, template->subject, pass_data, vmlen);
fprintf(p, "Subject: %s\n", pass_data);
} else {
ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
fclose(p);
return -1;
}
ast_debug(4, "Subject now: %s\n", pass_data);
} else {
fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain);
ast_debug(1, "Using default subject for this email \n");
}
if (option_debug > 2)
fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain);
fprintf(p, "MIME-Version: 1.0\n");
/* Something unique. */
snprintf(bound, sizeof(bound), "voicemail_%s%d%d", vmu->username, (int)getpid(), (unsigned int)ast_random());
fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound);
fprintf(p, "--%s\n", bound);
fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", global_charset);
if (!ast_strlen_zero(template->body)) {
char *pass_data;
int vmlen = strlen(template->body)*3 + 200;
if ((pass_data = alloca(vmlen))) {
pbx_substitute_variables_helper(ast, template->body, pass_data, vmlen);
ast_debug(3, "Message now: %s\n-----\n", pass_data);
fprintf(p, "%s\n", pass_data);
} else
ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n");
} else {
fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n"
"in mailbox %s from %s, on %s so you might\n"
"want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname,
dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
ast_debug(3, "Using default message body (no template)\n-----\n");
}
/* Eww. We want formats to tell us their own MIME type */
if (template->attachment) {
char *ctype = "audio/x-";
ast_debug(3, "Attaching file to message: %s\n", fname);
if (!strcasecmp(format, "ogg"))
ctype = "application/";
fprintf(p, "--%s\n", bound);
fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format);
fprintf(p, "Content-Transfer-Encoding: base64\n");
fprintf(p, "Content-Description: Voicemail sound attachment.\n");
fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format);
base_encode(fname, p);
fprintf(p, "\n\n--%s--\n.\n", bound);
}
fclose(p);
snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp);
ast_safe_system(tmp2);
ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : "");
ast_debug(3, "Actual command used: %s\n", tmp2);
if (ast)
ast_channel_free(ast);
return 0;
}
| static int timezone_add | ( | const char * | zonename, |
| const char * | config | ||
| ) | [static] |
Add time zone to memory list.
Definition at line 2411 of file app_minivm.c.
References ast_calloc, ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, global_stats, LOG_WARNING, minivm_zone::msg_format, minivm_zone::name, strsep(), minivm_zone::timezone, and minivm_stats::timezones.
Referenced by load_config().
{
struct minivm_zone *newzone;
char *msg_format, *timezone_str;
newzone = ast_calloc(1, sizeof(*newzone));
if (newzone == NULL)
return 0;
msg_format = ast_strdupa(config);
if (msg_format == NULL) {
ast_log(LOG_WARNING, "Out of memory.\n");
ast_free(newzone);
return 0;
}
timezone_str = strsep(&msg_format, "|");
if (!msg_format) {
ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename);
ast_free(newzone);
return 0;
}
ast_copy_string(newzone->name, zonename, sizeof(newzone->name));
ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone));
ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format));
AST_LIST_LOCK(&minivm_zones);
AST_LIST_INSERT_TAIL(&minivm_zones, newzone, list);
AST_LIST_UNLOCK(&minivm_zones);
global_stats.timezones++;
return 0;
}
| static void timezone_destroy_list | ( | void | ) | [static] |
Clear list of timezones.
Definition at line 2399 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by load_config(), and unload_module().
{
struct minivm_zone *this;
AST_LIST_LOCK(&minivm_zones);
while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list)))
free_zone(this);
AST_LIST_UNLOCK(&minivm_zones);
}
| static int unload_module | ( | void | ) | [static] |
Unload mini voicemail module.
Definition at line 3323 of file app_minivm.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_unregister_application(), cli_minivm, message_destroy_list(), minivm_account_function, minivm_counter_function, timezone_destroy_list(), and vmaccounts_destroy_list().
{
int res;
res = ast_unregister_application(app_minivm_record);
res |= ast_unregister_application(app_minivm_greet);
res |= ast_unregister_application(app_minivm_notify);
res |= ast_unregister_application(app_minivm_delete);
res |= ast_unregister_application(app_minivm_accmess);
res |= ast_unregister_application(app_minivm_mwi);
ast_cli_unregister_multiple(cli_minivm, ARRAY_LEN(cli_minivm));
ast_custom_function_unregister(&minivm_account_function);
ast_custom_function_unregister(&minivm_counter_function);
message_destroy_list(); /* Destroy list of voicemail message templates */
timezone_destroy_list(); /* Destroy list of timezones */
vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */
return res;
}
| static int vm_delete | ( | char * | file | ) | [static] |
Delete media files and attribute file.
Definition at line 1365 of file app_minivm.c.
References ast_debug, and ast_filedelete().
Referenced by minivm_delete_exec(), and play_record_review().
{
int res;
ast_debug(1, "Deleting voicemail file %s\n", file);
res = unlink(file); /* Remove the meta data file */
res |= ast_filedelete(file, NULL); /* remove the media file */
return res;
}
| static int vm_lock_path | ( | const char * | path | ) | [static] |
lock directory
only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason
Definition at line 3019 of file app_minivm.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by access_counter_file().
{
switch (ast_lock_path(path)) {
case AST_LOCK_TIMEOUT:
return -1;
default:
return 0;
}
}
| static void vmaccounts_destroy_list | ( | void | ) | [static] |
Clear list of users.
Definition at line 944 of file app_minivm.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
Referenced by load_config(), and unload_module().
{
struct minivm_account *this;
AST_LIST_LOCK(&minivm_accounts);
while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list)))
ast_free(this);
AST_LIST_UNLOCK(&minivm_accounts);
}
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3350 of file app_minivm.c.
char* app_minivm_accmess = "MinivmAccMess" [static] |
Definition at line 453 of file app_minivm.c.
char* app_minivm_delete = "MinivmDelete" [static] |
Definition at line 452 of file app_minivm.c.
char* app_minivm_greet = "MinivmGreet" [static] |
Definition at line 450 of file app_minivm.c.
char* app_minivm_mwi = "MinivmMWI" [static] |
Definition at line 454 of file app_minivm.c.
char* app_minivm_notify = "MinivmNotify" [static] |
Definition at line 451 of file app_minivm.c.
char* app_minivm_record = "MinivmRecord" [static] |
Definition at line 449 of file app_minivm.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 3350 of file app_minivm.c.
struct ast_cli_entry cli_minivm[] [static] |
CLI commands for Mini-voicemail.
Definition at line 3220 of file app_minivm.c.
Referenced by load_module(), and unload_module().
char default_vmformat[80] [static] |
Definition at line 587 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), load_config(), minivm_accmess_exec(), and populate_defaults().
char global_charset[32] [static] |
Global charset in messages
Definition at line 591 of file app_minivm.c.
Referenced by load_config(), and sendmail().
char global_externnotify[160] [static] |
External notification application
Definition at line 585 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and run_externnotify().
char global_logfile[PATH_MAX] [static] |
Global log file for messages
Definition at line 586 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), and load_config().
char global_mailcmd[160] [static] |
Configurable mail cmd
Definition at line 584 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and sendmail().
int global_maxgreet [static] |
Maximum length of prompts
Definition at line 582 of file app_minivm.c.
Referenced by apply_general_options(), load_config(), and minivm_accmess_exec().
int global_maxsilence [static] |
Maximum silence during recording
Definition at line 581 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
int global_saydurationminfo [static] |
Definition at line 590 of file app_minivm.c.
Referenced by load_config().
int global_silencethreshold = 128 [static] |
Definition at line 583 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
struct minivm_stats global_stats [static] |
Statistics for voicemail.
Definition at line 572 of file app_minivm.c.
Referenced by create_vmaccount(), handle_minivm_show_stats(), leave_voicemail(), load_config(), message_template_build(), and timezone_add().
int global_vmmaxmessage [static] |
Maximum duration of message
Definition at line 580 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), and load_config().
int global_vmminmessage [static] |
Minimum duration of messages
Definition at line 579 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), and load_config().
double global_volgain [static] |
Volume gain for voicmemail via e-mail
Definition at line 593 of file app_minivm.c.
Referenced by populate_defaults().
struct ast_flags globalflags = {0} [static] |
Global voicemail flags
Definition at line 589 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and populate_defaults().
struct message_templates message_templates [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] |
Definition at line 484 of file app_minivm.c.
Referenced by minivm_accmess_exec().
struct ast_custom_function minivm_account_function [static] |
Definition at line 3248 of file app_minivm.c.
Referenced by load_module(), and unload_module().
struct minivm_accounts minivm_accounts [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] |
Definition at line 477 of file app_minivm.c.
Referenced by minivm_greet_exec(), and minivm_record_exec().
struct ast_custom_function minivm_counter_function [static] |
Definition at line 3229 of file app_minivm.c.
Referenced by load_module(), and unload_module().
| enum { ... } minivm_option_args |
| enum { ... } minivm_option_flags |
struct minivm_zones minivm_zones [static] |
ast_mutex_t minivmlock = AST_MUTEX_INIT_VALUE [static] |
Lock to protect voicemail system
Definition at line 574 of file app_minivm.c.
Referenced by load_config().
| FILE* minivmlogfile |
The minivm log file
Definition at line 577 of file app_minivm.c.
Referenced by leave_voicemail(), and load_config().
ast_mutex_t minivmloglock = AST_MUTEX_INIT_VALUE [static] |
Lock to protect voicemail system log file
Definition at line 575 of file app_minivm.c.
Referenced by leave_voicemail().
char MVM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 446 of file app_minivm.c.