Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
app_minivm.c File Reference

MiniVoiceMail - A Minimal Voicemail System for Asterisk. More...

#include "asterisk.h"
#include <ctype.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include <locale.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/mwi.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/callerid.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/json.h"

Go to the source code of this file.

Data Structures

struct  leave_vm_options
 Options for leaving voicemail with the voicemail() application. More...
 
struct  message_templates
 The list of e-mail templates. More...
 
struct  minivm_account
 
struct  minivm_accounts
 
struct  minivm_stats
 Structure for gathering statistics. More...
 
struct  minivm_template
 
struct  minivm_zone
 Voicemail time zones. More...
 
struct  minivm_zones
 The list of e-mail time zones. More...
 

Macros

#define ASTERISK_USERNAME   "asterisk"
 
#define DEFAULT_CHARSET   "ISO-8859-1"
 
#define DEFAULT_DATEFORMAT   "%A, %B %d, %Y at %r"
 
#define EOL   "\r\n"
 
#define ERROR_LOCK_PATH   -100
 
#define FALSE   0
 
#define HMSU_OUTPUT_FORMAT   "%-23s %-15s %-15s %-10s %-10s %-50s\n"
 
#define HMSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"
 
#define HVLT_OUTPUT_FORMAT   "%-15s %-10s %-10s %-15.15s %-50s\n"
 
#define MAX_DATETIME_FORMAT   512
 
#define MAX_NUM_CID_CONTEXTS   10
 
#define MVM_ALLOCED   (1 << 13)
 
#define MVM_ENVELOPE   (1 << 4)
 
#define MVM_OPERATOR   (1 << 1)
 
#define MVM_PBXSKIP   (1 << 9)
 
#define MVM_REALTIME   (1 << 2)
 
#define MVM_REVIEW   (1 << 0)
 
#define MVM_SVMAIL   (1 << 3)
 
#define SENDMAIL   "/usr/sbin/sendmail -t"
 Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
 
#define SOUND_INTRO   "vm-intro"
 
#define TRUE   1
 
#define VOICEMAIL_CONFIG   "minivm.conf"
 
#define VOICEMAIL_DIR_MODE   0700
 

Enumerations

enum  minivm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_ARRAY_SIZE = 1 }
 
enum  minivm_option_flags {
  OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_TEMP_GREETING = (1 << 3),
  OPT_NAME_GREETING = (1 << 4), OPT_RECORDGAIN = (1 << 5)
}
 
enum  mvm_messagetype { MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE }
 Message types for notification.
 

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. More...
 
static int apply_general_options (struct ast_variable *var)
 Apply general configuration options.
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static const char * ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *charset, const char *start, size_t preamble, size_t postamble)
 
static const char * ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from)
 
static int check_dirpath (char *dest, int len, char *domain, char *username, char *folder)
 
static int check_mime (const char *str)
 
static char * complete_minivm_show_users (const char *line, const char *word, int pos, int state)
 
static int create_dirpath (char *dest, int len, char *domain, char *username, char *folder)
 
static int create_vmaccount (char *name, struct ast_variable *var, int realtime)
 Append new mailbox to mailbox list from configuration file.
 
static struct minivm_accountfind_account (const char *domain, const char *username, int createtemp)
 
static struct minivm_accountfind_user_realtime (const char *domain, const char *username)
 
static void free_user (struct minivm_account *vmu)
 
static void free_zone (struct minivm_zone *z)
 Free Mini Voicemail timezone.
 
static int get_date (char *s, int len)
 
