#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"
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_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 int | reload (void) |
Reload mini voicemail module. | |
static void | run_externnotify (struct ast_channel *chan, struct minivm_account *vmu) |
Run external notification for voicemail message. | |
static int | sendmail (struct minivm_template *template, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type, const char *counter) |
Send voicemail with audio file as an attachment. | |
static int | timezone_add (const char *zonename, const char *config) |
Add time zone to memory list. | |
static void | timezone_destroy_list (void) |
Clear list of timezones. | |
static int | unload_module (void) |
Unload mini voicemail module. | |
static int | vm_delete (char *file) |
Delete media files and attribute file. | |
static int | vm_lock_path (const char *path) |
lock directory | |
static void | vmaccounts_destroy_list (void) |
Clear list of users. | |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .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_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 * | descrip_minivm_accmess |
static char * | descrip_minivm_delete |
static char * | descrip_minivm_greet |
static char * | descrip_minivm_notify |
static char * | descrip_minivm_record |
static char | global_charset [32] |
static char | global_externnotify [160] |
static char | global_logfile [PATH_MAX] |
static char | global_mailcmd [160] |
static int | global_maxgreet |
static int | global_maxsilence |
static int | global_saydurationminfo |
static int | global_silencethreshold = 128 |
static struct minivm_stats | global_stats |
Statistics for voicemail. | |
static int | global_vmmaxmessage |
static int | global_vmminmessage |
static double | global_volgain |
static struct ast_flags | globalflags = {0} |
static struct ast_app_option | minivm_accmess_options [128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING },} |
static struct ast_custom_function | minivm_account_function |
static struct ast_app_option | minivm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 },} |
static struct ast_custom_function | minivm_counter_function |
enum { ... } | minivm_option_args |
enum { ... } | minivm_option_flags |
static ast_mutex_t | minivmlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
FILE * | minivmlogfile |
static ast_mutex_t | minivmloglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
static char | MVM_SPOOL_DIR [PATH_MAX] |
static char * | synopsis_minivm_accmess = "Record account specific messages" |
static char * | synopsis_minivm_delete = "Delete Mini-Voicemail voicemail messages" |
static char * | synopsis_minivm_greet = "Play Mini-Voicemail prompts" |
static char * | synopsis_minivm_notify = "Notify voicemail owner about new messages." |
static char * | synopsis_minivm_record = "Receive Mini-Voicemail and forward via e-mail" |
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 206 of file app_minivm.c.
Referenced by load_config().
#define B64_BASELINELEN 72 |
Line length for Base 64 endoded messages
Definition at line 196 of file app_minivm.c.
Referenced by b64_ochar().
#define B64_BASEMAXINLINE 256 |
Buffer size for Base 64 attachment encoding
Definition at line 195 of file app_minivm.c.
Referenced by b64_inbuf(), and base_encode().
#define DEFAULT_CHARSET "ISO-8859-1" |
#define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
Default dateformat, can be overridden in configuration file.
Definition at line 450 of file app_minivm.c.
Referenced by message_template_create().
#define EOL "\r\n" |
#define ERROR_LOCK_PATH -100 |
Definition at line 202 of file app_minivm.c.
Referenced by close_mailbox(), copy_message(), count_messages(), minivm_record_exec(), save_to_folder(), vm_exec(), and vm_execmain().
#define FALSE 0 |
Definition at line 178 of file app_minivm.c.
#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 199 of file app_minivm.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 200 of file app_minivm.c.
Referenced by load_config(), and play_message_callerid().
#define MVM_ALLOCED (1 << 13) |
Definition at line 188 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 186 of file app_minivm.c.
#define MVM_OPERATOR (1 << 1) |
Operator exit during voicemail recording
Definition at line 183 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 187 of file app_minivm.c.
#define MVM_REALTIME (1 << 2) |
This user is a realtime account
Definition at line 184 of file app_minivm.c.
#define MVM_REVIEW (1 << 0) |
Review message
Definition at line 182 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 185 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 192 of file app_minivm.c.
Referenced by load_config().
#define SOUND_INTRO "vm-intro" |
#define TRUE 1 |
Definition at line 175 of file app_minivm.c.
#define VOICEMAIL_CONFIG "minivm.conf" |
Definition at line 205 of file app_minivm.c.
#define VOICEMAIL_DIR_MODE 0700 |
anonymous enum |
OPT_SILENT | |
OPT_BUSY_GREETING | |
OPT_UNAVAIL_GREETING | |
OPT_TEMP_GREETING | |
OPT_NAME_GREETING | |
OPT_RECORDGAIN |
Definition at line 312 of file app_minivm.c.
00312 { 00313 OPT_SILENT = (1 << 0), 00314 OPT_BUSY_GREETING = (1 << 1), 00315 OPT_UNAVAIL_GREETING = (1 << 2), 00316 OPT_TEMP_GREETING = (1 << 3), 00317 OPT_NAME_GREETING = (1 << 4), 00318 OPT_RECORDGAIN = (1 << 5), 00319 } minivm_option_flags;
anonymous enum |
Definition at line 321 of file app_minivm.c.
00321 { 00322 OPT_ARG_RECORDGAIN = 0, 00323 OPT_ARG_ARRAY_SIZE = 1, 00324 } minivm_option_args;
enum mvm_messagetype |
Message types for notification.
Definition at line 209 of file app_minivm.c.
00209 { 00210 MVM_MESSAGE_EMAIL, 00211 MVM_MESSAGE_PAGE 00212 /* For trunk: MVM_MESSAGE_JABBER, */ 00213 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 3132 of file app_minivm.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 3132 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 2821 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().
02822 { 02823 char filename[BUFSIZ]; 02824 char readbuf[BUFSIZ]; 02825 FILE *counterfile; 02826 int old = 0, counter = 0; 02827 02828 /* Lock directory */ 02829 if (vm_lock_path(directory)) { 02830 return -1; /* Could not lock directory */ 02831 } 02832 snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername); 02833 if (operand != 1) { 02834 counterfile = fopen(filename, "r"); 02835 if (counterfile) { 02836 if(fgets(readbuf, sizeof(readbuf), counterfile)) { 02837 ast_debug(3, "Read this string from counter file: %s\n", readbuf); 02838 old = counter = atoi(readbuf); 02839 } 02840 fclose(counterfile); 02841 } 02842 } 02843 switch (operand) { 02844 case 0: /* Read only */ 02845 ast_unlock_path(directory); 02846 ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter); 02847 return counter; 02848 break; 02849 case 1: /* Set new value */ 02850 counter = value; 02851 break; 02852 case 2: /* Change value */ 02853 counter += value; 02854 if (counter < 0) /* Don't allow counters to fall below zero */ 02855 counter = 0; 02856 break; 02857 } 02858 02859 /* Now, write the new value to the file */ 02860 counterfile = fopen(filename, "w"); 02861 if (!counterfile) { 02862 ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno)); 02863 ast_unlock_path(directory); 02864 return -1; /* Could not open file for writing */ 02865 } 02866 fprintf(counterfile, "%d\n\n", counter); 02867 fclose(counterfile); 02868 ast_unlock_path(directory); 02869 ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter); 02870 return counter; 02871 }
static int apply_general_options | ( | struct ast_variable * | var | ) | [static] |
Apply general configuration options.
Definition at line 2304 of file app_minivm.c.
References ast_config_AST_LOG_DIR, ast_copy_string(), ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), default_vmformat, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and var.
Referenced by load_config().
02305 { 02306 int error = 0; 02307 02308 while (var) { 02309 /* Mail command */ 02310 if (!strcmp(var->name, "mailcmd")) { 02311 ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */ 02312 } else if (!strcmp(var->name, "maxgreet")) { 02313 global_maxgreet = atoi(var->value); 02314 } else if (!strcmp(var->name, "maxsilence")) { 02315 global_maxsilence = atoi(var->value); 02316 if (global_maxsilence > 0) 02317 global_maxsilence *= 1000; 02318 } else if (!strcmp(var->name, "logfile")) { 02319 if (!ast_strlen_zero(var->value) ) { 02320 if(*(var->value) == '/') 02321 ast_copy_string(global_logfile, var->value, sizeof(global_logfile)); 02322 else 02323 snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value); 02324 } 02325 } else if (!strcmp(var->name, "externnotify")) { 02326 /* External voicemail notify application */ 02327 ast_copy_string(global_externnotify, var->value, sizeof(global_externnotify)); 02328 } else if (!strcmp(var->name, "silencetreshold")) { 02329 /* Silence treshold */ 02330 global_silencethreshold = atoi(var->value); 02331 } else if (!strcmp(var->name, "maxmessage")) { 02332 int x; 02333 if (sscanf(var->value, "%30d", &x) == 1) { 02334 global_vmmaxmessage = x; 02335 } else { 02336 error ++; 02337 ast_log(LOG_WARNING, "Invalid max message time length\n"); 02338 } 02339 } else if (!strcmp(var->name, "minmessage")) { 02340 int x; 02341 if (sscanf(var->value, "%30d", &x) == 1) { 02342 global_vmminmessage = x; 02343 if (global_maxsilence <= global_vmminmessage) 02344 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 02345 } else { 02346 error ++; 02347 ast_log(LOG_WARNING, "Invalid min message time length\n"); 02348 } 02349 } else if (!strcmp(var->name, "format")) { 02350 ast_copy_string(default_vmformat, var->value, sizeof(default_vmformat)); 02351 } else if (!strcmp(var->name, "review")) { 02352 ast_set2_flag((&globalflags), ast_true(var->value), MVM_REVIEW); 02353 } else if (!strcmp(var->name, "operator")) { 02354 ast_set2_flag((&globalflags), ast_true(var->value), MVM_OPERATOR); 02355 } 02356 var = var->next; 02357 } 02358 return error; 02359 }
static int b64_inbuf | ( | struct b64_baseio * | bio, | |
FILE * | fi | |||
) | [static] |
read buffer from file (base64 conversion)
Definition at line 583 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().
00584 { 00585 int l; 00586 00587 if (bio->ateof) 00588 return 0; 00589 00590 if ((l = fread(bio->iobuf, 1, B64_BASEMAXINLINE,fi)) <= 0) { 00591 if (ferror(fi)) 00592 return -1; 00593 00594 bio->ateof = 1; 00595 return 0; 00596 } 00597 00598 bio->iolen= l; 00599 bio->iocp= 0; 00600 00601 return 1; 00602 }
static int b64_inchar | ( | struct b64_baseio * | bio, | |
FILE * | fi | |||
) | [static] |
read character from file to buffer (base64 conversion)
Definition at line 605 of file app_minivm.c.
References b64_inbuf(), b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by base_encode().
00606 { 00607 if (bio->iocp >= bio->iolen) { 00608 if (!b64_inbuf(bio, fi)) 00609 return EOF; 00610 } 00611 00612 return bio->iobuf[bio->iocp++]; 00613 }
static int b64_ochar | ( | struct b64_baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
write buffer to file (base64 conversion)
Definition at line 616 of file app_minivm.c.
References B64_BASELINELEN, EOL, and b64_baseio::linelength.
Referenced by base_encode().
00617 { 00618 if (bio->linelength >= B64_BASELINELEN) { 00619 if (fputs(EOL,so) == EOF) 00620 return -1; 00621 00622 bio->linelength= 0; 00623 } 00624 00625 if (putc(((unsigned char) c), so) == EOF) 00626 return -1; 00627 00628 bio->linelength++; 00629 00630 return 1; 00631 }
static int base_encode | ( | char * | filename, | |
FILE * | so | |||
) | [static] |
Encode file to base64 encoding for email attachment (base64 conversion).
Definition at line 634 of file app_minivm.c.
References ast_log(), B64_BASEMAXINLINE, b64_inchar(), b64_ochar(), EOL, errno, and LOG_WARNING.
Referenced by add_email_attachment(), and sendmail().
00635 { 00636 unsigned char dtable[B64_BASEMAXINLINE]; 00637 int i,hiteof= 0; 00638 FILE *fi; 00639 struct b64_baseio bio; 00640 00641 memset(&bio, 0, sizeof(bio)); 00642 bio.iocp = B64_BASEMAXINLINE; 00643 00644 if (!(fi = fopen(filename, "rb"))) { 00645 ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 00646 return -1; 00647 } 00648 00649 for (i= 0; i<9; i++) { 00650 dtable[i]= 'A'+i; 00651 dtable[i+9]= 'J'+i; 00652 dtable[26+i]= 'a'+i; 00653 dtable[26+i+9]= 'j'+i; 00654 } 00655 for (i= 0; i < 8; i++) { 00656 dtable[i+18]= 'S'+i; 00657 dtable[26+i+18]= 's'+i; 00658 } 00659 for (i= 0; i < 10; i++) { 00660 dtable[52+i]= '0'+i; 00661 } 00662 dtable[62]= '+'; 00663 dtable[63]= '/'; 00664 00665 while (!hiteof){ 00666 unsigned char igroup[3], ogroup[4]; 00667 int c,n; 00668 00669 igroup[0]= igroup[1]= igroup[2]= 0; 00670 00671 for (n= 0; n < 3; n++) { 00672 if ((c = b64_inchar(&bio, fi)) == EOF) { 00673 hiteof= 1; 00674 break; 00675 } 00676 igroup[n]= (unsigned char)c; 00677 } 00678 00679 if (n> 0) { 00680 ogroup[0]= dtable[igroup[0]>>2]; 00681 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 00682 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 00683 ogroup[3]= dtable[igroup[2]&0x3F]; 00684 00685 if (n<3) { 00686 ogroup[3]= '='; 00687 00688 if (n<2) 00689 ogroup[2]= '='; 00690 } 00691 00692 for (i= 0;i<4;i++) 00693 b64_ochar(&bio, ogroup[i], so); 00694 } 00695 } 00696 00697 /* Put end of line - line feed */ 00698 if (fputs(EOL, so) == EOF) 00699 return 0; 00700 00701 fclose(fi); 00702 00703 return 1; 00704 }
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 1130 of file app_minivm.c.
References FALSE, make_dir(), and TRUE.
Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().
01131 { 01132 struct stat filestat; 01133 make_dir(dest, len, domain, username, folder ? folder : ""); 01134 if (stat(dest, &filestat)== -1) 01135 return FALSE; 01136 else 01137 return TRUE; 01138 }
static char* complete_minivm_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2540 of file app_minivm.c.
References AST_LIST_TRAVERSE, ast_strdup, minivm_account::domain, and minivm_account::list.
Referenced by handle_minivm_show_users().
02541 { 02542 int which = 0; 02543 int wordlen; 02544 struct minivm_account *vmu; 02545 const char *domain = ""; 02546 02547 /* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */ 02548 if (pos > 4) 02549 return NULL; 02550 if (pos == 3) 02551 return (state == 0) ? ast_strdup("for") : NULL; 02552 wordlen = strlen(word); 02553 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 02554 if (!strncasecmp(word, vmu->domain, wordlen)) { 02555 if (domain && strcmp(domain, vmu->domain) && ++which > state) 02556 return ast_strdup(vmu->domain); 02557 /* ignore repeated domains ? */ 02558 domain = vmu->domain; 02559 } 02560 } 02561 return NULL; 02562 }
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 1148 of file app_minivm.c.
References ast_debug, ast_log(), ast_mkdir(), LOG_WARNING, and make_dir().
Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), minivm_counter_func_read(), minivm_counter_func_write(), open_mailbox(), and save_to_folder().
01149 { 01150 int res; 01151 make_dir(dest, len, domain, username, folder); 01152 if ((res = ast_mkdir(dest, 0777))) { 01153 ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01154 return -1; 01155 } 01156 ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest); 01157 return 0; 01158 }
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 2088 of file app_minivm.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_new(), global_stats, minivm_account::list, LOG_ERROR, ast_variable::next, populate_defaults(), minivm_account::username, var, and minivm_stats::voicemailaccounts.
Referenced by find_user_realtime(), and load_config().
02089 { 02090 struct minivm_account *vmu; 02091 char *domain; 02092 char *username; 02093 char accbuf[BUFSIZ]; 02094 02095 ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name); 02096 02097 ast_copy_string(accbuf, name, sizeof(accbuf)); 02098 username = accbuf; 02099 domain = strchr(accbuf, '@'); 02100 if (domain) { 02101 *domain = '\0'; 02102 domain++; 02103 } 02104 if (ast_strlen_zero(domain)) { 02105 ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name); 02106 return 0; 02107 } 02108 02109 ast_debug(3, "Creating static account for user %s domain %s\n", username, domain); 02110 02111 /* Allocate user account */ 02112 vmu = ast_calloc(1, sizeof(*vmu)); 02113 if (!vmu) 02114 return 0; 02115 02116 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 02117 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 02118 02119 populate_defaults(vmu); 02120 02121 ast_debug(3, "...Configuring account %s\n", name); 02122 02123 while (var) { 02124 ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name); 02125 if (!strcasecmp(var->name, "serveremail")) { 02126 ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail)); 02127 } else if (!strcasecmp(var->name, "email")) { 02128 ast_copy_string(vmu->email, var->value, sizeof(vmu->email)); 02129 } else if (!strcasecmp(var->name, "accountcode")) { 02130 ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode)); 02131 } else if (!strcasecmp(var->name, "pincode")) { 02132 ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode)); 02133 } else if (!strcasecmp(var->name, "domain")) { 02134 ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain)); 02135 } else if (!strcasecmp(var->name, "language")) { 02136 ast_copy_string(vmu->language, var->value, sizeof(vmu->language)); 02137 } else if (!strcasecmp(var->name, "timezone")) { 02138 ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag)); 02139 } else if (!strcasecmp(var->name, "externnotify")) { 02140 ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify)); 02141 } else if (!strcasecmp(var->name, "etemplate")) { 02142 ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate)); 02143 } else if (!strcasecmp(var->name, "ptemplate")) { 02144 ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate)); 02145 } else if (!strcasecmp(var->name, "fullname")) { 02146 ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname)); 02147 } else if (!strcasecmp(var->name, "setvar")) { 02148 char *varval; 02149 char *varname = ast_strdupa(var->value); 02150 struct ast_variable *tmpvar; 02151 02152 if (varname && (varval = strchr(varname, '='))) { 02153 *varval = '\0'; 02154 varval++; 02155 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 02156 tmpvar->next = vmu->chanvars; 02157 vmu->chanvars = tmpvar; 02158 } 02159 } 02160 } else if (!strcasecmp(var->name, "pager")) { 02161 ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager)); 02162 } else if (!strcasecmp(var->name, "volgain")) { 02163 sscanf(var->value, "%30lf", &vmu->volgain); 02164 } else { 02165 ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name); 02166 } 02167 var = var->next; 02168 } 02169 ast_debug(3, "...Linking account %s\n", name); 02170 02171 AST_LIST_LOCK(&minivm_accounts); 02172 AST_LIST_INSERT_TAIL(&minivm_accounts, vmu, list); 02173 AST_LIST_UNLOCK(&minivm_accounts); 02174 02175 global_stats.voicemailaccounts++; 02176 02177 ast_debug(2, "MINIVM :: 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)" : ""); 02178 return 0; 02179 }
static struct minivm_account* find_account | ( | const char * | domain, | |
const char * | username, | |||
int | createtemp | |||
) | [static] |
Find user from static memory object list.
Definition at line 809 of file app_minivm.c.
References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set2_flag, ast_strlen_zero(), minivm_account::domain, find_user_realtime(), minivm_account::list, LOG_NOTICE, MVM_ALLOCED, mvm_user_alloc(), TRUE, and minivm_account::username.
Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_counter_func_read(), minivm_counter_func_write(), minivm_greet_exec(), and minivm_notify_exec().
00810 { 00811 struct minivm_account *vmu = NULL, *cur; 00812 00813 00814 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 00815 ast_log(LOG_NOTICE, "No username or domain? \n"); 00816 return NULL; 00817 } 00818 ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain); 00819 00820 AST_LIST_LOCK(&minivm_accounts); 00821 AST_LIST_TRAVERSE(&minivm_accounts, cur, list) { 00822 /* Is this the voicemail account we're looking for? */ 00823 if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username)) 00824 break; 00825 } 00826 AST_LIST_UNLOCK(&minivm_accounts); 00827 00828 if (cur) { 00829 ast_debug(3, "Found account for %s@%s\n", username, domain); 00830 vmu = cur; 00831 00832 } else 00833 vmu = find_user_realtime(domain, username); 00834 00835 if (createtemp && !vmu) { 00836 /* Create a temporary user, send e-mail and be gone */ 00837 vmu = mvm_user_alloc(); 00838 ast_set2_flag(vmu, TRUE, MVM_ALLOCED); 00839 if (vmu) { 00840 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 00841 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 00842 ast_debug(1, "Created temporary account\n"); 00843 } 00844 00845 } 00846 return vmu; 00847 }
static struct minivm_account * find_user_realtime | ( | const char * | domain, | |
const char * | username | |||
) | [static] |
Find user in realtime storage Returns pointer to minivm_account structure.
Definition at line 852 of file app_minivm.c.
References ast_copy_string(), ast_free, ast_load_realtime(), ast_variables_destroy(), create_vmaccount(), MAXHOSTNAMELEN, mvm_user_alloc(), populate_defaults(), SENTINEL, TRUE, minivm_account::username, and var.
Referenced by find_account(), and find_user().
00853 { 00854 struct ast_variable *var; 00855 struct minivm_account *retval; 00856 char name[MAXHOSTNAMELEN]; 00857 00858 retval = mvm_user_alloc(); 00859 if (!retval) 00860 return NULL; 00861 00862 if (username) 00863 ast_copy_string(retval->username, username, sizeof(retval->username)); 00864 00865 populate_defaults(retval); 00866 var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL); 00867 00868 if (!var) { 00869 ast_free(retval); 00870 return NULL; 00871 } 00872 00873 snprintf(name, sizeof(name), "%s@%s", username, domain); 00874 create_vmaccount(name, var, TRUE); 00875 00876 ast_variables_destroy(var); 00877 return retval; 00878 }
static void free_user | ( | struct minivm_account * | vmu | ) | [static] |
Free user structure - if it's allocated.
Definition at line 717 of file app_minivm.c.
References ast_free, ast_variables_destroy(), and minivm_account::chanvars.
Referenced by forward_message(), free_vm_users(), leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), and vm_execmain().
00718 { 00719 if (vmu->chanvars) 00720 ast_variables_destroy(vmu->chanvars); 00721 ast_free(vmu); 00722 }
static void free_zone | ( | struct minivm_zone * | z | ) | [static] |
Free Mini Voicemail timezone.
Definition at line 2182 of file app_minivm.c.
References ast_free.
02183 { 02184 ast_free(z); 02185 }
static int get_date | ( | char * | s, | |
int | len | |||
) | [static] |
Definition at line 706 of file app_minivm.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail(), and tds_log().
00707 { 00708 struct ast_tm tm; 00709 struct timeval now = ast_tvnow(); 00710 00711 ast_localtime(&now, &tm, NULL); 00712 return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm); 00713 }
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 2499 of file app_minivm.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVLT_OUTPUT_FORMAT, minivm_account::list, and ast_cli_entry::usage.
02500 { 02501 struct minivm_template *this; 02502 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" 02503 int count = 0; 02504 02505 switch (cmd) { 02506 case CLI_INIT: 02507 e->command = "minivm list templates"; 02508 e->usage = 02509 "Usage: minivm list templates\n" 02510 " Lists message templates for e-mail, paging and IM\n"; 02511 return NULL; 02512 case CLI_GENERATE: 02513 return NULL; 02514 } 02515 02516 if (a->argc > 3) 02517 return CLI_SHOWUSAGE; 02518 02519 AST_LIST_LOCK(&message_templates); 02520 if (AST_LIST_EMPTY(&message_templates)) { 02521 ast_cli(a->fd, "There are no message templates defined\n"); 02522 AST_LIST_UNLOCK(&message_templates); 02523 return CLI_FAILURE; 02524 } 02525 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject"); 02526 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------"); 02527 AST_LIST_TRAVERSE(&message_templates, this, list) { 02528 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name, 02529 this->charset ? this->charset : "-", 02530 this->locale ? this->locale : "-", 02531 this->attachment ? "Yes" : "No", 02532 this->subject ? this->subject : "-"); 02533 count++; 02534 } 02535 AST_LIST_UNLOCK(&message_templates); 02536 ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count); 02537 return CLI_SUCCESS; 02538 }
static char * handle_minivm_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Reload cofiguration.
Definition at line 3087 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.
03088 { 03089 03090 switch (cmd) { 03091 case CLI_INIT: 03092 e->command = "minivm reload"; 03093 e->usage = 03094 "Usage: minivm reload\n" 03095 " Reload mini-voicemail configuration and reset statistics\n"; 03096 return NULL; 03097 case CLI_GENERATE: 03098 return NULL; 03099 } 03100 03101 reload(); 03102 ast_cli(a->fd, "\n-- Mini voicemail re-configured \n"); 03103 return CLI_SUCCESS; 03104 }
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 2650 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.
02651 { 02652 switch (cmd) { 02653 case CLI_INIT: 02654 e->command = "minivm show settings"; 02655 e->usage = 02656 "Usage: minivm show settings\n" 02657 " Display Mini-Voicemail general settings\n"; 02658 return NULL; 02659 case CLI_GENERATE: 02660 return NULL; 02661 } 02662 02663 ast_cli(a->fd, "* Mini-Voicemail general settings\n"); 02664 ast_cli(a->fd, " -------------------------------\n"); 02665 ast_cli(a->fd, "\n"); 02666 ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd); 02667 ast_cli(a->fd, " Max silence: %d\n", global_maxsilence); 02668 ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold); 02669 ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage); 02670 ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage); 02671 ast_cli(a->fd, " Default format: %s\n", default_vmformat); 02672 ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify); 02673 ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>"); 02674 ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No"); 02675 ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No"); 02676 02677 ast_cli(a->fd, "\n"); 02678 return CLI_SUCCESS; 02679 }
static char* handle_minivm_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show stats.
Definition at line 2682 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.
02683 { 02684 struct ast_tm timebuf; 02685 char buf[BUFSIZ]; 02686 02687 switch (cmd) { 02688 02689 case CLI_INIT: 02690 e->command = "minivm show stats"; 02691 e->usage = 02692 "Usage: minivm show stats\n" 02693 " Display Mini-Voicemail counters\n"; 02694 return NULL; 02695 case CLI_GENERATE: 02696 return NULL; 02697 } 02698 02699 ast_cli(a->fd, "* Mini-Voicemail statistics\n"); 02700 ast_cli(a->fd, " -------------------------\n"); 02701 ast_cli(a->fd, "\n"); 02702 ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts); 02703 ast_cli(a->fd, " Templates: %5d\n", global_stats.templates); 02704 ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones); 02705 if (global_stats.receivedmessages == 0) { 02706 ast_cli(a->fd, " Received messages since last reset: <none>\n"); 02707 } else { 02708 ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages); 02709 ast_localtime(&global_stats.lastreceived, &timebuf, NULL); 02710 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 02711 ast_cli(a->fd, " Last received voicemail: %s\n", buf); 02712 } 02713 ast_localtime(&global_stats.reset, &timebuf, NULL); 02714 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 02715 ast_cli(a->fd, " Last reset: %s\n", buf); 02716 02717 ast_cli(a->fd, "\n"); 02718 return CLI_SUCCESS; 02719 }
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 2565 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, minivm_account::attachfmt, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_minivm_show_users(), minivm_account::domain, minivm_account::etemplate, ast_cli_args::fd, minivm_account::fullname, HMSU_OUTPUT_FORMAT, ast_cli_args::line, minivm_account::list, ast_cli_args::n, ast_cli_args::pos, minivm_account::ptemplate, ast_cli_entry::usage, minivm_account::username, ast_cli_args::word, and minivm_account::zonetag.
02566 { 02567 struct minivm_account *vmu; 02568 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" 02569 int count = 0; 02570 02571 switch (cmd) { 02572 case CLI_INIT: 02573 e->command = "minivm list accounts"; 02574 e->usage = 02575 "Usage: minivm list accounts\n" 02576 " Lists all mailboxes currently set up\n"; 02577 return NULL; 02578 case CLI_GENERATE: 02579 return complete_minivm_show_users(a->line, a->word, a->pos, a->n); 02580 } 02581 02582 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 02583 return CLI_SHOWUSAGE; 02584 if ((a->argc == 5) && strcmp(a->argv[3],"for")) 02585 return CLI_SHOWUSAGE; 02586 02587 AST_LIST_LOCK(&minivm_accounts); 02588 if (AST_LIST_EMPTY(&minivm_accounts)) { 02589 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 02590 AST_LIST_UNLOCK(&minivm_accounts); 02591 return CLI_FAILURE; 02592 } 02593 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name"); 02594 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------"); 02595 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 02596 char tmp[256] = ""; 02597 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) { 02598 count++; 02599 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain); 02600 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-", 02601 vmu->ptemplate ? vmu->ptemplate : "-", 02602 vmu->zonetag ? vmu->zonetag : "-", 02603 vmu->attachfmt ? vmu->attachfmt : "-", 02604 vmu->fullname); 02605 } 02606 } 02607 AST_LIST_UNLOCK(&minivm_accounts); 02608 ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count); 02609 return CLI_SUCCESS; 02610 }
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 2613 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HMSZ_OUTPUT_FORMAT, minivm_account::list, minivm_zone::msg_format, minivm_zone::name, minivm_zone::timezone, and ast_cli_entry::usage.
02614 { 02615 struct minivm_zone *zone; 02616 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 02617 char *res = CLI_SUCCESS; 02618 02619 switch (cmd) { 02620 case CLI_INIT: 02621 e->command = "minivm list zones"; 02622 e->usage = 02623 "Usage: minivm list zones\n" 02624 " Lists zone message formats\n"; 02625 return NULL; 02626 case CLI_GENERATE: 02627 return NULL; 02628 } 02629 02630 if (a->argc != e->args) 02631 return CLI_SHOWUSAGE; 02632 02633 AST_LIST_LOCK(&minivm_zones); 02634 if (!AST_LIST_EMPTY(&minivm_zones)) { 02635 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 02636 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------"); 02637 AST_LIST_TRAVERSE(&minivm_zones, zone, list) { 02638 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 02639 } 02640 } else { 02641 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 02642 res = CLI_FAILURE; 02643 } 02644 AST_LIST_UNLOCK(&minivm_zones); 02645 02646 return res; 02647 }
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 1163 of file app_minivm.c.
References ast_debug, ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), chan, FALSE, and ast_channel::language.
Referenced by leave_voicemail(), and minivm_greet_exec().
01164 { 01165 int res; 01166 char fn[PATH_MAX]; 01167 01168 ast_debug(2, "Still preparing to play message ...\n"); 01169 01170 snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username); 01171 01172 if (ast_fileexists(fn, NULL, NULL) > 0) { 01173 res = ast_streamfile(chan, fn, chan->language); 01174 if (res) 01175 return -1; 01176 res = ast_waitstream(chan, ecodes); 01177 if (res) 01178 return res; 01179 } else { 01180 int numericusername = 1; 01181 char *i = username; 01182 01183 ast_debug(2, "No personal prompts. Using default prompt set for language\n"); 01184 01185 while (*i) { 01186 ast_debug(2, "Numeric? Checking %c\n", *i); 01187 if (!isdigit(*i)) { 01188 numericusername = FALSE; 01189 break; 01190 } 01191 i++; 01192 } 01193 01194 if (numericusername) { 01195 if(ast_streamfile(chan, "vm-theperson", chan->language)) 01196 return -1; 01197 if ((res = ast_waitstream(chan, ecodes))) 01198 return res; 01199 01200 res = ast_say_digit_str(chan, username, ecodes, chan->language); 01201 if (res) 01202 return res; 01203 } else { 01204 if(ast_streamfile(chan, "vm-theextensionis", chan->language)) 01205 return -1; 01206 if ((res = ast_waitstream(chan, ecodes))) 01207 return res; 01208 } 01209 } 01210 01211 res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language); 01212 if (res) 01213 return -1; 01214 res = ast_waitstream(chan, ecodes); 01215 return res; 01216 }
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 1458 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, chan, check_dirpath(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, create_dirpath(), default_vmformat, minivm_account::domain, errno, ast_channel::exten, find_account(), free_user(), get_date(), global_stats, global_vmmaxmessage, global_vmminmessage, ast_channel::language, minivm_stats::lastreceived, LOG_ERROR, LOG_WARNING, ast_channel::macrocontext, minivmlogfile, minivmloglock, MVM_ALLOCED, ast_channel::name, pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, minivm_stats::receivedmessages, leave_vm_options::record_gain, and TRUE.
Referenced by advanced_options(), forward_message(), minivm_record_exec(), and vm_exec().
01459 { 01460 char tmptxtfile[PATH_MAX]; 01461 char callerid[256]; 01462 FILE *txt; 01463 int res = 0, txtdes; 01464 int msgnum; 01465 int duration = 0; 01466 char date[256]; 01467 char tmpdir[PATH_MAX]; 01468 char ext_context[256] = ""; 01469 char fmt[80]; 01470 char *domain; 01471 char tmp[256] = ""; 01472 struct minivm_account *vmu; 01473 int userdir; 01474 01475 ast_copy_string(tmp, username, sizeof(tmp)); 01476 username = tmp; 01477 domain = strchr(tmp, '@'); 01478 if (domain) { 01479 *domain = '\0'; 01480 domain++; 01481 } 01482 01483 if (!(vmu = find_account(domain, username, TRUE))) { 01484 /* We could not find user, let's exit */ 01485 ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain); 01486 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01487 return 0; 01488 } 01489 01490 /* Setup pre-file if appropriate */ 01491 if (strcmp(vmu->domain, "localhost")) 01492 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 01493 else 01494 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 01495 01496 /* The meat of recording the message... All the announcements and beeps have been played*/ 01497 if (ast_strlen_zero(vmu->attachfmt)) 01498 ast_copy_string(fmt, default_vmformat, sizeof(fmt)); 01499 else 01500 ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt)); 01501 01502 if (ast_strlen_zero(fmt)) { 01503 ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat); 01504 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01505 return res; 01506 } 01507 msgnum = 0; 01508 01509 userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp"); 01510 01511 /* If we have no user directory, use generic temporary directory */ 01512 if (!userdir) { 01513 create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", ""); 01514 ast_debug(3, "Creating temporary directory %s\n", tmpdir); 01515 } 01516 01517 01518 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 01519 01520 01521 /* XXX This file needs to be in temp directory */ 01522 txtdes = mkstemp(tmptxtfile); 01523 if (txtdes < 0) { 01524 ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno)); 01525 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 01526 if (!res) 01527 res = ast_waitstream(chan, ""); 01528 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01529 return res; 01530 } 01531 01532 if (res >= 0) { 01533 /* Unless we're *really* silent, try to send the beep */ 01534 res = ast_streamfile(chan, "beep", chan->language); 01535 if (!res) 01536 res = ast_waitstream(chan, ""); 01537 } 01538 01539 /* OEJ XXX Maybe this can be turned into a log file? Hmm. */ 01540 /* Store information */ 01541 ast_debug(2, "Open file for metadata: %s\n", tmptxtfile); 01542 01543 res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, NULL, options->record_gain); 01544 01545 txt = fdopen(txtdes, "w+"); 01546 if (!txt) { 01547 ast_log(LOG_WARNING, "Error opening text file for output\n"); 01548 } else { 01549 struct ast_tm tm; 01550 struct timeval now = ast_tvnow(); 01551 char timebuf[30]; 01552 char logbuf[BUFSIZ]; 01553 get_date(date, sizeof(date)); 01554 ast_localtime(&now, &tm, NULL); 01555 ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm); 01556 01557 snprintf(logbuf, sizeof(logbuf), 01558 /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */ 01559 "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n", 01560 username, 01561 chan->context, 01562 chan->macrocontext, 01563 chan->exten, 01564 chan->priority, 01565 chan->name, 01566 ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), 01567 date, 01568 timebuf, 01569 duration, 01570 duration < global_vmminmessage ? "IGNORED" : "OK", 01571 vmu->accountcode 01572 ); 01573 fprintf(txt, "%s", logbuf); 01574 if (minivmlogfile) { 01575 ast_mutex_lock(&minivmloglock); 01576 fprintf(minivmlogfile, "%s", logbuf); 01577 ast_mutex_unlock(&minivmloglock); 01578 } 01579 01580 if (duration < global_vmminmessage) { 01581 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, global_vmminmessage); 01582 fclose(txt); 01583 ast_filedelete(tmptxtfile, NULL); 01584 unlink(tmptxtfile); 01585 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01586 return 0; 01587 } 01588 fclose(txt); /* Close log file */ 01589 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01590 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 01591 unlink(tmptxtfile); 01592 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01593 if(ast_test_flag(vmu, MVM_ALLOCED)) 01594 free_user(vmu); 01595 return 0; 01596 } 01597 01598 /* Set channel variables for the notify application */ 01599 pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile); 01600 snprintf(timebuf, sizeof(timebuf), "%d", duration); 01601 pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf); 01602 pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt); 01603 01604 } 01605 global_stats.lastreceived = ast_tvnow(); 01606 global_stats.receivedmessages++; 01607 // /* Go ahead and delete audio files from system, they're not needed any more */ 01608 // if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01609 // ast_filedelete(tmptxtfile, NULL); 01610 // /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */ 01611 // ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile); 01612 // } 01613 01614 if (res > 0) 01615 res = 0; 01616 01617 if(ast_test_flag(vmu, MVM_ALLOCED)) 01618 free_user(vmu); 01619 01620 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 01621 return res; 01622 }
static int load_config | ( | int | reload | ) | [static] |
Load minivoicemail configuration.
Definition at line 2362 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_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, SENDMAIL, THRESHOLD_SILENCE, timezone_add(), timezone_destroy_list(), TRUE, var, vmaccounts_destroy_list(), and VOICEMAIL_CONFIG.
02363 { 02364 struct ast_config *cfg; 02365 struct ast_variable *var; 02366 char *cat; 02367 const char *chanvar; 02368 int error = 0; 02369 struct minivm_template *template; 02370 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 02371 02372 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 02373 if (cfg == CONFIG_STATUS_FILEUNCHANGED) 02374 return 0; 02375 02376 ast_mutex_lock(&minivmlock); 02377 02378 /* Destroy lists to reconfigure */ 02379 message_destroy_list(); /* Destroy list of voicemail message templates */ 02380 timezone_destroy_list(); /* Destroy list of timezones */ 02381 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 02382 ast_debug(2, "Destroyed memory objects...\n"); 02383 02384 /* First, set some default settings */ 02385 global_externnotify[0] = '\0'; 02386 global_logfile[0] = '\0'; 02387 global_vmmaxmessage = 2000; 02388 global_maxgreet = 2000; 02389 global_vmminmessage = 0; 02390 strcpy(global_mailcmd, SENDMAIL); 02391 global_maxsilence = 0; 02392 global_saydurationminfo = 2; 02393 ast_copy_string(default_vmformat, "wav", sizeof(default_vmformat)); 02394 ast_set2_flag((&globalflags), FALSE, MVM_REVIEW); 02395 ast_set2_flag((&globalflags), FALSE, MVM_OPERATOR); 02396 strcpy(global_charset, "ISO-8859-1"); 02397 /* Reset statistics */ 02398 memset(&global_stats, 0, sizeof(global_stats)); 02399 global_stats.reset = ast_tvnow(); 02400 02401 global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 02402 02403 /* Make sure we could load configuration file */ 02404 if (!cfg) { 02405 ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n"); 02406 ast_mutex_unlock(&minivmlock); 02407 return 0; 02408 } 02409 02410 ast_debug(2, "Loaded configuration file, now parsing\n"); 02411 02412 /* General settings */ 02413 02414 cat = ast_category_browse(cfg, NULL); 02415 while (cat) { 02416 ast_debug(3, "Found configuration section [%s]\n", cat); 02417 if (!strcasecmp(cat, "general")) { 02418 /* Nothing right now */ 02419 error += apply_general_options(ast_variable_browse(cfg, cat)); 02420 } else if (!strncasecmp(cat, "template-", 9)) { 02421 /* Template */ 02422 char *name = cat + 9; 02423 02424 /* Now build and link template to list */ 02425 error += message_template_build(name, ast_variable_browse(cfg, cat)); 02426 } else { 02427 var = ast_variable_browse(cfg, cat); 02428 if (!strcasecmp(cat, "zonemessages")) { 02429 /* Timezones in this context */ 02430 while (var) { 02431 timezone_add(var->name, var->value); 02432 var = var->next; 02433 } 02434 } else { 02435 /* Create mailbox from this */ 02436 error += create_vmaccount(cat, var, FALSE); 02437 } 02438 } 02439 /* Find next section in configuration file */ 02440 cat = ast_category_browse(cfg, cat); 02441 } 02442 02443 /* Configure the default email template */ 02444 message_template_build("email-default", NULL); 02445 template = message_template_find("email-default"); 02446 02447 /* Load date format config for voicemail mail */ 02448 if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat"))) 02449 ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat)); 02450 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring"))) 02451 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02452 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress"))) 02453 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02454 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset"))) 02455 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02456 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject"))) 02457 ast_copy_string(template->subject, chanvar, sizeof(template->subject)); 02458 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody"))) 02459 template->body = message_template_parse_emailbody(chanvar); 02460 template->attachment = TRUE; 02461 02462 message_template_build("pager-default", NULL); 02463 template = message_template_find("pager-default"); 02464 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 02465 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02466 if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress"))) 02467 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02468 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset"))) 02469 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02470 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject"))) 02471 ast_copy_string(template->subject, chanvar,sizeof(template->subject)); 02472 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody"))) 02473 template->body = message_template_parse_emailbody(chanvar); 02474 template->attachment = FALSE; 02475 02476 if (error) 02477 ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error); 02478 02479 ast_mutex_unlock(&minivmlock); 02480 ast_config_destroy(cfg); 02481 02482 /* Close log file if it's open and disabled */ 02483 if(minivmlogfile) 02484 fclose(minivmlogfile); 02485 02486 /* Open log file if it's enabled */ 02487 if(!ast_strlen_zero(global_logfile)) { 02488 minivmlogfile = fopen(global_logfile, "a"); 02489 if(!minivmlogfile) 02490 ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno)); 02491 if (minivmlogfile) 02492 ast_debug(3, "Opened log file %s \n", global_logfile); 02493 } 02494 02495 return 0; 02496 }
static int load_module | ( | void | ) | [static] |
Load mini voicemail module.
Definition at line 3054 of file app_minivm.c.
References ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_register_application, cli_minivm, load_config(), minivm_accmess_exec(), minivm_account_function, minivm_counter_function, minivm_delete_exec(), minivm_greet_exec(), minivm_notify_exec(), and minivm_record_exec().
03055 { 03056 int res; 03057 03058 res = ast_register_application(app_minivm_record, minivm_record_exec, synopsis_minivm_record, descrip_minivm_record); 03059 res = ast_register_application(app_minivm_greet, minivm_greet_exec, synopsis_minivm_greet, descrip_minivm_greet); 03060 res = ast_register_application(app_minivm_notify, minivm_notify_exec, synopsis_minivm_notify, descrip_minivm_notify); 03061 res = ast_register_application(app_minivm_delete, minivm_delete_exec, synopsis_minivm_delete, descrip_minivm_delete); 03062 res = ast_register_application(app_minivm_accmess, minivm_accmess_exec, synopsis_minivm_accmess, descrip_minivm_accmess); 03063 03064 ast_custom_function_register(&minivm_account_function); 03065 ast_custom_function_register(&minivm_counter_function); 03066 if (res) 03067 return(res); 03068 03069 if ((res = load_config(0))) 03070 return(res); 03071 03072 ast_cli_register_multiple(cli_minivm, sizeof(cli_minivm)/sizeof(cli_minivm[0])); 03073 03074 /* compute the location of the voicemail spool directory */ 03075 snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 03076 03077 return res; 03078 }
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 765 of file app_minivm.c.
Referenced by sendmail().
00766 { 00767 char *ptr = to; 00768 *ptr++ = '"'; 00769 for (; ptr < to + len - 1; from++) { 00770 if (*from == '"') 00771 *ptr++ = '\\'; 00772 else if (*from == '\0') 00773 break; 00774 *ptr++ = *from; 00775 } 00776 if (ptr < to + len - 1) 00777 *ptr++ = '"'; 00778 *ptr = '\0'; 00779 return to; 00780 }
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 1117 of file app_minivm.c.
References ast_strlen_zero().
Referenced by check_dirpath(), copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01118 { 01119 return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : ""); 01120 }
static void message_destroy_list | ( | void | ) | [static] |
Clear list of templates.
Definition at line 572 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, minivm_account::list, and message_template_free().
Referenced by load_config(), and unload_module().
00573 { 00574 struct minivm_template *this; 00575 AST_LIST_LOCK(&message_templates); 00576 while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list))) 00577 message_template_free(this); 00578 00579 AST_LIST_UNLOCK(&message_templates); 00580 }
static int message_template_build | ( | const char * | name, | |
struct ast_variable * | var | |||
) | [static] |
Build message template from configuration.
Definition at line 489 of file app_minivm.c.
References ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_true(), global_stats, minivm_account::list, LOG_ERROR, message_template_create(), message_template_parse_emailbody(), message_template_parse_filebody(), minivm_stats::templates, and var.
Referenced by load_config().
00490 { 00491 struct minivm_template *template; 00492 int error = 0; 00493 00494 template = message_template_create(name); 00495 if (!template) { 00496 ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name); 00497 return -1; 00498 } 00499 00500 while (var) { 00501 ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name); 00502 if (!strcasecmp(var->name, "fromaddress")) { 00503 ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress)); 00504 } else if (!strcasecmp(var->name, "fromemail")) { 00505 ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail)); 00506 } else if (!strcasecmp(var->name, "subject")) { 00507 ast_copy_string(template->subject, var->value, sizeof(template->subject)); 00508 } else if (!strcasecmp(var->name, "locale")) { 00509 ast_copy_string(template->locale, var->value, sizeof(template->locale)); 00510 } else if (!strcasecmp(var->name, "attachmedia")) { 00511 template->attachment = ast_true(var->value); 00512 } else if (!strcasecmp(var->name, "dateformat")) { 00513 ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat)); 00514 } else if (!strcasecmp(var->name, "charset")) { 00515 ast_copy_string(template->charset, var->value, sizeof(template->charset)); 00516 } else if (!strcasecmp(var->name, "templatefile")) { 00517 if (template->body) 00518 ast_free(template->body); 00519 template->body = message_template_parse_filebody(var->value); 00520 if (!template->body) { 00521 ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value); 00522 error++; 00523 } 00524 } else if (!strcasecmp(var->name, "messagebody")) { 00525 if (template->body) 00526 ast_free(template->body); 00527 template->body = message_template_parse_emailbody(var->value); 00528 if (!template->body) { 00529 ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value); 00530 error++; 00531 } 00532 } else { 00533 ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value); 00534 error++; 00535 } 00536 var = var->next; 00537 } 00538 if (error) 00539 ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name); 00540 00541 AST_LIST_LOCK(&message_templates); 00542 AST_LIST_INSERT_TAIL(&message_templates, template, list); 00543 AST_LIST_UNLOCK(&message_templates); 00544 00545 global_stats.templates++; 00546 00547 return error; 00548 }
static struct minivm_template* message_template_create | ( | const char * | name | ) | [static] |
Create message template.
Definition at line 461 of file app_minivm.c.
References ast_calloc, ast_copy_string(), DEFAULT_CHARSET, DEFAULT_DATEFORMAT, and TRUE.
Referenced by message_template_build().
00462 { 00463 struct minivm_template *template; 00464 00465 template = ast_calloc(1, sizeof(*template)); 00466 if (!template) 00467 return NULL; 00468 00469 /* Set some defaults for templates */ 00470 ast_copy_string(template->name, name, sizeof(template->name)); 00471 ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat)); 00472 ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset)); 00473 ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject)); 00474 template->attachment = TRUE; 00475 00476 return template; 00477 }
static struct minivm_template* message_template_find | ( | const char * | name | ) | [static] |
Find named template.
Definition at line 551 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), and minivm_account::list.
Referenced by load_config(), and notify_new_message().
00552 { 00553 struct minivm_template *this, *res = NULL; 00554 00555 if (ast_strlen_zero(name)) 00556 return NULL; 00557 00558 AST_LIST_LOCK(&message_templates); 00559 AST_LIST_TRAVERSE(&message_templates, this, list) { 00560 if (!strcasecmp(this->name, name)) { 00561 res = this; 00562 break; 00563 } 00564 } 00565 AST_LIST_UNLOCK(&message_templates); 00566 00567 return res; 00568 }
static void message_template_free | ( | struct minivm_template * | template | ) | [static] |
Release memory allocated by message template.
Definition at line 480 of file app_minivm.c.
References ast_free, and minivm_template::body.
Referenced by message_destroy_list().
00481 { 00482 if (template->body) 00483 ast_free(template->body); 00484 00485 ast_free (template); 00486 }
static char * message_template_parse_emailbody | ( | const char * | body | ) | [static] |
Parse emailbody template from configuration file.
Definition at line 2277 of file app_minivm.c.
References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.
Referenced by load_config(), and message_template_build().
02278 { 02279 char *tmpread, *tmpwrite; 02280 char *emailbody = ast_strdup(configuration); 02281 02282 /* substitute strings \t and \n into the apropriate characters */ 02283 tmpread = tmpwrite = emailbody; 02284 while ((tmpwrite = strchr(tmpread,'\\'))) { 02285 int len = strlen("\n"); 02286 switch (tmpwrite[1]) { 02287 case 'n': 02288 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02289 strncpy(tmpwrite, "\n", len); 02290 break; 02291 case 't': 02292 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02293 strncpy(tmpwrite, "\t", len); 02294 break; 02295 default: 02296 ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]); 02297 } 02298 tmpread = tmpwrite + len; 02299 } 02300 return emailbody; 02301 }
static char * message_template_parse_filebody | ( | const char * | filename | ) | [static] |
Read message template from file.
Definition at line 2237 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().
02237 { 02238 char buf[BUFSIZ * 6]; 02239 char readbuf[BUFSIZ]; 02240 char filenamebuf[BUFSIZ]; 02241 char *writepos; 02242 char *messagebody; 02243 FILE *fi; 02244 int lines = 0; 02245 02246 if (ast_strlen_zero(filename)) 02247 return NULL; 02248 if (*filename == '/') 02249 ast_copy_string(filenamebuf, filename, sizeof(filenamebuf)); 02250 else 02251 snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 02252 02253 if (!(fi = fopen(filenamebuf, "r"))) { 02254 ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf); 02255 return NULL; 02256 } 02257 writepos = buf; 02258 while (fgets(readbuf, sizeof(readbuf), fi)) { 02259 lines ++; 02260 if (writepos != buf) { 02261 *writepos = '\n'; /* Replace EOL with new line */ 02262 writepos++; 02263 } 02264 ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf)); 02265 writepos += strlen(readbuf) - 1; 02266 } 02267 fclose(fi); 02268 messagebody = ast_calloc(1, strlen(buf + 1)); 02269 ast_copy_string(messagebody, buf, strlen(buf) + 1); 02270 ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) ); 02271 ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody); 02272 02273 return messagebody; 02274 }
static int minivm_accmess_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Record specific messages for voicemail account.
Definition at line 1984 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, chan, 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().
01985 { 01986 int argc = 0; 01987 char *argv[2]; 01988 char filename[PATH_MAX]; 01989 char tmp[PATH_MAX]; 01990 char *domain; 01991 char *tmpptr = NULL; 01992 struct minivm_account *vmu; 01993 char *username = argv[0]; 01994 struct ast_flags flags = { 0 }; 01995 char *opts[OPT_ARG_ARRAY_SIZE]; 01996 int error = FALSE; 01997 char *message = NULL; 01998 char *prompt = NULL; 01999 int duration; 02000 int cmd; 02001 02002 if (ast_strlen_zero(data)) { 02003 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02004 error = TRUE; 02005 } else 02006 tmpptr = ast_strdupa((char *)data); 02007 if (!error) { 02008 if (!tmpptr) { 02009 ast_log(LOG_ERROR, "Out of memory\n"); 02010 error = TRUE; 02011 } else 02012 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02013 } 02014 02015 if (argc <=1) { 02016 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02017 error = TRUE; 02018 } 02019 if (!error && strlen(argv[1]) > 1) { 02020 ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]); 02021 error = TRUE; 02022 } 02023 02024 if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) { 02025 ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]); 02026 error = TRUE; 02027 } 02028 02029 if (error) { 02030 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02031 return -1; 02032 } 02033 02034 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02035 username = tmp; 02036 domain = strchr(tmp, '@'); 02037 if (domain) { 02038 *domain = '\0'; 02039 domain++; 02040 } 02041 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02042 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02043 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02044 return -1; 02045 } 02046 02047 if(!(vmu = find_account(domain, username, TRUE))) { 02048 /* We could not find user, let's exit */ 02049 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02050 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02051 return -1; 02052 } 02053 02054 /* Answer channel if it's not already answered */ 02055 if (chan->_state != AST_STATE_UP) 02056 ast_answer(chan); 02057 02058 /* Here's where the action is */ 02059 if (ast_test_flag(&flags, OPT_BUSY_GREETING)) { 02060 message = "busy"; 02061 prompt = "vm-rec-busy"; 02062 } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) { 02063 message = "unavailable"; 02064 prompt = "vm-rec-unv"; 02065 } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) { 02066 message = "temp"; 02067 prompt = "vm-rec-temp"; 02068 } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) { 02069 message = "greet"; 02070 prompt = "vm-rec-name"; 02071 } 02072 snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message); 02073 /* Maybe we should check the result of play_record_review ? */ 02074 cmd = play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, FALSE); 02075 02076 ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration); 02077 02078 if(ast_test_flag(vmu, MVM_ALLOCED)) 02079 free_user(vmu); 02080 02081 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS"); 02082 02083 /* Ok, we're ready to rock and roll. Return to dialplan */ 02084 return 0; 02085 }
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 2722 of file app_minivm.c.
References minivm_account::accountcode, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, minivm_account::chanvars, check_dirpath(), minivm_account::domain, minivm_account::email, minivm_account::etemplate, find_account(), free_user(), minivm_account::fullname, minivm_account::language, LOG_ERROR, MVM_ALLOCED, minivm_account::pager, minivm_account::pincode, minivm_account::ptemplate, TRUE, minivm_account::username, var, and minivm_account::zonetag.
02723 { 02724 struct minivm_account *vmu; 02725 char *username, *domain, *colname; 02726 02727 if (!(username = ast_strdupa(data))) { 02728 ast_log(LOG_ERROR, "Memory Error!\n"); 02729 return -1; 02730 } 02731 02732 if ((colname = strchr(username, ':'))) { 02733 *colname = '\0'; 02734 colname++; 02735 } else { 02736 colname = "path"; 02737 } 02738 if ((domain = strchr(username, '@'))) { 02739 *domain = '\0'; 02740 domain++; 02741 } 02742 if (ast_strlen_zero(username) || ast_strlen_zero(domain)) { 02743 ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n"); 02744 return 0; 02745 } 02746 02747 if (!(vmu = find_account(domain, username, TRUE))) 02748 return 0; 02749 02750 if (!strcasecmp(colname, "hasaccount")) { 02751 ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len); 02752 } else if (!strcasecmp(colname, "fullname")) { 02753 ast_copy_string(buf, vmu->fullname, len); 02754 } else if (!strcasecmp(colname, "email")) { 02755 if (!ast_strlen_zero(vmu->email)) 02756 ast_copy_string(buf, vmu->email, len); 02757 else 02758 snprintf(buf, len, "%s@%s", vmu->username, vmu->domain); 02759 } else if (!strcasecmp(colname, "pager")) { 02760 ast_copy_string(buf, vmu->pager, len); 02761 } else if (!strcasecmp(colname, "etemplate")) { 02762 if (!ast_strlen_zero(vmu->etemplate)) 02763 ast_copy_string(buf, vmu->etemplate, len); 02764 else 02765 ast_copy_string(buf, "email-default", len); 02766 } else if (!strcasecmp(colname, "language")) { 02767 ast_copy_string(buf, vmu->language, len); 02768 } else if (!strcasecmp(colname, "timezone")) { 02769 ast_copy_string(buf, vmu->zonetag, len); 02770 } else if (!strcasecmp(colname, "ptemplate")) { 02771 if (!ast_strlen_zero(vmu->ptemplate)) 02772 ast_copy_string(buf, vmu->ptemplate, len); 02773 else 02774 ast_copy_string(buf, "email-default", len); 02775 } else if (!strcasecmp(colname, "accountcode")) { 02776 ast_copy_string(buf, vmu->accountcode, len); 02777 } else if (!strcasecmp(colname, "pincode")) { 02778 ast_copy_string(buf, vmu->pincode, len); 02779 } else if (!strcasecmp(colname, "path")) { 02780 check_dirpath(buf, len, vmu->domain, vmu->username, NULL); 02781 } else { /* Look in channel variables */ 02782 struct ast_variable *var; 02783 int found = 0; 02784 02785 for (var = vmu->chanvars ; var ; var = var->next) 02786 if (!strcmp(var->name, colname)) { 02787 ast_copy_string(buf, var->value, len); 02788 found = 1; 02789 break; 02790 } 02791 } 02792 02793 if(ast_test_flag(vmu, MVM_ALLOCED)) 02794 free_user(vmu); 02795 02796 return 0; 02797 }
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 2874 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
02875 { 02876 char *username, *domain, *countername; 02877 struct minivm_account *vmu = NULL; 02878 char userpath[BUFSIZ]; 02879 int res; 02880 02881 *buf = '\0'; 02882 02883 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 02884 ast_log(LOG_WARNING, "Memory error!\n"); 02885 return -1; 02886 } 02887 if ((countername = strchr(username, ':'))) { 02888 *countername = '\0'; 02889 countername++; 02890 } 02891 02892 if ((domain = strchr(username, '@'))) { 02893 *domain = '\0'; 02894 domain++; 02895 } 02896 02897 /* If we have neither username nor domain now, let's give up */ 02898 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 02899 ast_log(LOG_ERROR, "No account given\n"); 02900 return -1; 02901 } 02902 02903 if (ast_strlen_zero(countername)) { 02904 ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n"); 02905 return -1; 02906 } 02907 02908 /* We only have a domain, no username */ 02909 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 02910 domain = username; 02911 username = NULL; 02912 } 02913 02914 /* If we can't find account or if the account is temporary, return. */ 02915 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 02916 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 02917 return 0; 02918 } 02919 02920 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 02921 02922 /* We have the path, now read the counter file */ 02923 res = access_counter_file(userpath, countername, 0, 0); 02924 if (res >= 0) 02925 snprintf(buf, len, "%d", res); 02926 return 0; 02927 }
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 2930 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
02931 { 02932 char *username, *domain, *countername, *operand; 02933 char userpath[BUFSIZ]; 02934 struct minivm_account *vmu; 02935 int change = 0; 02936 int operation = 0; 02937 02938 if(!value) 02939 return -1; 02940 change = atoi(value); 02941 02942 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 02943 ast_log(LOG_WARNING, "Memory error!\n"); 02944 return -1; 02945 } 02946 02947 if ((countername = strchr(username, ':'))) { 02948 *countername = '\0'; 02949 countername++; 02950 } 02951 if ((operand = strchr(countername, ':'))) { 02952 *operand = '\0'; 02953 operand++; 02954 } 02955 02956 if ((domain = strchr(username, '@'))) { 02957 *domain = '\0'; 02958 domain++; 02959 } 02960 02961 /* If we have neither username nor domain now, let's give up */ 02962 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 02963 ast_log(LOG_ERROR, "No account given\n"); 02964 return -1; 02965 } 02966 02967 /* We only have a domain, no username */ 02968 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 02969 domain = username; 02970 username = NULL; 02971 } 02972 02973 if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) { 02974 ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n"); 02975 return -1; 02976 } 02977 02978 /* If we can't find account or if the account is temporary, return. */ 02979 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 02980 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 02981 return 0; 02982 } 02983 02984 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 02985 /* Now, find out our operator */ 02986 if (*operand == 'i') /* Increment */ 02987 operation = 2; 02988 else if (*operand == 'd') { 02989 change = change * -1; 02990 operation = 2; 02991 } else if (*operand == 's') 02992 operation = 1; 02993 else { 02994 ast_log(LOG_ERROR, "Unknown operator: %s\n", operand); 02995 return -1; 02996 } 02997 02998 /* We have the path, now read the counter file */ 02999 access_counter_file(userpath, countername, change, operation); 03000 return 0; 03001 }
static int minivm_delete_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Dialplan application to delete voicemail.
Definition at line 1946 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_fileexists(), ast_log(), ast_strlen_zero(), chan, LOG_ERROR, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and vm_delete().
Referenced by load_module().
01947 { 01948 int res = 0; 01949 char filename[BUFSIZ]; 01950 01951 if (!ast_strlen_zero(data)) { 01952 ast_copy_string(filename, (char *) data, sizeof(filename)); 01953 } else { 01954 ast_channel_lock(chan); 01955 ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename)); 01956 ast_channel_unlock(chan); 01957 } 01958 01959 if (ast_strlen_zero(filename)) { 01960 ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n"); 01961 return res; 01962 } 01963 01964 /* Go ahead and delete audio files from system, they're not needed any more */ 01965 /* We should look for both audio and text files here */ 01966 if (ast_fileexists(filename, NULL, NULL) > 0) { 01967 res = vm_delete(filename); 01968 if (res) { 01969 ast_debug(2, "Can't delete file: %s\n", filename); 01970 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 01971 } else { 01972 ast_debug(2, "Deleted voicemail file :: %s \n", filename); 01973 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS"); 01974 } 01975 } else { 01976 ast_debug(2, "Filename does not exist: %s\n", filename); 01977 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 01978 } 01979 01980 return res; 01981 }
static int minivm_greet_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Play voicemail prompts - either generic or user specific.
Definition at line 1760 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(), chan, check_dirpath(), minivm_account::domain, minivm_account::exit, find_account(), minivm_account::flags, free_user(), invent_message(), LOG_ERROR, minivm_app_options, MVM_ALLOCED, MVM_OPERATOR, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), SOUND_INTRO, TRUE, and minivm_account::username.
Referenced by load_module().
01761 { 01762 struct leave_vm_options leave_options = { 0, '\0'}; 01763 int argc; 01764 char *argv[2]; 01765 struct ast_flags flags = { 0 }; 01766 char *opts[OPT_ARG_ARRAY_SIZE]; 01767 int res = 0; 01768 int ausemacro = 0; 01769 int ousemacro = 0; 01770 int ouseexten = 0; 01771 char tmp[PATH_MAX]; 01772 char dest[PATH_MAX]; 01773 char prefile[PATH_MAX] = ""; 01774 char tempfile[PATH_MAX] = ""; 01775 char ext_context[256] = ""; 01776 char *domain; 01777 char ecodes[16] = "#"; 01778 char *tmpptr; 01779 struct minivm_account *vmu; 01780 char *username = argv[0]; 01781 01782 if (ast_strlen_zero(data)) { 01783 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01784 return -1; 01785 } 01786 tmpptr = ast_strdupa((char *)data); 01787 if (!tmpptr) { 01788 ast_log(LOG_ERROR, "Out of memory\n"); 01789 return -1; 01790 } 01791 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 01792 01793 if (argc == 2) { 01794 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) 01795 return -1; 01796 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 01797 } 01798 01799 ast_copy_string(tmp, argv[0], sizeof(tmp)); 01800 username = tmp; 01801 domain = strchr(tmp, '@'); 01802 if (domain) { 01803 *domain = '\0'; 01804 domain++; 01805 } 01806 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 01807 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]); 01808 return -1; 01809 } 01810 ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain); 01811 01812 if (!(vmu = find_account(domain, username, TRUE))) { 01813 ast_log(LOG_ERROR, "Could not allocate memory. \n"); 01814 return -1; 01815 } 01816 01817 /* Answer channel if it's not already answered */ 01818 if (chan->_state != AST_STATE_UP) 01819 ast_answer(chan); 01820 01821 /* Setup pre-file if appropriate */ 01822 if (strcmp(vmu->domain, "localhost")) 01823 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 01824 else 01825 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 01826 01827 if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) { 01828 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy"); 01829 if (res) 01830 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username); 01831 } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) { 01832 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail"); 01833 if (res) 01834 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username); 01835 } 01836 /* Check for temporary greeting - it overrides busy and unavail */ 01837 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username); 01838 if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) { 01839 ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile); 01840 ast_copy_string(prefile, tempfile, sizeof(prefile)); 01841 } 01842 ast_debug(2, "Preparing to play message ...\n"); 01843 01844 /* Check current or macro-calling context for special extensions */ 01845 if (ast_test_flag(vmu, MVM_OPERATOR)) { 01846 if (!ast_strlen_zero(vmu->exit)) { 01847 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 01848 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 01849 ouseexten = 1; 01850 } 01851 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 01852 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 01853 ouseexten = 1; 01854 } 01855 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 01856 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 01857 ousemacro = 1; 01858 } 01859 } 01860 01861 if (!ast_strlen_zero(vmu->exit)) { 01862 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 01863 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 01864 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 01865 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 01866 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 01867 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 01868 ausemacro = 1; 01869 } 01870 01871 res = 0; /* Reset */ 01872 /* Play the beginning intro if desired */ 01873 if (!ast_strlen_zero(prefile)) { 01874 if (ast_streamfile(chan, prefile, chan->language) > -1) 01875 res = ast_waitstream(chan, ecodes); 01876 } else { 01877 ast_debug(2, "%s doesn't exist, doing what we can\n", prefile); 01878 res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes); 01879 } 01880 if (res < 0) { 01881 ast_debug(2, "Hang up during prefile playback\n"); 01882 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 01883 if(ast_test_flag(vmu, MVM_ALLOCED)) 01884 free_user(vmu); 01885 return -1; 01886 } 01887 if (res == '#') { 01888 /* On a '#' we skip the instructions */ 01889 ast_set_flag(&leave_options, OPT_SILENT); 01890 res = 0; 01891 } 01892 if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) { 01893 res = ast_streamfile(chan, SOUND_INTRO, chan->language); 01894 if (!res) 01895 res = ast_waitstream(chan, ecodes); 01896 if (res == '#') { 01897 ast_set_flag(&leave_options, OPT_SILENT); 01898 res = 0; 01899 } 01900 } 01901 if (res > 0) 01902 ast_stopstream(chan); 01903 /* Check for a '*' here in case the caller wants to escape from voicemail to something 01904 other than the operator -- an automated attendant or mailbox login for example */ 01905 if (res == '*') { 01906 chan->exten[0] = 'a'; 01907 chan->exten[1] = '\0'; 01908 if (!ast_strlen_zero(vmu->exit)) { 01909 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 01910 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 01911 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 01912 } 01913 chan->priority = 0; 01914 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 01915 res = 0; 01916 } else if (res == '0') { /* Check for a '0' here */ 01917 if(ouseexten || ousemacro) { 01918 chan->exten[0] = 'o'; 01919 chan->exten[1] = '\0'; 01920 if (!ast_strlen_zero(vmu->exit)) { 01921 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 01922 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 01923 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 01924 } 01925 ast_play_and_wait(chan, "transfer"); 01926 chan->priority = 0; 01927 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 01928 } 01929 res = 0; 01930 } else if (res < 0) { 01931 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 01932 res = -1; 01933 } else 01934 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS"); 01935 01936 if(ast_test_flag(vmu, MVM_ALLOCED)) 01937 free_user(vmu); 01938 01939 01940 /* Ok, we're ready to rock and roll. Return to dialplan */ 01941 return res; 01942 01943 }
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 1625 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, chan, 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().
01626 { 01627 int argc; 01628 char *argv[2]; 01629 int res = 0; 01630 char tmp[PATH_MAX]; 01631 char *domain; 01632 char *tmpptr; 01633 struct minivm_account *vmu; 01634 char *username = argv[0]; 01635 const char *template = ""; 01636 const char *filename; 01637 const char *format; 01638 const char *duration_string; 01639 01640 if (ast_strlen_zero(data)) { 01641 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01642 return -1; 01643 } 01644 tmpptr = ast_strdupa((char *)data); 01645 if (!tmpptr) { 01646 ast_log(LOG_ERROR, "Out of memory\n"); 01647 return -1; 01648 } 01649 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 01650 01651 if (argc == 2 && !ast_strlen_zero(argv[1])) 01652 template = argv[1]; 01653 01654 ast_copy_string(tmp, argv[0], sizeof(tmp)); 01655 username = tmp; 01656 domain = strchr(tmp, '@'); 01657 if (domain) { 01658 *domain = '\0'; 01659 domain++; 01660 } 01661 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 01662 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 01663 return -1; 01664 } 01665 01666 if(!(vmu = find_account(domain, username, TRUE))) { 01667 /* We could not find user, let's exit */ 01668 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 01669 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED"); 01670 return -1; 01671 } 01672 01673 ast_channel_lock(chan); 01674 if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) { 01675 filename = ast_strdupa(filename); 01676 } 01677 ast_channel_unlock(chan); 01678 /* Notify of new message to e-mail and pager */ 01679 if (!ast_strlen_zero(filename)) { 01680 ast_channel_lock(chan); 01681 if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) { 01682 format = ast_strdupa(format); 01683 } 01684 if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) { 01685 duration_string = ast_strdupa(duration_string); 01686 } 01687 ast_channel_unlock(chan); 01688 res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), format, chan->cid.cid_num, chan->cid.cid_name); 01689 } 01690 01691 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED"); 01692 01693 01694 if(ast_test_flag(vmu, MVM_ALLOCED)) 01695 free_user(vmu); 01696 01697 /* Ok, we're ready to rock and roll. Return to dialplan */ 01698 01699 return res; 01700 01701 }
static int minivm_record_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Dialplan function to record voicemail.
Definition at line 1704 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, chan, ERROR_LOCK_PATH, minivm_account::flags, leave_voicemail(), LOG_ERROR, LOG_WARNING, minivm_app_options, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, and pbx_builtin_setvar_helper().
Referenced by load_module().
01705 { 01706 int res = 0; 01707 char *tmp; 01708 struct leave_vm_options leave_options; 01709 int argc; 01710 char *argv[2]; 01711 struct ast_flags flags = { 0 }; 01712 char *opts[OPT_ARG_ARRAY_SIZE]; 01713 01714 memset(&leave_options, 0, sizeof(leave_options)); 01715 01716 /* Answer channel if it's not already answered */ 01717 if (chan->_state != AST_STATE_UP) 01718 ast_answer(chan); 01719 01720 if (ast_strlen_zero(data)) { 01721 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 01722 return -1; 01723 } 01724 tmp = ast_strdupa((char *)data); 01725 if (!tmp) { 01726 ast_log(LOG_ERROR, "Out of memory\n"); 01727 return -1; 01728 } 01729 argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv)); 01730 if (argc == 2) { 01731 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) { 01732 return -1; 01733 } 01734 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 01735 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 01736 int gain; 01737 01738 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 01739 ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 01740 return -1; 01741 } else 01742 leave_options.record_gain = (signed char) gain; 01743 } 01744 } 01745 01746 /* Now run the appliation and good luck to you! */ 01747 res = leave_voicemail(chan, argv[0], &leave_options); 01748 01749 if (res == ERROR_LOCK_PATH) { 01750 ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 01751 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01752 res = 0; 01753 } 01754 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 01755 01756 return res; 01757 }
static struct minivm_account* mvm_user_alloc | ( | void | ) | [static] |
Allocate new vm user and set default values.
Definition at line 784 of file app_minivm.c.
References ast_calloc, and populate_defaults().
Referenced by find_account(), and find_user_realtime().
00785 { 00786 struct minivm_account *new; 00787 00788 new = ast_calloc(1, sizeof(*new)); 00789 if (!new) 00790 return NULL; 00791 populate_defaults(new); 00792 00793 return new; 00794 }
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 1381 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, chan, minivm_account::domain, minivm_account::etemplate, EVENT_FLAG_CALL, LOG_WARNING, manager_event, message_template_find(), MVM_MESSAGE_EMAIL, minivm_account::pager, pbx_builtin_getvar_helper(), minivm_account::ptemplate, run_externnotify(), sendmail(), strsep(), and minivm_account::username.
Referenced by copy_message(), leave_voicemail(), and minivm_notify_exec().
01382 { 01383 char *stringp; 01384 struct minivm_template *etemplate; 01385 char *messageformat; 01386 int res = 0; 01387 char oldlocale[100]; 01388 const char *counter; 01389 01390 if (!ast_strlen_zero(vmu->attachfmt)) { 01391 if (strstr(format, vmu->attachfmt)) { 01392 format = vmu->attachfmt; 01393 } else 01394 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); 01395 } 01396 01397 etemplate = message_template_find(vmu->etemplate); 01398 if (!etemplate) 01399 etemplate = message_template_find(templatename); 01400 if (!etemplate) 01401 etemplate = message_template_find("email-default"); 01402 01403 /* Attach only the first format */ 01404 stringp = messageformat = ast_strdupa(format); 01405 strsep(&stringp, "|"); 01406 01407 if (!ast_strlen_zero(etemplate->locale)) { 01408 char *new_locale; 01409 ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale)); 01410 ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale); 01411 new_locale = setlocale(LC_TIME, etemplate->locale); 01412 if (new_locale == NULL) { 01413 ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale); 01414 } 01415 } 01416 01417 01418 01419 /* Read counter if available */ 01420 ast_channel_lock(chan); 01421 if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) { 01422 counter = ast_strdupa(counter); 01423 } 01424 ast_channel_unlock(chan); 01425 01426 if (ast_strlen_zero(counter)) { 01427 ast_debug(2, "MVM_COUNTER not found\n"); 01428 } else { 01429 ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter); 01430 } 01431 01432 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter); 01433 01434 if (res == 0 && !ast_strlen_zero(vmu->pager)) { 01435 /* Find template for paging */ 01436 etemplate = message_template_find(vmu->ptemplate); 01437 if (!etemplate) 01438 etemplate = message_template_find("pager-default"); 01439 if (etemplate->locale) { 01440 ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale)); 01441 setlocale(LC_TIME, etemplate->locale); 01442 } 01443 01444 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter); 01445 } 01446 01447 manager_event(EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter); 01448 01449 run_externnotify(chan, vmu); /* Run external notification */ 01450 01451 if (etemplate->locale) 01452 setlocale(LC_TIME, oldlocale); /* Rest to old locale */ 01453 return res; 01454 }
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 1232 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(), chan, global_maxsilence, global_silencethreshold, ast_channel::language, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and vm_delete().
Referenced by leave_voicemail(), minivm_accmess_exec(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
01235 { 01236 int cmd = 0; 01237 int max_attempts = 3; 01238 int attempts = 0; 01239 int recorded = 0; 01240 int message_exists = 0; 01241 signed char zero_gain = 0; 01242 char *acceptdtmf = "#"; 01243 char *canceldtmf = ""; 01244 01245 /* Note that urgent and private are for flagging messages as such in the future */ 01246 01247 /* barf if no pointer passed to store duration in */ 01248 if (duration == NULL) { 01249 ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n"); 01250 return -1; 01251 } 01252 01253 cmd = '3'; /* Want to start by recording */ 01254 01255 while ((cmd >= 0) && (cmd != 't')) { 01256 switch (cmd) { 01257 case '1': 01258 ast_verb(3, "Saving message as is\n"); 01259 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01260 cmd = 't'; 01261 break; 01262 case '2': 01263 /* Review */ 01264 ast_verb(3, "Reviewing the message\n"); 01265 ast_streamfile(chan, recordfile, chan->language); 01266 cmd = ast_waitstream(chan, AST_DIGIT_ANY); 01267 break; 01268 case '3': 01269 message_exists = 0; 01270 /* Record */ 01271 if (recorded == 1) 01272 ast_verb(3, "Re-recording the message\n"); 01273 else 01274 ast_verb(3, "Recording the message\n"); 01275 if (recorded && outsidecaller) 01276 cmd = ast_play_and_wait(chan, "beep"); 01277 recorded = 1; 01278 /* 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 */ 01279 if (record_gain) 01280 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 01281 if (ast_test_flag(vmu, MVM_OPERATOR)) 01282 canceldtmf = "0"; 01283 cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf); 01284 if (record_gain) 01285 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 01286 if (cmd == -1) /* User has hung up, no options to give */ 01287 return cmd; 01288 if (cmd == '0') 01289 break; 01290 else if (cmd == '*') 01291 break; 01292 else { 01293 /* If all is well, a message exists */ 01294 message_exists = 1; 01295 cmd = 0; 01296 } 01297 break; 01298 case '4': 01299 case '5': 01300 case '6': 01301 case '7': 01302 case '8': 01303 case '9': 01304 case '*': 01305 case '#': 01306 cmd = ast_play_and_wait(chan, "vm-sorry"); 01307 break; 01308 case '0': 01309 if(!ast_test_flag(vmu, MVM_OPERATOR)) { 01310 cmd = ast_play_and_wait(chan, "vm-sorry"); 01311 break; 01312 } 01313 if (message_exists || recorded) { 01314 cmd = ast_play_and_wait(chan, "vm-saveoper"); 01315 if (!cmd) 01316 cmd = ast_waitfordigit(chan, 3000); 01317 if (cmd == '1') { 01318 ast_play_and_wait(chan, "vm-msgsaved"); 01319 cmd = '0'; 01320 } else { 01321 ast_play_and_wait(chan, "vm-deleted"); 01322 vm_delete(recordfile); 01323 cmd = '0'; 01324 } 01325 } 01326 return cmd; 01327 default: 01328 /* If the caller is an ouside caller, and the review option is enabled, 01329 allow them to review the message, but let the owner of the box review 01330 their OGM's */ 01331 if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW)) 01332 return cmd; 01333 if (message_exists) { 01334 cmd = ast_play_and_wait(chan, "vm-review"); 01335 } else { 01336 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01337 if (!cmd) 01338 cmd = ast_waitfordigit(chan, 600); 01339 } 01340 01341 if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) { 01342 cmd = ast_play_and_wait(chan, "vm-reachoper"); 01343 if (!cmd) 01344 cmd = ast_waitfordigit(chan, 600); 01345 } 01346 if (!cmd) 01347 cmd = ast_waitfordigit(chan, 6000); 01348 if (!cmd) { 01349 attempts++; 01350 } 01351 if (attempts > max_attempts) { 01352 cmd = 't'; 01353 } 01354 } 01355 } 01356 if (outsidecaller) 01357 ast_play_and_wait(chan, "vm-goodbye"); 01358 if (cmd == 't') 01359 cmd = 0; 01360 return cmd; 01361 }
static void populate_defaults | ( | struct minivm_account * | vmu | ) | [static] |
Set default values for Mini-Voicemail users.
Definition at line 757 of file app_minivm.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, minivm_account::attachfmt, default_vmformat, global_volgain, globalflags, and minivm_account::volgain.
Referenced by append_mailbox(), create_vmaccount(), find_user_realtime(), load_config(), and mvm_user_alloc().
00758 { 00759 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00760 ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt)); 00761 vmu->volgain = global_volgain; 00762 }
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 729 of file app_minivm.c.
References ast_callerid_merge(), ast_log(), ast_strlen_zero(), minivm_account::chanvars, minivm_account::domain, minivm_account::fullname, LOG_ERROR, pbx_builtin_setvar_helper(), minivm_account::username, and var.
Referenced by make_email_file(), sendmail(), and sendpage().
00730 { 00731 char callerid[256]; 00732 struct ast_variable *var; 00733 00734 if (!channel) { 00735 ast_log(LOG_ERROR, "No allocated channel, giving up...\n"); 00736 return; 00737 } 00738 00739 for (var = vmu->chanvars ; var ; var = var->next) { 00740 pbx_builtin_setvar_helper(channel, var->name, var->value); 00741 } 00742 00743 /* Prepare variables for substition in email body and subject */ 00744 pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname); 00745 pbx_builtin_setvar_helper(channel, "MVM_DUR", dur); 00746 pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain); 00747 pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username); 00748 pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller")); 00749 pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller")); 00750 pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller")); 00751 pbx_builtin_setvar_helper(channel, "MVM_DATE", date); 00752 if (!ast_strlen_zero(counter)) 00753 pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter); 00754 }
static int reload | ( | void | ) | [static] |
Reload mini voicemail module.
Definition at line 3081 of file app_minivm.c.
References load_config().
03082 { 03083 return(load_config(1)); 03084 }
static void run_externnotify | ( | struct ast_channel * | chan, | |
struct minivm_account * | vmu | |||
) | [static] |
Run external notification for voicemail message.
Definition at line 1364 of file app_minivm.c.
References ast_debug, ast_safe_system(), ast_strlen_zero(), chan, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, minivm_account::domain, minivm_account::externnotify, global_externnotify, and minivm_account::username.
Referenced by forward_message(), notify_new_message(), and vm_execmain().
01365 { 01366 char arguments[BUFSIZ]; 01367 01368 if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify)) 01369 return; 01370 01371 snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&", 01372 ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify, 01373 vmu->username, vmu->domain, 01374 chan->cid.cid_name, chan->cid.cid_num); 01375 01376 ast_debug(1, "Executing: %s\n", arguments); 01377 ast_safe_system(arguments); 01378 }
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 881 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(), minivm_template::attachment, base_encode(), minivm_template::body, minivm_template::dateformat, minivm_account::domain, minivm_account::email, minivm_template::fromaddress, minivm_account::fullname, global_charset, global_mailcmd, minivm_account::list, LOG_WARNING, mailheader_quote(), MAXHOSTNAMELEN, MVM_MESSAGE_EMAIL, minivm_zone::name, minivm_template::name, option_debug, minivm_account::pager, pbx_substitute_variables_helper(), prep_email_sub_vars(), minivm_account::serveremail, minivm_template::subject, minivm_zone::timezone, minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.
Referenced by forward_message(), and notify_new_message().
00882 { 00883 FILE *p = NULL; 00884 int pfd; 00885 char email[256] = ""; 00886 char who[256] = ""; 00887 char date[256]; 00888 char bound[256]; 00889 char fname[PATH_MAX]; 00890 char dur[PATH_MAX]; 00891 char tmp[80] = "/tmp/astmail-XXXXXX"; 00892 char tmp2[PATH_MAX]; 00893 struct timeval now; 00894 struct ast_tm tm; 00895 struct minivm_zone *the_zone = NULL; 00896 int len_passdata; 00897 struct ast_channel *ast; 00898 char *finalfilename; 00899 char *passdata = NULL; 00900 char *passdata2 = NULL; 00901 char *fromaddress; 00902 char *fromemail; 00903 00904 if (type == MVM_MESSAGE_EMAIL) { 00905 if (vmu && !ast_strlen_zero(vmu->email)) { 00906 ast_copy_string(email, vmu->email, sizeof(email)); 00907 } else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain)) 00908 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 00909 } else if (type == MVM_MESSAGE_PAGE) { 00910 ast_copy_string(email, vmu->pager, sizeof(email)); 00911 } 00912 00913 if (ast_strlen_zero(email)) { 00914 ast_log(LOG_WARNING, "No address to send message to.\n"); 00915 return -1; 00916 } 00917 00918 ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name); 00919 00920 if (!strcmp(format, "wav49")) 00921 format = "WAV"; 00922 00923 00924 /* If we have a gain option, process it now with sox */ 00925 if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) { 00926 char newtmp[PATH_MAX]; 00927 char tmpcmd[PATH_MAX]; 00928 int tmpfd; 00929 00930 ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp)); 00931 ast_debug(3, "newtmp: %s\n", newtmp); 00932 tmpfd = mkstemp(newtmp); 00933 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format); 00934 ast_safe_system(tmpcmd); 00935 finalfilename = newtmp; 00936 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username); 00937 } else { 00938 finalfilename = ast_strdupa(filename); 00939 } 00940 00941 /* Create file name */ 00942 snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format); 00943 00944 if (template->attachment) 00945 ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail); 00946 00947 /* Make a temporary file instead of piping directly to sendmail, in case the mail 00948 command hangs */ 00949 pfd = mkstemp(tmp); 00950 if (pfd > -1) { 00951 p = fdopen(pfd, "w"); 00952 if (!p) { 00953 close(pfd); 00954 pfd = -1; 00955 } 00956 ast_debug(1, "Opening temp file for e-mail: %s\n", tmp); 00957 } 00958 if (!p) { 00959 ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp); 00960 return -1; 00961 } 00962 /* Allocate channel used for chanvar substitution */ 00963 ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "%s", ""); 00964 00965 00966 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 00967 00968 /* Does this user have a timezone specified? */ 00969 if (!ast_strlen_zero(vmu->zonetag)) { 00970 /* Find the zone in the list */ 00971 struct minivm_zone *z; 00972 AST_LIST_LOCK(&minivm_zones); 00973 AST_LIST_TRAVERSE(&minivm_zones, z, list) { 00974 if (strcmp(z->name, vmu->zonetag)) 00975 continue; 00976 the_zone = z; 00977 } 00978 AST_LIST_UNLOCK(&minivm_zones); 00979 } 00980 00981 now = ast_tvnow(); 00982 ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL); 00983 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm); 00984 00985 /* Start printing the email to the temporary file */ 00986 fprintf(p, "Date: %s\n", date); 00987 00988 /* Set date format for voicemail mail */ 00989 ast_strftime(date, sizeof(date), template->dateformat, &tm); 00990 00991 00992 /* Populate channel with channel variables for substitution */ 00993 prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter); 00994 00995 /* Find email address to use */ 00996 /* If there's a server e-mail adress in the account, user that, othterwise template */ 00997 fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail; 00998 00999 /* Find name to user for server e-mail */ 01000 fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress; 01001 01002 /* If needed, add hostname as domain */ 01003 if (ast_strlen_zero(fromemail)) 01004 fromemail = "asterisk"; 01005 01006 if (strchr(fromemail, '@')) 01007 ast_copy_string(who, fromemail, sizeof(who)); 01008 else { 01009 char host[MAXHOSTNAMELEN]; 01010 gethostname(host, sizeof(host)-1); 01011 snprintf(who, sizeof(who), "%s@%s", fromemail, host); 01012 } 01013 01014 if (ast_strlen_zero(fromaddress)) { 01015 fprintf(p, "From: Asterisk PBX <%s>\n", who); 01016 } else { 01017 /* Allocate a buffer big enough for variable substitution */ 01018 int vmlen = strlen(fromaddress) * 3 + 200; 01019 01020 ast_debug(4, "Fromaddress template: %s\n", fromaddress); 01021 if ((passdata = alloca(vmlen))) { 01022 pbx_substitute_variables_helper(ast, fromaddress, passdata, vmlen); 01023 len_passdata = strlen(passdata) * 2 + 3; 01024 passdata2 = alloca(len_passdata); 01025 fprintf(p, "From: %s <%s>\n", mailheader_quote(passdata, passdata2, len_passdata), who); 01026 } else { 01027 ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); 01028 fclose(p); 01029 return -1; 01030 } 01031 } 01032 ast_debug(4, "Fromstring now: %s\n", ast_strlen_zero(passdata) ? "-default-" : passdata); 01033 01034 fprintf(p, "Message-ID: <Asterisk-%d-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who); 01035 len_passdata = strlen(vmu->fullname) * 2 + 3; 01036 passdata2 = alloca(len_passdata); 01037 if (!ast_strlen_zero(vmu->email)) 01038 fprintf(p, "To: %s <%s>\n", mailheader_quote(vmu->fullname, passdata2, len_passdata), vmu->email); 01039 else 01040 fprintf(p, "To: %s <%s@%s>\n", mailheader_quote(vmu->fullname, passdata2, len_passdata), vmu->username, vmu->domain); 01041 01042 if (!ast_strlen_zero(template->subject)) { 01043 char *pass_data; 01044 int vmlen = strlen(template->subject) * 3 + 200; 01045 if ((pass_data = alloca(vmlen))) { 01046 pbx_substitute_variables_helper(ast, template->subject, pass_data, vmlen); 01047 fprintf(p, "Subject: %s\n", pass_data); 01048 } else { 01049 ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); 01050 fclose(p); 01051 return -1; 01052 } 01053 01054 ast_debug(4, "Subject now: %s\n", pass_data); 01055 01056 } else { 01057 fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain); 01058 ast_debug(1, "Using default subject for this email \n"); 01059 } 01060 01061 01062 if (option_debug > 2) 01063 fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain); 01064 fprintf(p, "MIME-Version: 1.0\n"); 01065 01066 /* Something unique. */ 01067 snprintf(bound, sizeof(bound), "voicemail_%s%d%d", vmu->username, (int)getpid(), (unsigned int)ast_random()); 01068 01069 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound); 01070 01071 fprintf(p, "--%s\n", bound); 01072 fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", global_charset); 01073 if (!ast_strlen_zero(template->body)) { 01074 char *pass_data; 01075 int vmlen = strlen(template->body)*3 + 200; 01076 if ((pass_data = alloca(vmlen))) { 01077 pbx_substitute_variables_helper(ast, template->body, pass_data, vmlen); 01078 ast_debug(3, "Message now: %s\n-----\n", pass_data); 01079 fprintf(p, "%s\n", pass_data); 01080 } else 01081 ast_log(LOG_WARNING, "Cannot allocate workspace for variable substitution\n"); 01082 } else { 01083 fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n" 01084 01085 "in mailbox %s from %s, on %s so you might\n" 01086 "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, 01087 dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 01088 ast_debug(3, "Using default message body (no template)\n-----\n"); 01089 } 01090 /* Eww. We want formats to tell us their own MIME type */ 01091 if (template->attachment) { 01092 char *ctype = "audio/x-"; 01093 ast_debug(3, "Attaching file to message: %s\n", fname); 01094 if (!strcasecmp(format, "ogg")) 01095 ctype = "application/"; 01096 01097 fprintf(p, "--%s\n", bound); 01098 fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format); 01099 fprintf(p, "Content-Transfer-Encoding: base64\n"); 01100 fprintf(p, "Content-Description: Voicemail sound attachment.\n"); 01101 fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format); 01102 01103 base_encode(fname, p); 01104 fprintf(p, "\n\n--%s--\n.\n", bound); 01105 } 01106 fclose(p); 01107 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp); 01108 ast_safe_system(tmp2); 01109 ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : ""); 01110 ast_debug(3, "Actual command used: %s\n", tmp2); 01111 if (ast) 01112 ast_channel_free(ast); 01113 return 0; 01114 }
static int timezone_add | ( | const char * | zonename, | |
const char * | config | |||
) | [static] |
Add time zone to memory list.
Definition at line 2200 of file app_minivm.c.
References ast_calloc, ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, global_stats, minivm_account::list, LOG_WARNING, strsep(), and minivm_stats::timezones.
Referenced by load_config().
02201 { 02202 struct minivm_zone *newzone; 02203 char *msg_format, *timezone_str; 02204 02205 newzone = ast_calloc(1, sizeof(*newzone)); 02206 if (newzone == NULL) 02207 return 0; 02208 02209 msg_format = ast_strdupa(config); 02210 if (msg_format == NULL) { 02211 ast_log(LOG_WARNING, "Out of memory.\n"); 02212 ast_free(newzone); 02213 return 0; 02214 } 02215 02216 timezone_str = strsep(&msg_format, "|"); 02217 if (!msg_format) { 02218 ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename); 02219 ast_free(newzone); 02220 return 0; 02221 } 02222 02223 ast_copy_string(newzone->name, zonename, sizeof(newzone->name)); 02224 ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone)); 02225 ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format)); 02226 02227 AST_LIST_LOCK(&minivm_zones); 02228 AST_LIST_INSERT_TAIL(&minivm_zones, newzone, list); 02229 AST_LIST_UNLOCK(&minivm_zones); 02230 02231 global_stats.timezones++; 02232 02233 return 0; 02234 }
static void timezone_destroy_list | ( | void | ) | [static] |
Clear list of timezones.
Definition at line 2188 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and minivm_account::list.
Referenced by load_config(), and unload_module().
02189 { 02190 struct minivm_zone *this; 02191 02192 AST_LIST_LOCK(&minivm_zones); 02193 while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list))) 02194 free_zone(this); 02195 02196 AST_LIST_UNLOCK(&minivm_zones); 02197 }
static int unload_module | ( | void | ) | [static] |
Unload mini voicemail module.
Definition at line 3107 of file app_minivm.c.
References 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().
03108 { 03109 int res; 03110 03111 res = ast_unregister_application(app_minivm_record); 03112 res |= ast_unregister_application(app_minivm_greet); 03113 res |= ast_unregister_application(app_minivm_notify); 03114 res |= ast_unregister_application(app_minivm_delete); 03115 res |= ast_unregister_application(app_minivm_accmess); 03116 ast_cli_unregister_multiple(cli_minivm, sizeof(cli_minivm)/sizeof(cli_minivm[0])); 03117 ast_custom_function_unregister(&minivm_account_function); 03118 ast_custom_function_unregister(&minivm_counter_function); 03119 03120 message_destroy_list(); /* Destroy list of voicemail message templates */ 03121 timezone_destroy_list(); /* Destroy list of timezones */ 03122 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 03123 03124 return res; 03125 }
static int vm_delete | ( | char * | file | ) | [static] |
Delete media files and attribute file.
Definition at line 1219 of file app_minivm.c.
References ast_debug, and ast_filedelete().
Referenced by copy_message(), minivm_delete_exec(), notify_new_message(), and play_record_review().
01220 { 01221 int res; 01222 01223 ast_debug(1, "Deleting voicemail file %s\n", file); 01224 01225 res = unlink(file); /* Remove the meta data file */ 01226 res |= ast_filedelete(file, NULL); /* remove the media file */ 01227 return res; 01228 }
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 2804 of file app_minivm.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by access_counter_file(), close_mailbox(), copy_message(), count_messages(), leave_voicemail(), open_mailbox(), and save_to_folder().
02805 { 02806 switch (ast_lock_path(path)) { 02807 case AST_LOCK_TIMEOUT: 02808 return -1; 02809 default: 02810 return 0; 02811 } 02812 }
static void vmaccounts_destroy_list | ( | void | ) | [static] |
Clear list of users.
Definition at line 798 of file app_minivm.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and minivm_account::list.
Referenced by load_config(), and unload_module().
00799 { 00800 struct minivm_account *this; 00801 AST_LIST_LOCK(&minivm_accounts); 00802 while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list))) 00803 ast_free(this); 00804 AST_LIST_UNLOCK(&minivm_accounts); 00805 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3132 of file app_minivm.c.
char* app_minivm_accmess = "MinivmAccMess" [static] |
Definition at line 222 of file app_minivm.c.
char* app_minivm_delete = "MinivmDelete" [static] |
Definition at line 221 of file app_minivm.c.
char* app_minivm_greet = "MinivmGreet" [static] |
Definition at line 219 of file app_minivm.c.
char* app_minivm_notify = "MinivmNotify" [static] |
Definition at line 220 of file app_minivm.c.
char* app_minivm_record = "MinivmRecord" [static] |
Definition at line 218 of file app_minivm.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 3132 of file app_minivm.c.
struct ast_cli_entry cli_minivm[] [static] |
CLI commands for Mini-voicemail.
Definition at line 3005 of file app_minivm.c.
Referenced by load_module(), and unload_module().
char default_vmformat[80] [static] |
Definition at line 441 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* descrip_minivm_accmess [static] |
Definition at line 295 of file app_minivm.c.
char* descrip_minivm_delete [static] |
Definition at line 284 of file app_minivm.c.
char* descrip_minivm_greet [static] |
Definition at line 248 of file app_minivm.c.
char* descrip_minivm_notify [static] |
Definition at line 265 of file app_minivm.c.
char* descrip_minivm_record [static] |
Definition at line 225 of file app_minivm.c.
char global_charset[32] [static] |
Global charset in messages
Definition at line 445 of file app_minivm.c.
Referenced by load_config(), and sendmail().
char global_externnotify[160] [static] |
External notification application
Definition at line 439 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 440 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 438 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 436 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 435 of file app_minivm.c.
int global_saydurationminfo [static] |
int global_silencethreshold = 128 [static] |
Definition at line 437 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 426 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 434 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 433 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 447 of file app_minivm.c.
Referenced by populate_defaults().
struct ast_flags globalflags = {0} [static] |
Global voicemail flags
Definition at line 443 of file app_minivm.c.
struct ast_app_option minivm_accmess_options[128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING },} [static] |
struct ast_custom_function minivm_account_function [static] |
struct ast_app_option minivm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 },} [static] |
Definition at line 331 of file app_minivm.c.
Referenced by minivm_greet_exec(), and minivm_record_exec().
struct ast_custom_function minivm_counter_function [static] |
enum { ... } minivm_option_args |
enum { ... } minivm_option_flags |
ast_mutex_t minivmlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Lock to protect voicemail system
Definition at line 428 of file app_minivm.c.
Referenced by load_config().
FILE* minivmlogfile |
The minivm log file
Definition at line 431 of file app_minivm.c.
Referenced by leave_voicemail(), and load_config().
ast_mutex_t minivmloglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Lock to protect voicemail system log file
Definition at line 429 of file app_minivm.c.
Referenced by leave_voicemail().
char MVM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 215 of file app_minivm.c.
char* synopsis_minivm_accmess = "Record account specific messages" [static] |
Definition at line 294 of file app_minivm.c.
char* synopsis_minivm_delete = "Delete Mini-Voicemail voicemail messages" [static] |
Definition at line 283 of file app_minivm.c.
char* synopsis_minivm_greet = "Play Mini-Voicemail prompts" [static] |
Definition at line 247 of file app_minivm.c.
char* synopsis_minivm_notify = "Notify voicemail owner about new messages." [static] |
Definition at line 264 of file app_minivm.c.
char* synopsis_minivm_record = "Receive Mini-Voicemail and forward via e-mail" [static] |
Definition at line 224 of file app_minivm.c.