static char * handle_minivm_list_templates (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI routine for listing templates.
 
static char * handle_minivm_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Reload cofiguration.
 
static char * handle_minivm_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Show settings.
 
static char * handle_minivm_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show stats.
 
static char * handle_minivm_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list voicemail accounts.
 
static char * handle_minivm_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show a list of voicemail zones in the CLI.
 
static int invent_message (struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes)
 
static int leave_voicemail (struct ast_channel *chan, char *username, struct leave_vm_options *options)
 
static int load_config (int reload)
 Load minivoicemail configuration.
 
static int load_module (void)
 Load mini voicemail module.
 
static int make_dir (char *dest, int len, const char *domain, const char *username, const char *folder)
 
static void message_destroy_list (void)
 
static int message_template_build (const char *name, struct ast_variable *var)
 
static struct minivm_templatemessage_template_create (const char *name)
 
static struct minivm_templatemessage_template_find (const char *name)
 
static void message_template_free (struct minivm_template *template)
 
static char * message_template_parse_emailbody (const char *configuration)
 Parse emailbody template from configuration file.
 
static char * message_template_parse_filebody (const char *filename)
 Read message template from file.
 
static int minivm_accmess_exec (struct ast_channel *chan, const char *data)
 Record specific messages for voicemail account.
 
static int minivm_account_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${MINIVMACCOUNT()} Dialplan function - reads account data
 
static int minivm_counter_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${MINIVMCOUNTER()} Dialplan function - read counters
 
static int minivm_counter_func_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 ${MINIVMCOUNTER()} Dialplan function - changes counter data
 
static int minivm_delete_exec (struct ast_channel *chan, const char *data)
 
static int minivm_greet_exec (struct ast_channel *chan, const char *data)
 
static int minivm_mwi_exec (struct ast_channel *chan, const char *data)
 
static int minivm_notify_exec (struct ast_channel *chan, const char *data)
 
static int minivm_record_exec (struct ast_channel *chan, const char *data)
 
static struct minivm_accountmvm_user_alloc (void)
 
static int notify_new_message (struct ast_channel *chan, const char *templatename, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname)
 
static int play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct minivm_account *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain)
 
static void populate_defaults (struct minivm_account *vmu)
 
static void prep_email_sub_vars (struct ast_channel *channel, const struct minivm_account *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date, const char *counter)
 
static void queue_mwi_event (const char *channel_id, const char *mbx, const char *ctx, int urgent, int new, int old)
 
static int reload (void)
 Reload mini voicemail module.
 
static void run_externnotify (struct ast_channel *chan, struct minivm_account *vmu)
 Run external notification for voicemail message.
 
static int sendmail (struct minivm_template *template, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type, const char *counter)
 
static int timezone_add (const char *zonename, const char *config)
 Add time zone to memory list.
 
static void timezone_destroy_list (void)
 Clear list of timezones.
 
static int unload_module (void)
 Unload mini voicemail module.
 
static int vm_delete (char *file)
 
static int vm_lock_path (const char *path)
 lock directory More...
 
static void vmaccounts_destroy_list (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "da6642af068ee5e6490c5b1d2cc1d238" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
 
static char * app_minivm_accmess = "MinivmAccMess"
 
static char * app_minivm_delete = "MinivmDelete"
 
static char * app_minivm_greet = "MinivmGreet"
 
static char * app_minivm_mwi = "MinivmMWI"
 
static char * app_minivm_notify = "MinivmNotify"
 
static char * app_minivm_record = "MinivmRecord"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_minivm []
 CLI commands for Mini-voicemail.
 
static char default_vmformat [80]
 
static char global_externnotify [160]
 
static char global_logfile [PATH_MAX]
 
static char global_mailcmd [160]
 
static int global_maxgreet
 
static int global_maxsilence
 
static int global_saydurationminfo
 
static int global_silencethreshold = 128
 
static struct minivm_stats global_stats
 Statistics for voicemail.
 
static int global_vmmaxmessage
 
static int global_vmminmessage
 
static double global_volgain
 
static struct ast_flags globalflags = {0}
 
static struct message_templates message_templates = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static const struct ast_app_option minivm_accmess_options [128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING }, }
 
static struct ast_custom_function minivm_account_function
 
static struct minivm_accounts minivm_accounts = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static const struct ast_app_option minivm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, }
 
static struct ast_custom_function minivm_counter_function
 
static struct minivm_zones minivm_zones = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static ast_mutex_t minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static FILE * minivmlogfile
 
static ast_mutex_t minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static char MVM_SPOOL_DIR [PATH_MAX]
 

Detailed Description

MiniVoiceMail - A Minimal Voicemail System for Asterisk.

A voicemail system in small building blocks, working together based on the Comedian Mail voicemail system (app_voicemail.c).

See also

Definition in file app_minivm.c.

Macro Definition Documentation

#define ASTERISK_USERNAME   "asterisk"

Default username for sending mail is asterisk@localhost

Definition at line 553 of file app_minivm.c.

#define MVM_OPERATOR   (1 << 1)

Operator exit during voicemail recording

Definition at line 532 of file app_minivm.c.

Referenced by apply_general_options(), handle_minivm_show_settings(), and load_config().

#define MVM_REALTIME   (1 << 2)

This user is a realtime account

Definition at line 533 of file app_minivm.c.

#define MVM_REVIEW   (1 << 0)

Review message

Definition at line 531 of file app_minivm.c.

Referenced by apply_general_options(), handle_minivm_show_settings(), and load_config().

Function Documentation

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.

Parameters
directoryDirectory to crate file in
counternamefilename
valueIf set to zero, we only read the variable
operand0 to read, 1 to set new value, 2 to change
Returns
-1 on error, otherwise counter value

Definition at line 3170 of file app_minivm.c.

References ast_debug, ast_unlock_path(), and vm_lock_path().

Referenced by minivm_counter_func_read(), and minivm_counter_func_write().

3171 {
3172  char filename[BUFSIZ];
3173  char readbuf[BUFSIZ];
3174  FILE *counterfile;
3175  int old = 0, counter = 0;
3176 
3177  /* Lock directory */
3178  if (vm_lock_path(directory)) {
3179  return -1; /* Could not lock directory */
3180  }
3181  snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername);
3182  if (operand != 1) {
3183  counterfile = fopen(filename, "r");
3184  if (counterfile) {
3185  if(fgets(readbuf, sizeof(readbuf), counterfile)) {
3186  ast_debug(3, "Read this string from counter file: %s\n", readbuf);
3187  old = counter = atoi(readbuf);
3188  }
3189  fclose(counterfile);
3190  }
3191  }
3192  switch (operand) {
3193  case 0: /* Read only */
3194  ast_unlock_path(directory);
3195  ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter);
3196  return counter;
3197  break;
3198  case 1: /* Set new value */
3199  counter = value;
3200  break;
3201  case 2: /* Change value */
3202  counter += value;
3203  if (counter < 0) /* Don't allow counters to fall below zero */
3204  counter = 0;
3205  break;
3206  }
3207 
3208  /* Now, write the new value to the file */
3209  counterfile = fopen(filename, "w");
3210  if (!counterfile) {
3211  ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno));
3212  ast_unlock_path(directory);
3213  return -1; /* Could not open file for writing */
3214  }
3215  fprintf(counterfile, "%d\n\n", counter);
3216  fclose(counterfile);
3217  ast_unlock_path(directory);
3218  ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter);
3219  return counter;
3220 }
int ast_unlock_path(const char *path)
Unlock a path.
Definition: main/app.c:2630
#define ast_debug(level,...)
Log a DEBUG message.
static int vm_lock_path(const char *path)
lock directory
Definition: app_minivm.c:3153
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 3153 of file app_minivm.c.

References ast_lock_path().

Referenced by access_counter_file().

3154 {
3155  switch (ast_lock_path(path)) {
3156  case AST_LOCK_TIMEOUT:
3157  return -1;
3158  default:
3159  return 0;
3160  }
3161 }
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Definition: main/app.c:2614

Variable Documentation

char global_externnotify[160]
static

External notification application

Definition at line 695 of file app_minivm.c.

char global_logfile[PATH_MAX]
static

Global log file for messages

Definition at line 696 of file app_minivm.c.

char global_mailcmd[160]
static

Configurable mail cmd

Definition at line 694 of file app_minivm.c.

int global_maxgreet
static

Maximum length of prompts

Definition at line 692 of file app_minivm.c.

int global_maxsilence
static

Maximum silence during recording

Definition at line 691 of file app_minivm.c.

Referenced by __ast_play_and_record().

int global_vmmaxmessage
static

Maximum duration of message

Definition at line 690 of file app_minivm.c.

int global_vmminmessage
static

Minimum duration of messages

Definition at line 689 of file app_minivm.c.

double global_volgain
static

Volume gain for voicmemail via e-mail

Definition at line 702 of file app_minivm.c.

struct ast_flags globalflags = {0}
static

Global voicemail flags

Definition at line 699 of file app_minivm.c.

struct ast_custom_function minivm_account_function
static
Initial value:
= {
.name = "MINIVMACCOUNT",
}
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
Definition: app_minivm.c:3076

Definition at line 3362 of file app_minivm.c.

struct ast_custom_function minivm_counter_function
static
Initial value:
= {
.name = "MINIVMCOUNTER",
}
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
Definition: app_minivm.c:3223
static int minivm_counter_func_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
${MINIVMCOUNTER()} Dialplan function - changes counter data
Definition: app_minivm.c:3276

Definition at line 3356 of file app_minivm.c.

ast_mutex_t minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Lock to protect voicemail system

Definition at line 684 of file app_minivm.c.

Referenced by load_config().

FILE* minivmlogfile
static

The minivm log file

Definition at line 687 of file app_minivm.c.

ast_mutex_t minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Lock to protect voicemail system log file

Definition at line 685 of file app_minivm.c.