Wed Jan 8 2020 09:49:54

Asterisk developer's documentation


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/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/callerid.h"
#include "asterisk/event.h"

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int access_counter_file (char *directory, char *countername, int value, int operand)
 Access counter file, lock directory, read and possibly write it again changed. More...
 
static int apply_general_options (struct ast_variable *var)
 Apply general configuration options. More...
 
static const char * ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *charset, const char *start, size_t preamble, size_t postamble)
 
static const char * ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from)
 
static int b64_inbuf (struct b64_baseio *bio, FILE *fi)
 
static int b64_inchar (struct b64_baseio *bio, FILE *fi)
 
static int b64_ochar (struct b64_baseio *bio, int c, FILE *so)
 
static int base_encode (char *filename, FILE *so)
 
static int check_dirpath (char *dest, int len, char *domain, char *username, char *folder)
 
static int check_mime (const char *str)
 
static char * complete_minivm_show_users (const char *line, const char *word, int pos, int state)
 
static int create_dirpath (char *dest, int len, char *domain, char *username, char *folder)
 
static int create_vmaccount (char *name, struct ast_variable *var, int realtime)
 Append new mailbox to mailbox list from configuration file. More...
 
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. More...
 
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. More...
 
static char * handle_minivm_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Reload cofiguration. More...
 
static char * handle_minivm_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Show settings. More...
 
static char * handle_minivm_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show stats. More...
 
static char * handle_minivm_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list voicemail accounts. More...
 
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. More...
 
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. More...
 
static int load_module (void)
 Load mini voicemail module. More...
 
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. More...
 
static char * message_template_parse_filebody (const char *filename)
 Read message template from file. More...
 
static int minivm_accmess_exec (struct ast_channel *chan, const char *data)
 Record specific messages for voicemail account. More...
 
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 More...
 
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 More...
 
static int minivm_counter_func_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 ${MINIVMCOUNTER()} Dialplan function - changes counter data More...
 
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 *mbx, const char *ctx, int urgent, int new, int old)
 
static int reload (void)
 Reload mini voicemail module. More...
 
static void run_externnotify (struct ast_channel *chan, struct minivm_account *vmu)
 Run external notification for voicemail message. More...
 
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. More...
 
static void timezone_destroy_list (void)
 Clear list of timezones. More...
 
static int unload_module (void)
 Unload mini voicemail module. More...
 
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, }
 
static char * app_minivm_accmess = "MinivmAccMess"
 
static char * app_minivm_delete = "MinivmDelete"
 
static char * app_minivm_greet = "MinivmGreet"
 
static char * app_minivm_mwi = "MinivmMWI"
 
static char * app_minivm_notify = "MinivmNotify"
 
static char * app_minivm_record = "MinivmRecord"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_minivm []
 CLI commands for Mini-voicemail. More...
 
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. More...
 
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 } , }
 
static struct ast_app_option minivm_accmess_options [128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING }, }
 
static struct ast_custom_function minivm_account_function
 
static struct minivm_accounts minivm_accounts = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 
static struct ast_app_option minivm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, }
 
static struct ast_custom_function minivm_counter_function
 
static struct minivm_zones minivm_zones = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 
static ast_mutex_t minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static FILE * minivmlogfile
 
static ast_mutex_t minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static char MVM_SPOOL_DIR [PATH_MAX]
 

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 534 of file app_minivm.c.

#define B64_BASELINELEN   72

Line length for Base 64 endoded messages

Definition at line 524 of file app_minivm.c.

Referenced by b64_ochar().

#define B64_BASEMAXINLINE   256

Buffer size for Base 64 attachment encoding

Definition at line 523 of file app_minivm.c.

Referenced by b64_inbuf(), and base_encode().

#define DEFAULT_CHARSET   "ISO-8859-1"

Definition at line 697 of file app_minivm.c.

Referenced by message_template_create().

#define DEFAULT_DATEFORMAT   "%A, %B %d, %Y at %r"

Definition at line 696 of file app_minivm.c.

Referenced by message_template_create().

#define EOL   "\r\n"

Definition at line 525 of file app_minivm.c.

Referenced by b64_ochar(), and base_encode().

#define ERROR_LOCK_PATH   -100

Definition at line 530 of file app_minivm.c.

Referenced by minivm_record_exec().

#define FALSE   0

Definition at line 506 of file app_minivm.c.

Referenced by __sip_ack(), __sip_semi_ack(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), add_sdp(), AST_TEST_DEFINE(), ast_tzset(), build_peer(), cb_extensionstate(), cc_esc_publish_handler(), cc_handle_publish_error(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), create_addr(), do_monitor(), expire_register(), find_sdp(), function_sippeer(), handle_invite_replaces(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), interpret_t38_parameters(), invent_message(), load_config(), minivm_accmess_exec(), minivm_counter_func_read(), minivm_counter_func_write(), parse_register_contact(), parse_sip_options(), pidf_validate_presence(), pidf_validate_tuple(), proc_session_timer(), process_crypto(), process_sdp(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), proxy_from_config(), proxy_update(), rcvfax_exec(), register_verify(), reload_config(), reqprep(), send_provisional_keepalive_full(), set_destination(), sip_addheader(), sip_answer(), sip_cc_monitor_request_cc(), sip_destroy_peer(), sip_devicestate(), sip_do_debug_peer(), sip_hangup(), sip_is_xml_parsable(), sip_monitor_instance_destructor(), sip_parse_register_line(), sip_pidf_validate(), sip_poke_noanswer(), sip_prune_realtime(), sip_read(), sip_sendhtml(), sip_set_history(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_inuse(), sip_show_settings(), sip_show_user(), sip_show_users(), sndfax_exec(), stop_session_timer(), time1(), time2(), time2sub(), transmit_audio(), transmit_fake_auth_response(), transmit_invite(), transmit_provisional_response(), transmit_publish(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_t38(), tzload(), tzparse(), update_call_counter(), and update_connectedline().

#define HMSU_OUTPUT_FORMAT   "%-23s %-15s %-15s %-10s %-10s %-50s\n"
#define HMSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"
#define HVLT_OUTPUT_FORMAT   "%-15s %-10s %-10s %-15.15s %-50s\n"
#define MAX_DATETIME_FORMAT   512

Definition at line 527 of file app_minivm.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 528 of file app_minivm.c.

#define MVM_ALLOCED   (1 << 13)
#define MVM_ENVELOPE   (1 << 4)

Definition at line 514 of file app_minivm.c.

#define MVM_OPERATOR   (1 << 1)

Operator exit during voicemail recording

Definition at line 511 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 515 of file app_minivm.c.

#define MVM_REALTIME   (1 << 2)

This user is a realtime account

Definition at line 512 of file app_minivm.c.

#define MVM_REVIEW   (1 << 0)

Review message

Definition at line 510 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 513 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 520 of file app_minivm.c.

Referenced by load_config().

#define SOUND_INTRO   "vm-intro"

Definition at line 522 of file app_minivm.c.

Referenced by minivm_greet_exec().

#define TRUE   1

Definition at line 503 of file app_minivm.c.

Referenced by __sip_ack(), __sip_autodestruct(), __sip_semi_ack(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), add_sdp(), ast_tzset(), build_peer(), cc_esc_publish_handler(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), create_addr(), find_account(), find_sdp(), find_user_realtime(), function_sippeer(), get_sip_pvt_byid_locked(), gmtload(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_peerpoke(), interpret_t38_parameters(), leave_voicemail(), load_config(), local_attended_transfer(), message_template_create(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), parse_ok_contact(), parse_register_contact(), parse_sip_options(), pidf_validate_presence(), pidf_validate_tuple(), proc_session_timer(), process_crypto(), process_sdp(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), proxy_update(), rcvfax_exec(), realtime_peer(), reg_source_db(), register_verify(), reload_config(), reqprep(), respprep(), restart_session_timer(), set_destination(), sip_addheader(), sip_alloc(), sip_answer(), sip_cc_agent_respond(), sip_destroy(), sip_devicestate(), sip_do_debug_peer(), sip_hangup(), sip_indicate(), sip_is_xml_parsable(), sip_park_thread(), sip_pidf_validate(), sip_prune_realtime(), sip_reload(), sip_request_call(), sip_scheddestroy(), sip_set_history(), sip_set_udptl_peer(), sip_show_channel(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), sip_write(), sndfax_exec(), spandsp_fax_start(), st_get_se(), start_session_timer(), stop_session_timer(), temp_peer(), time1(), time2(), time2sub(), transmit_audio(), transmit_cc_notify(), transmit_invite(), transmit_publish(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_t38(), tzload(), tzparse(), and update_connectedline().

#define VOICEMAIL_CONFIG   "minivm.conf"

Definition at line 533 of file app_minivm.c.

Referenced by load_config().

#define VOICEMAIL_DIR_MODE   0700

Definition at line 531 of file app_minivm.c.

Enumeration Type Documentation

Enumerator
OPT_ARG_RECORDGAIN 
OPT_ARG_ARRAY_SIZE 

Definition at line 564 of file app_minivm.c.

Enumerator
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_TEMP_GREETING 
OPT_NAME_GREETING 
OPT_RECORDGAIN 

Definition at line 555 of file app_minivm.c.

555  {
556  OPT_SILENT = (1 << 0),
557  OPT_BUSY_GREETING = (1 << 1),
558  OPT_UNAVAIL_GREETING = (1 << 2),
559  OPT_TEMP_GREETING = (1 << 3),
560  OPT_NAME_GREETING = (1 << 4),
561  OPT_RECORDGAIN = (1 << 5),
562 };

Message types for notification.

Enumerator
MVM_MESSAGE_EMAIL 
MVM_MESSAGE_PAGE 

Definition at line 537 of file app_minivm.c.

537  {
540  /* For trunk: MVM_MESSAGE_JABBER, */
541 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 3545 of file app_minivm.c.

static void __unreg_module ( void  )
static

Definition at line 3545 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.

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 3264 of file app_minivm.c.

References ast_debug, ast_log(), ast_unlock_path(), errno, LOG_ERROR, value, and vm_lock_path().

Referenced by minivm_counter_func_read(), and minivm_counter_func_write().

3265 {
3266  char filename[BUFSIZ];
3267  char readbuf[BUFSIZ];
3268  FILE *counterfile;
3269  int old = 0, counter = 0;
3270 
3271  /* Lock directory */
3272  if (vm_lock_path(directory)) {
3273  return -1; /* Could not lock directory */
3274  }
3275  snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername);
3276  if (operand != 1) {
3277  counterfile = fopen(filename, "r");
3278  if (counterfile) {
3279  if(fgets(readbuf, sizeof(readbuf), counterfile)) {
3280  ast_debug(3, "Read this string from counter file: %s\n", readbuf);
3281  old = counter = atoi(readbuf);
3282  }
3283  fclose(counterfile);
3284  }
3285  }
3286  switch (operand) {
3287  case 0: /* Read only */
3288  ast_unlock_path(directory);
3289  ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter);
3290  return counter;
3291  break;
3292  case 1: /* Set new value */
3293  counter = value;
3294  break;
3295  case 2: /* Change value */
3296  counter += value;
3297  if (counter < 0) /* Don't allow counters to fall below zero */
3298  counter = 0;
3299  break;
3300  }
3301 
3302  /* Now, write the new value to the file */
3303  counterfile = fopen(filename, "w");
3304  if (!counterfile) {
3305  ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno));
3306  ast_unlock_path(directory);
3307  return -1; /* Could not open file for writing */
3308  }
3309  fprintf(counterfile, "%d\n\n", counter);
3310  fclose(counterfile);
3311  ast_unlock_path(directory);
3312  ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter);
3313  return counter;
3314 }
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
int value
Definition: syslog.c:39
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static int vm_lock_path(const char *path)
lock directory
Definition: app_minivm.c:3247
static int apply_general_options ( struct ast_variable var)
static

Apply general configuration options.

Definition at line 2749 of file app_minivm.c.

References ast_config_AST_LOG_DIR, ast_copy_string(), ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), default_vmformat, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by load_config().

2750 {
2751  int error = 0;
2752 
2753  while (var) {
2754  /* Mail command */
2755  if (!strcmp(var->name, "mailcmd")) {
2756  ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */
2757  } else if (!strcmp(var->name, "maxgreet")) {
2758  global_maxgreet = atoi(var->value);
2759  } else if (!strcmp(var->name, "maxsilence")) {
2760  global_maxsilence = atoi(var->value);
2761  if (global_maxsilence > 0)
2762  global_maxsilence *= 1000;
2763  } else if (!strcmp(var->name, "logfile")) {
2764  if (!ast_strlen_zero(var->value) ) {
2765  if(*(var->value) == '/')
2767  else
2768  snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value);
2769  }
2770  } else if (!strcmp(var->name, "externnotify")) {
2771  /* External voicemail notify application */
2773  } else if (!strcmp(var->name, "silencetreshold")) {
2774  /* Silence treshold */
2775  global_silencethreshold = atoi(var->value);
2776  } else if (!strcmp(var->name, "maxmessage")) {
2777  int x;
2778  if (sscanf(var->value, "%30d", &x) == 1) {
2779  global_vmmaxmessage = x;
2780  } else {
2781  error ++;
2782  ast_log(LOG_WARNING, "Invalid max message time length\n");
2783  }
2784  } else if (!strcmp(var->name, "minmessage")) {
2785  int x;
2786  if (sscanf(var->value, "%30d", &x) == 1) {
2787  global_vmminmessage = x;
2789  ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
2790  } else {
2791  error ++;
2792  ast_log(LOG_WARNING, "Invalid min message time length\n");
2793  }
2794  } else if (!strcmp(var->name, "format")) {
2796  } else if (!strcmp(var->name, "review")) {
2798  } else if (!strcmp(var->name, "operator")) {
2800  }
2801  var = var->next;
2802  }
2803  return error;
2804 }
#define MVM_REVIEW
Definition: app_minivm.c:510
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
static int global_vmminmessage
Definition: app_minivm.c:679
#define LOG_WARNING
Definition: logger.h:144
static int global_vmmaxmessage
Definition: app_minivm.c:680
static int global_silencethreshold
Definition: app_minivm.c:683
static char global_mailcmd[160]
Definition: app_minivm.c:684
const char * value
Definition: config.h:79
#define MVM_OPERATOR
Definition: app_minivm.c:511
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int global_maxgreet
Definition: app_minivm.c:682
const char * name
Definition: config.h:77
static int global_maxsilence
Definition: app_minivm.c:681
static char default_vmformat[80]
Definition: app_minivm.c:687
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_config_AST_LOG_DIR
Definition: asterisk.c:263
static char global_externnotify[160]
Definition: app_minivm.c:685
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
static struct ast_flags globalflags
Definition: app_minivm.c:689
static char global_logfile[PATH_MAX]
Definition: app_minivm.c:686
static const char* ast_str_encode_mime ( struct ast_str **  end,
ssize_t  maxlen,
const char *  charset,
const char *  start,
size_t  preamble,
size_t  postamble 
)
static

Definition at line 1158 of file app_minivm.c.

References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), and ast_str_strlen().

Referenced by sendmail().

1159 {
1160  struct ast_str *tmp = ast_str_alloca(80);
1161  int first_section = 1;
1162 
1163  ast_str_reset(*end);
1164  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
1165  for (; *start; start++) {
1166  int need_encoding = 0;
1167  if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
1168  need_encoding = 1;
1169  }
1170  if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) ||
1171  (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) ||
1172  (!first_section && need_encoding && ast_str_strlen(tmp) > 70) ||
1173  (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) {
1174  /* Start new line */
1175  ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp));
1176  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
1177  first_section = 0;
1178  }
1179  if (need_encoding && *start == ' ') {
1180  ast_str_append(&tmp, -1, "_");
1181  } else if (need_encoding) {
1182  ast_str_append(&tmp, -1, "=%hhX", *start);
1183  } else {
1184  ast_str_append(&tmp, -1, "%c", *start);
1185  }
1186  }
1187  ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : "");
1188  return ast_str_buffer(*end);
1189 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
#define ast_str_alloca(init_len)
Definition: strings.h:608
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static char charset[32]
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static const char* ast_str_quote ( struct ast_str **  buf,
ssize_t  maxlen,
const char *  from 
)
static

Definition at line 1199 of file app_minivm.c.

References ast_str_append(), ast_str_buffer(), and ast_str_set().

Referenced by sendmail().

1200 {
1201  const char *ptr;
1202 
1203  /* We're only ever passing 0 to maxlen, so short output isn't possible */
1204  ast_str_set(buf, maxlen, "\"");
1205  for (ptr = from; *ptr; ptr++) {
1206  if (*ptr == '"' || *ptr == '\\') {
1207  ast_str_append(buf, maxlen, "\\%c", *ptr);
1208  } else {
1209  ast_str_append(buf, maxlen, "%c", *ptr);
1210  }
1211  }
1212  ast_str_append(buf, maxlen, "\"");
1213 
1214  return ast_str_buffer(*buf);
1215 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
static int b64_inbuf ( struct b64_baseio bio,
FILE *  fi 
)
static

Definition at line 836 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().

837 {
838  int l;
839 
840  if (bio->ateof)
841  return 0;
842 
843  if ((l = fread(bio->iobuf, 1, B64_BASEMAXINLINE,fi)) <= 0) {
844  if (ferror(fi))
845  return -1;
846 
847  bio->ateof = 1;
848  return 0;
849  }
850 
851  bio->iolen= l;
852  bio->iocp= 0;
853 
854  return 1;
855 }
#define B64_BASEMAXINLINE
Definition: app_minivm.c:523
unsigned char iobuf[B64_BASEMAXINLINE]
Definition: app_minivm.c:646
static int b64_inchar ( struct b64_baseio bio,
FILE *  fi 
)
static

Definition at line 859 of file app_minivm.c.

References b64_inbuf(), b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.

Referenced by base_encode().

860 {
861  if (bio->iocp >= bio->iolen) {
862  if (!b64_inbuf(bio, fi))
863  return EOF;
864  }
865 
866  return bio->iobuf[bio->iocp++];
867 }
unsigned char iobuf[B64_BASEMAXINLINE]
Definition: app_minivm.c:646
static int b64_inbuf(struct b64_baseio *bio, FILE *fi)
Definition: app_minivm.c:836
static int b64_ochar ( struct b64_baseio bio,
int  c,
FILE *  so 
)
static

Definition at line 871 of file app_minivm.c.

References B64_BASELINELEN, EOL, and b64_baseio::linelength.

Referenced by base_encode().

872 {
873  if (bio->linelength >= B64_BASELINELEN) {
874  if (fputs(EOL,so) == EOF)
875  return -1;
876 
877  bio->linelength= 0;
878  }
879 
880  if (putc(((unsigned char) c), so) == EOF)
881  return -1;
882 
883  bio->linelength++;
884 
885  return 1;
886 }
#define B64_BASELINELEN
Definition: app_minivm.c:524
int linelength
Definition: app_minivm.c:644
#define EOL
Definition: app_minivm.c:525
static int base_encode ( char *  filename,
FILE *  so 
)
static

Definition at line 890 of file app_minivm.c.

References ast_log(), B64_BASEMAXINLINE, b64_inchar(), b64_ochar(), EOL, errno, b64_baseio::iocp, and LOG_WARNING.

Referenced by sendmail().

891 {
892  unsigned char dtable[B64_BASEMAXINLINE];
893  int i,hiteof= 0;
894  FILE *fi;
895  struct b64_baseio bio;
896 
897  memset(&bio, 0, sizeof(bio));
898  bio.iocp = B64_BASEMAXINLINE;
899 
900  if (!(fi = fopen(filename, "rb"))) {
901  ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
902  return -1;
903  }
904 
905  for (i= 0; i<9; i++) {
906  dtable[i]= 'A'+i;
907  dtable[i+9]= 'J'+i;
908  dtable[26+i]= 'a'+i;
909  dtable[26+i+9]= 'j'+i;
910  }
911  for (i= 0; i < 8; i++) {
912  dtable[i+18]= 'S'+i;
913  dtable[26+i+18]= 's'+i;
914  }
915  for (i= 0; i < 10; i++) {
916  dtable[52+i]= '0'+i;
917  }
918  dtable[62]= '+';
919  dtable[63]= '/';
920 
921  while (!hiteof){
922  unsigned char igroup[3], ogroup[4];
923  int c,n;
924 
925  igroup[0]= igroup[1]= igroup[2]= 0;
926 
927  for (n= 0; n < 3; n++) {
928  if ((c = b64_inchar(&bio, fi)) == EOF) {
929  hiteof= 1;
930  break;
931  }
932  igroup[n]= (unsigned char)c;
933  }
934 
935  if (n> 0) {
936  ogroup[0]= dtable[igroup[0]>>2];
937  ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)];
938  ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)];
939  ogroup[3]= dtable[igroup[2]&0x3F];
940 
941  if (n<3) {
942  ogroup[3]= '=';
943 
944  if (n<2)
945  ogroup[2]= '=';
946  }
947 
948  for (i= 0;i<4;i++)
949  b64_ochar(&bio, ogroup[i], so);
950  }
951  }
952 
953  /* Put end of line - line feed */
954  if (fputs(EOL, so) == EOF)
955  return 0;
956 
957  fclose(fi);
958 
959  return 1;
960 }
static int b64_inchar(struct b64_baseio *bio, FILE *fi)
Definition: app_minivm.c:859
#define LOG_WARNING
Definition: logger.h:144
static int b64_ochar(struct b64_baseio *bio, int c, FILE *so)
Definition: app_minivm.c:871
#define B64_BASEMAXINLINE
Definition: app_minivm.c:523
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
Structure for base64 encoding.
Definition: app_minivm.c:641
#define EOL
Definition: app_minivm.c:525
static int check_dirpath ( char *  dest,
int  len,
char *  domain,
char *  username,
char *  folder 
)
static

Definition at line 1504 of file app_minivm.c.

References FALSE, make_dir(), and TRUE.

Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().

1505 {
1506  struct stat filestat;
1507  make_dir(dest, len, domain, username, folder ? folder : "");
1508  if (stat(dest, &filestat)== -1)
1509  return FALSE;
1510  else
1511  return TRUE;
1512 }
#define FALSE
Definition: app_minivm.c:506
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define TRUE
Definition: app_minivm.c:503
static int make_dir(char *dest, int len, const char *domain, const char *username, const char *folder)
Definition: app_minivm.c:1490
static int check_mime ( const char *  str)
static

Definition at line 1129 of file app_minivm.c.

References str.

Referenced by sendmail().

1130 {
1131  for (; *str; str++) {
1132  if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
1133  return 1;
1134  }
1135  }
1136  return 0;
1137 }
const char * str
Definition: app_jack.c:144
static char* complete_minivm_show_users ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 2988 of file app_minivm.c.

References AST_LIST_TRAVERSE, ast_strdup, and minivm_account::domain.

Referenced by handle_minivm_show_users().

2989 {
2990  int which = 0;
2991  int wordlen;
2992  struct minivm_account *vmu;
2993  const char *domain = "";
2994 
2995  /* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */
2996  if (pos > 4)
2997  return NULL;
2998  if (pos == 3)
2999  return (state == 0) ? ast_strdup("for") : NULL;
3000  wordlen = strlen(word);
3002  if (!strncasecmp(word, vmu->domain, wordlen)) {
3003  if (domain && strcmp(domain, vmu->domain) && ++which > state)
3004  return ast_strdup(vmu->domain);
3005  /* ignore repeated domains ? */
3006  domain = vmu->domain;
3007  }
3008  }
3009  return NULL;
3010 }
#define ast_strdup(a)
Definition: astmm.h:109
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
Definition: ael.tab.c:203
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct minivm_account::@47 list
static int create_dirpath ( char *  dest,
int  len,
char *  domain,
char *  username,
char *  folder 
)
static

Definition at line 1523 of file app_minivm.c.

References ast_debug, ast_log(), ast_mkdir(), LOG_WARNING, and make_dir().

Referenced by leave_voicemail(), minivm_counter_func_read(), and minivm_counter_func_write().

1524 {
1525  int res;
1526  make_dir(dest, len, domain, username, folder);
1527  if ((res = ast_mkdir(dest, 0777))) {
1528  ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res));
1529  return -1;
1530  }
1531  ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest);
1532  return 0;
1533 }
#define LOG_WARNING
Definition: logger.h:144
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int make_dir(char *dest, int len, const char *domain, const char *username, const char *folder)
Definition: app_minivm.c:1490
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
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 2538 of file app_minivm.c.

References minivm_account::accountcode, ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_new(), minivm_account::chanvars, minivm_account::domain, minivm_account::email, minivm_account::etemplate, minivm_account::externnotify, minivm_account::fullname, global_stats, minivm_account::language, LOG_ERROR, ast_variable::name, ast_variable::next, minivm_account::pager, minivm_account::pincode, populate_defaults(), minivm_account::ptemplate, minivm_account::serveremail, minivm_account::username, ast_variable::value, minivm_stats::voicemailaccounts, minivm_account::volgain, and minivm_account::zonetag.

Referenced by find_user_realtime(), and load_config().

2539 {
2540  struct minivm_account *vmu;
2541  char *domain;
2542  char *username;
2543  char accbuf[BUFSIZ];
2544 
2545  ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name);
2546 
2547  ast_copy_string(accbuf, name, sizeof(accbuf));
2548  username = accbuf;
2549  domain = strchr(accbuf, '@');
2550  if (domain) {
2551  *domain = '\0';
2552  domain++;
2553  }
2554  if (ast_strlen_zero(domain)) {
2555  ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name);
2556  return 0;
2557  }
2558 
2559  ast_debug(3, "Creating static account for user %s domain %s\n", username, domain);
2560 
2561  /* Allocate user account */
2562  vmu = ast_calloc(1, sizeof(*vmu));
2563  if (!vmu)
2564  return 0;
2565 
2566  ast_copy_string(vmu->domain, domain, sizeof(vmu->domain));
2567  ast_copy_string(vmu->username, username, sizeof(vmu->username));
2568 
2569  populate_defaults(vmu);
2570 
2571  ast_debug(3, "...Configuring account %s\n", name);
2572 
2573  while (var) {
2574  ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name);
2575  if (!strcasecmp(var->name, "serveremail")) {
2576  ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail));
2577  } else if (!strcasecmp(var->name, "email")) {
2578  ast_copy_string(vmu->email, var->value, sizeof(vmu->email));
2579  } else if (!strcasecmp(var->name, "accountcode")) {
2580  ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode));
2581  } else if (!strcasecmp(var->name, "pincode")) {
2582  ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode));
2583  } else if (!strcasecmp(var->name, "domain")) {
2584  ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain));
2585  } else if (!strcasecmp(var->name, "language")) {
2586  ast_copy_string(vmu->language, var->value, sizeof(vmu->language));
2587  } else if (!strcasecmp(var->name, "timezone")) {
2588  ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag));
2589  } else if (!strcasecmp(var->name, "externnotify")) {
2590  ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify));
2591  } else if (!strcasecmp(var->name, "etemplate")) {
2592  ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate));
2593  } else if (!strcasecmp(var->name, "ptemplate")) {
2594  ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate));
2595  } else if (!strcasecmp(var->name, "fullname")) {
2596  ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname));
2597  } else if (!strcasecmp(var->name, "setvar")) {
2598  char *varval;
2599  char *varname = ast_strdupa(var->value);
2600  struct ast_variable *tmpvar;
2601 
2602  if ((varval = strchr(varname, '='))) {
2603  *varval = '\0';
2604  varval++;
2605  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
2606  tmpvar->next = vmu->chanvars;
2607  vmu->chanvars = tmpvar;
2608  }
2609  }
2610  } else if (!strcasecmp(var->name, "pager")) {
2611  ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager));
2612  } else if (!strcasecmp(var->name, "volgain")) {
2613  sscanf(var->value, "%30lf", &vmu->volgain);
2614  } else {
2615  ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name);
2616  }
2617  var = var->next;
2618  }
2619  ast_debug(3, "...Linking account %s\n", name);
2620 
2624 
2626 
2627  ast_debug(2, "MVM :: Created account %s@%s - tz %s etemplate %s %s\n", username, domain, ast_strlen_zero(vmu->zonetag) ? "" : vmu->zonetag, ast_strlen_zero(vmu->etemplate) ? "" : vmu->etemplate, realtime ? "(realtime)" : "");
2628  return 0;
2629 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char etemplate[80]
Definition: app_minivm.c:601
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char language[MAX_LANGUAGE]
Definition: app_minivm.c:596
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: app_minivm.c:593
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
int voicemailaccounts
Definition: app_minivm.c:662
char pincode[10]
Definition: app_minivm.c:589
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:672
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
char email[80]
Definition: app_minivm.c:591
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char zonetag[80]
Definition: app_minivm.c:597
const char * name
Definition: config.h:77
static void populate_defaults(struct minivm_account *vmu)
Definition: app_minivm.c:1016
double volgain
Definition: app_minivm.c:605
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
struct ast_variable * chanvars
Definition: app_minivm.c:604
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
char fullname[120]
Definition: app_minivm.c:590
char ptemplate[80]
Definition: app_minivm.c:602
char pager[80]
Definition: app_minivm.c:592
#define ast_calloc(a, b)
Definition: astmm.h:82
char externnotify[160]
Definition: app_minivm.c:595
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
char serveremail[80]
Definition: app_minivm.c:594
static struct minivm_account* find_account ( const char *  domain,
const char *  username,
int  createtemp 
)
static

Definition at line 1052 of file app_minivm.c.

References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set2_flag, ast_strlen_zero(), minivm_account::domain, find_user_realtime(), LOG_NOTICE, MVM_ALLOCED, mvm_user_alloc(), TRUE, and minivm_account::username.

Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_counter_func_read(), minivm_counter_func_write(), minivm_greet_exec(), and minivm_notify_exec().

1053 {
1054  struct minivm_account *vmu = NULL, *cur;
1055 
1056 
1058  ast_log(LOG_NOTICE, "No username or domain? \n");
1059  return NULL;
1060  }
1061  ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain);
1062 
1065  /* Is this the voicemail account we're looking for? */
1066  if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username))
1067  break;
1068  }
1070 
1071  if (cur) {
1072  ast_debug(3, "Found account for %s@%s\n", username, domain);
1073  vmu = cur;
1074 
1075  } else
1077 
1078  if (createtemp && !vmu) {
1079  /* Create a temporary user, send e-mail and be gone */
1080  vmu = mvm_user_alloc();
1081  ast_set2_flag(vmu, TRUE, MVM_ALLOCED);
1082  if (vmu) {
1083  ast_copy_string(vmu->username, username, sizeof(vmu->username));
1084  ast_copy_string(vmu->domain, domain, sizeof(vmu->domain));
1085  ast_debug(1, "Created temporary account\n");
1086  }
1087 
1088  }
1089  return vmu;
1090 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct minivm_account * find_user_realtime(const char *domain, const char *username)
Definition: app_minivm.c:1096
#define MVM_ALLOCED
Definition: app_minivm.c:516
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct minivm_account * mvm_user_alloc(void)
Definition: app_minivm.c:1025
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct minivm_account::@47 list
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
static struct minivm_account * find_user_realtime ( const char *  domain,
const char *  username 
)
static

Definition at line 1096 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().

1097 {
1098  struct ast_variable *var;
1099  struct minivm_account *retval;
1100  char name[MAXHOSTNAMELEN];
1101 
1102  retval = mvm_user_alloc();
1103  if (!retval)
1104  return NULL;
1105 
1106  if (username)
1107  ast_copy_string(retval->username, username, sizeof(retval->username));
1108 
1109  populate_defaults(retval);
1110  var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL);
1111 
1112  if (!var) {
1113  ast_free(retval);
1114  return NULL;
1115  }
1116 
1117  snprintf(name, sizeof(name), "%s@%s", username, domain);
1118  create_vmaccount(name, var, TRUE);
1119 
1120  ast_variables_destroy(var);
1121  return retval;
1122 }
static int create_vmaccount(char *name, struct ast_variable *var, int realtime)
Append new mailbox to mailbox list from configuration file.
Definition: app_minivm.c:2538
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
#define MAXHOSTNAMELEN
Definition: network.h:69
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
#define SENTINEL
Definition: compiler.h:75
static void populate_defaults(struct minivm_account *vmu)
Definition: app_minivm.c:1016
static struct minivm_account * mvm_user_alloc(void)
Definition: app_minivm.c:1025
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
static void free_user ( struct minivm_account vmu)
static

Definition at line 974 of file app_minivm.c.

References ast_free, ast_variables_destroy(), and minivm_account::chanvars.

Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), and minivm_notify_exec().

975 {
976  if (vmu->chanvars)
978  ast_free(vmu);
979 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
struct ast_variable * chanvars
Definition: app_minivm.c:604
#define ast_free(a)
Definition: astmm.h:97
static void free_zone ( struct minivm_zone z)
static

Free Mini Voicemail timezone.

Definition at line 2632 of file app_minivm.c.

References ast_free.

Referenced by timezone_destroy_list().

2633 {
2634  ast_free(z);
2635 }
#define ast_free(a)
Definition: astmm.h:97
static int get_date ( char *  s,
int  len 
)
static

Definition at line 962 of file app_minivm.c.

References ast_localtime(), ast_strftime(), and ast_tvnow().

Referenced by leave_voicemail().

963 {
964  struct ast_tm tm;
965  struct timeval now = ast_tvnow();
966 
967  ast_localtime(&now, &tm, NULL);
968  return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm);
969 }
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
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 2947 of file app_minivm.c.

References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVLT_OUTPUT_FORMAT, and ast_cli_entry::usage.

2948 {
2949  struct minivm_template *this;
2950 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n"
2951  int count = 0;
2952 
2953  switch (cmd) {
2954  case CLI_INIT:
2955  e->command = "minivm list templates";
2956  e->usage =
2957  "Usage: minivm list templates\n"
2958  " Lists message templates for e-mail, paging and IM\n";
2959  return NULL;
2960  case CLI_GENERATE:
2961  return NULL;
2962  }
2963 
2964  if (a->argc > 3)
2965  return CLI_SHOWUSAGE;
2966 
2969  ast_cli(a->fd, "There are no message templates defined\n");
2971  return CLI_FAILURE;
2972  }
2973  ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject");
2974  ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------");
2976  ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name,
2977  this->charset ? this->charset : "-",
2978  this->locale ? this->locale : "-",
2979  this->attachment ? "Yes" : "No",
2980  this->subject ? this->subject : "-");
2981  count++;
2982  }
2984  ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count);
2985  return CLI_SUCCESS;
2986 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
const int argc
Definition: cli.h:154
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:146
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
struct minivm_template::@48 list
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
The list of e-mail templates.
Definition: app_minivm.c:632
#define CLI_SUCCESS
Definition: cli.h:43
#define HVLT_OUTPUT_FORMAT
static char * handle_minivm_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Reload cofiguration.

Definition at line 3498 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.

3499 {
3500 
3501  switch (cmd) {
3502  case CLI_INIT:
3503  e->command = "minivm reload";
3504  e->usage =
3505  "Usage: minivm reload\n"
3506  " Reload mini-voicemail configuration and reset statistics\n";
3507  return NULL;
3508  case CLI_GENERATE:
3509  return NULL;
3510  }
3511 
3512  reload();
3513  ast_cli(a->fd, "\n-- Mini voicemail re-configured \n");
3514  return CLI_SUCCESS;
3515 }
static int reload(void)
Reload mini voicemail module.
Definition: app_minivm.c:3492
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
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 3098 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.

3099 {
3100  switch (cmd) {
3101  case CLI_INIT:
3102  e->command = "minivm show settings";
3103  e->usage =
3104  "Usage: minivm show settings\n"
3105  " Display Mini-Voicemail general settings\n";
3106  return NULL;
3107  case CLI_GENERATE:
3108  return NULL;
3109  }
3110 
3111  ast_cli(a->fd, "* Mini-Voicemail general settings\n");
3112  ast_cli(a->fd, " -------------------------------\n");
3113  ast_cli(a->fd, "\n");
3114  ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd);
3115  ast_cli(a->fd, " Max silence: %d\n", global_maxsilence);
3116  ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold);
3117  ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage);
3118  ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage);
3119  ast_cli(a->fd, " Default format: %s\n", default_vmformat);
3120  ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify);
3121  ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>");
3122  ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No");
3123  ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No");
3124 
3125  ast_cli(a->fd, "\n");
3126  return CLI_SUCCESS;
3127 }
#define MVM_REVIEW
Definition: app_minivm.c:510
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int global_vmminmessage
Definition: app_minivm.c:679
Definition: cli.h:146
static int global_vmmaxmessage
Definition: app_minivm.c:680
static int global_silencethreshold
Definition: app_minivm.c:683
static char global_mailcmd[160]
Definition: app_minivm.c:684
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define MVM_OPERATOR
Definition: app_minivm.c:511
const int fd
Definition: cli.h:153
static int global_maxsilence
Definition: app_minivm.c:681
static char default_vmformat[80]
Definition: app_minivm.c:687
char * command
Definition: cli.h:180
static char global_externnotify[160]
Definition: app_minivm.c:685
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static struct ast_flags globalflags
Definition: app_minivm.c:689
static char global_logfile[PATH_MAX]
Definition: app_minivm.c:686
static char* handle_minivm_show_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Show stats.

Definition at line 3130 of file app_minivm.c.

References ast_cli(), ast_localtime(), ast_strftime(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_stats, minivm_stats::lastreceived, minivm_stats::receivedmessages, minivm_stats::reset, minivm_stats::templates, minivm_stats::timezones, ast_cli_entry::usage, and minivm_stats::voicemailaccounts.

3131 {
3132  struct ast_tm timebuf;
3133  char buf[BUFSIZ];
3134 
3135  switch (cmd) {
3136 
3137  case CLI_INIT:
3138  e->command = "minivm show stats";
3139  e->usage =
3140  "Usage: minivm show stats\n"
3141  " Display Mini-Voicemail counters\n";
3142  return NULL;
3143  case CLI_GENERATE:
3144  return NULL;
3145  }
3146 
3147  ast_cli(a->fd, "* Mini-Voicemail statistics\n");
3148  ast_cli(a->fd, " -------------------------\n");
3149  ast_cli(a->fd, "\n");
3150  ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts);
3151  ast_cli(a->fd, " Templates: %5d\n", global_stats.templates);
3152  ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones);
3153  if (global_stats.receivedmessages == 0) {
3154  ast_cli(a->fd, " Received messages since last reset: <none>\n");
3155  } else {
3156  ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages);
3157  ast_localtime(&global_stats.lastreceived, &timebuf, NULL);
3158  ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf);
3159  ast_cli(a->fd, " Last received voicemail: %s\n", buf);
3160  }
3161  ast_localtime(&global_stats.reset, &timebuf, NULL);
3162  ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf);
3163  ast_cli(a->fd, " Last reset: %s\n", buf);
3164 
3165  ast_cli(a->fd, "\n");
3166  return CLI_SUCCESS;
3167 }
struct timeval reset
Definition: app_minivm.c:666
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
struct timeval lastreceived
Definition: app_minivm.c:668
int voicemailaccounts
Definition: app_minivm.c:662
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:672
const int fd
Definition: cli.h:153
int receivedmessages
Definition: app_minivm.c:667
char * command
Definition: cli.h:180
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
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 3013 of file app_minivm.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, minivm_account::attachfmt, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_minivm_show_users(), minivm_account::domain, minivm_account::etemplate, ast_cli_args::fd, minivm_account::fullname, HMSU_OUTPUT_FORMAT, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, minivm_account::ptemplate, ast_cli_entry::usage, minivm_account::username, ast_cli_args::word, and minivm_account::zonetag.

3014 {
3015  struct minivm_account *vmu;
3016 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n"
3017  int count = 0;
3018 
3019  switch (cmd) {
3020  case CLI_INIT:
3021  e->command = "minivm list accounts";
3022  e->usage =
3023  "Usage: minivm list accounts\n"
3024  " Lists all mailboxes currently set up\n";
3025  return NULL;
3026  case CLI_GENERATE:
3027  return complete_minivm_show_users(a->line, a->word, a->pos, a->n);
3028  }
3029 
3030  if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
3031  return CLI_SHOWUSAGE;
3032  if ((a->argc == 5) && strcmp(a->argv[3],"for"))
3033  return CLI_SHOWUSAGE;
3034 
3037  ast_cli(a->fd, "There are no voicemail users currently defined\n");
3039  return CLI_FAILURE;
3040  }
3041  ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name");
3042  ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------");
3044  char tmp[256] = "";
3045  if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) {
3046  count++;
3047  snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain);
3048  ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-",
3049  vmu->ptemplate ? vmu->ptemplate : "-",
3050  vmu->zonetag ? vmu->zonetag : "-",
3051  vmu->attachfmt ? vmu->attachfmt : "-",
3052  vmu->fullname);
3053  }
3054  }
3056  ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count);
3057  return CLI_SUCCESS;
3058 }
char attachfmt[80]
Definition: app_minivm.c:600
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char etemplate[80]
Definition: app_minivm.c:601
#define HMSU_OUTPUT_FORMAT
const int argc
Definition: cli.h:154
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
Definition: cli.h:146
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
const char * line
Definition: cli.h:156
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
char zonetag[80]
Definition: app_minivm.c:597
const char *const * argv
Definition: cli.h:155
static char * complete_minivm_show_users(const char *line, const char *word, int pos, int state)
Definition: app_minivm.c:2988
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define CLI_FAILURE
Definition: cli.h:45
struct minivm_account::@47 list
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
char fullname[120]
Definition: app_minivm.c:590
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
char ptemplate[80]
Definition: app_minivm.c:602
const int pos
Definition: cli.h:158
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 3061 of file app_minivm.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HMSZ_OUTPUT_FORMAT, minivm_zone::msg_format, minivm_zone::name, minivm_zone::timezone, and ast_cli_entry::usage.

3062 {
3063  struct minivm_zone *zone;
3064 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
3065  char *res = CLI_SUCCESS;
3066 
3067  switch (cmd) {
3068  case CLI_INIT:
3069  e->command = "minivm list zones";
3070  e->usage =
3071  "Usage: minivm list zones\n"
3072  " Lists zone message formats\n";
3073  return NULL;
3074  case CLI_GENERATE:
3075  return NULL;
3076  }
3077 
3078  if (a->argc != e->args)
3079  return CLI_SHOWUSAGE;
3080 
3082  if (!AST_LIST_EMPTY(&minivm_zones)) {
3083  ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format");
3084  ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------");
3086  ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format);
3087  }
3088  } else {
3089  ast_cli(a->fd, "There are no voicemail zones currently defined\n");
3090  res = CLI_FAILURE;
3091  }
3093 
3094  return res;
3095 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char name[80]
Definition: app_minivm.c:651
const int argc
Definition: cli.h:154
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:146
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
char timezone[80]
Definition: app_minivm.c:652
#define HMSZ_OUTPUT_FORMAT
#define CLI_SHOWUSAGE
Definition: cli.h:44
char msg_format[BUFSIZ]
Definition: app_minivm.c:653
Voicemail time zones.
Definition: app_minivm.c:650
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
The list of e-mail time zones.
Definition: app_minivm.c:658
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct minivm_zone::@49 list
static int invent_message ( struct ast_channel chan,
char *  domain,
char *  username,
int  busy,
char *  ecodes 
)
static

Definition at line 1539 of file app_minivm.c.

References ast_debug, ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), FALSE, ast_channel::language, and minivm_account::username.

Referenced by minivm_greet_exec().

1540 {
1541  int res;
1542  char fn[PATH_MAX];
1543 
1544  ast_debug(2, "Still preparing to play message ...\n");
1545 
1546  snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username);
1547 
1548  if (ast_fileexists(fn, NULL, NULL) > 0) {
1549  res = ast_streamfile(chan, fn, chan->language);
1550  if (res)
1551  return -1;
1552  res = ast_waitstream(chan, ecodes);
1553  if (res)
1554  return res;
1555  } else {
1556  int numericusername = 1;
1557  char *i = username;
1558 
1559  ast_debug(2, "No personal prompts. Using default prompt set for language\n");
1560 
1561  while (*i) {
1562  ast_debug(2, "Numeric? Checking %c\n", *i);
1563  if (!isdigit(*i)) {
1564  numericusername = FALSE;
1565  break;
1566  }
1567  i++;
1568  }
1569 
1570  if (numericusername) {
1571  if (ast_streamfile(chan, "vm-theperson", chan->language))
1572  return -1;
1573  if ((res = ast_waitstream(chan, ecodes)))
1574  return res;
1575 
1576  res = ast_say_digit_str(chan, username, ecodes, chan->language);
1577  if (res)
1578  return res;
1579  } else {
1580  if (ast_streamfile(chan, "vm-theextensionis", chan->language))
1581  return -1;
1582  if ((res = ast_waitstream(chan, ecodes)))
1583  return res;
1584  }
1585  }
1586 
1587  res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language);
1588  if (res)
1589  return -1;
1590  res = ast_waitstream(chan, ecodes);
1591  return res;
1592 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define FALSE
Definition: app_minivm.c:506
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8415
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
const ast_string_field language
Definition: channel.h:787
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:543
static int leave_voicemail ( struct ast_channel chan,
char *  username,
struct leave_vm_options options 
)
static

Definition at line 1843 of file app_minivm.c.

References minivm_account::accountcode, ast_callerid_merge(), ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_localtime(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_streamfile(), ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_verb, ast_waitstream(), minivm_account::attachfmt, ast_channel::caller, check_dirpath(), ast_channel::context, create_dirpath(), default_vmformat, minivm_account::domain, errno, ast_channel::exten, find_account(), free_user(), get_date(), global_stats, global_vmmaxmessage, global_vmminmessage, ast_party_caller::id, ast_channel::language, minivm_stats::lastreceived, LOG_ERROR, LOG_WARNING, ast_channel::macrocontext, minivmlogfile, minivmloglock, MVM_ALLOCED, ast_party_id::name, ast_channel::name, ast_party_id::number, pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, minivm_stats::receivedmessages, leave_vm_options::record_gain, S_COR, ast_party_name::str, ast_party_number::str, TRUE, ast_party_name::valid, and ast_party_number::valid.

Referenced by minivm_record_exec().

1844 {
1845  char tmptxtfile[PATH_MAX];
1846  char callerid[256];
1847  FILE *txt;
1848  int res = 0, txtdes;
1849  int duration = 0;
1850  int sound_duration = 0;
1851  char date[256];
1852  char tmpdir[PATH_MAX];
1853  char ext_context[256] = "";
1854  char fmt[80];
1855  char *domain;
1856  char tmp[256] = "";
1857  struct minivm_account *vmu;
1858  int userdir;
1859 
1860  ast_copy_string(tmp, username, sizeof(tmp));
1861  username = tmp;
1862  domain = strchr(tmp, '@');
1863  if (domain) {
1864  *domain = '\0';
1865  domain++;
1866  }
1867 
1868  if (!(vmu = find_account(domain, username, TRUE))) {
1869  /* We could not find user, let's exit */
1870  ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain);
1871  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1872  return 0;
1873  }
1874 
1875  /* Setup pre-file if appropriate */
1876  if (strcmp(vmu->domain, "localhost"))
1877  snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain);
1878  else
1879  ast_copy_string(ext_context, vmu->domain, sizeof(ext_context));
1880 
1881  /* The meat of recording the message... All the announcements and beeps have been played*/
1882  if (ast_strlen_zero(vmu->attachfmt))
1883  ast_copy_string(fmt, default_vmformat, sizeof(fmt));
1884  else
1885  ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt));
1886 
1887  if (ast_strlen_zero(fmt)) {
1888  ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat);
1889  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1890  return res;
1891  }
1892 
1893  userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp");
1894 
1895  /* If we have no user directory, use generic temporary directory */
1896  if (!userdir) {
1897  create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", "");
1898  ast_debug(3, "Creating temporary directory %s\n", tmpdir);
1899  }
1900 
1901 
1902  snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
1903 
1904  /* XXX This file needs to be in temp directory */
1905  txtdes = mkstemp(tmptxtfile);
1906  if (txtdes < 0) {
1907  ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno));
1908  res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
1909  if (!res)
1910  res = ast_waitstream(chan, "");
1911  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1912  return res;
1913  }
1914 
1915  if (res >= 0) {
1916  /* Unless we're *really* silent, try to send the beep */
1917  res = ast_streamfile(chan, "beep", chan->language);
1918  if (!res)
1919  res = ast_waitstream(chan, "");
1920  }
1921 
1922  /* OEJ XXX Maybe this can be turned into a log file? Hmm. */
1923  /* Store information */
1924  ast_debug(2, "Open file for metadata: %s\n", tmptxtfile);
1925 
1926  res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain);
1927 
1928  txt = fdopen(txtdes, "w+");
1929  if (!txt) {
1930  ast_log(LOG_WARNING, "Error opening text file for output\n");
1931  } else {
1932  struct ast_tm tm;
1933  struct timeval now = ast_tvnow();
1934  char timebuf[30];
1935  char logbuf[BUFSIZ];
1936  get_date(date, sizeof(date));
1937  ast_localtime(&now, &tm, NULL);
1938  ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm);
1939 
1940  ast_callerid_merge(callerid, sizeof(callerid),
1941  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
1942  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
1943  "Unknown");
1944  snprintf(logbuf, sizeof(logbuf),
1945  /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
1946  "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
1947  username,
1948  chan->context,
1949  chan->macrocontext,
1950  chan->exten,
1951  chan->priority,
1952  chan->name,
1953  callerid,
1954  date,
1955  timebuf,
1956  duration,
1957  duration < global_vmminmessage ? "IGNORED" : "OK",
1958  vmu->accountcode
1959  );
1960  fprintf(txt, "%s", logbuf);
1961  if (minivmlogfile) {
1963  fprintf(minivmlogfile, "%s", logbuf);
1965  }
1966 
1967  if (sound_duration < global_vmminmessage) {
1968  ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, global_vmminmessage);
1969  fclose(txt);
1970  ast_filedelete(tmptxtfile, NULL);
1971  unlink(tmptxtfile);
1972  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1973  return 0;
1974  }
1975  fclose(txt); /* Close log file */
1976  if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
1977  ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
1978  unlink(tmptxtfile);
1979  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1980  if(ast_test_flag(vmu, MVM_ALLOCED))
1981  free_user(vmu);
1982  return 0;
1983  }
1984 
1985  /* Set channel variables for the notify application */
1986  pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile);
1987  snprintf(timebuf, sizeof(timebuf), "%d", duration);
1988  pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf);
1989  pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt);
1990 
1991  }
1994 #if 0
1995  /* Go ahead and delete audio files from system, they're not needed any more */
1996  if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
1997  ast_filedelete(tmptxtfile, NULL);
1998  /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */
1999  ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile);
2000  }
2001 #endif
2002 
2003  if (res > 0)
2004  res = 0;
2005 
2006  if(ast_test_flag(vmu, MVM_ALLOCED))
2007  free_user(vmu);
2008 
2009  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS");
2010  return res;
2011 }
char attachfmt[80]
Definition: app_minivm.c:600
static int get_date(char *s, int len)
Definition: app_minivm.c:962
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
#define MVM_ALLOCED
Definition: app_minivm.c:516
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static int global_vmminmessage
Definition: app_minivm.c:679
#define LOG_WARNING
Definition: logger.h:144
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)
Definition: app_minivm.c:1610
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:974
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static int global_vmmaxmessage
Definition: app_minivm.c:680
#define ast_mutex_lock(a)
Definition: lock.h:155
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: app_minivm.c:593
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
struct timeval lastreceived
Definition: app_minivm.c:668
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1523
#define ast_verb(level,...)
Definition: logger.h:243
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:672
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1504
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1074
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
static FILE * minivmlogfile
Definition: app_minivm.c:677
static char default_vmformat[80]
Definition: app_minivm.c:687
#define LOG_ERROR
Definition: logger.h:155
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int receivedmessages
Definition: app_minivm.c:667
int errno
static ast_mutex_t minivmloglock
Definition: app_minivm.c:675
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
signed char record_gain
Definition: app_minivm.c:637
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_mutex_unlock(a)
Definition: lock.h:156
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int load_config ( int  reload)
static

Load minivoicemail configuration.

Definition at line 2807 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_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, create_vmaccount(), default_vmformat, errno, FALSE, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_saydurationminfo, global_silencethreshold, global_stats, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_ERROR, LOG_WARNING, message_destroy_list(), message_template_build(), message_template_find(), message_template_parse_emailbody(), minivmlock, minivmlogfile, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, minivm_stats::reset, SENDMAIL, THRESHOLD_SILENCE, timezone_add(), timezone_destroy_list(), TRUE, ast_variable::value, var, vmaccounts_destroy_list(), and VOICEMAIL_CONFIG.

Referenced by load_module(), and reload().

2808 {
2809  struct ast_config *cfg;
2810  struct ast_variable *var;
2811  char *cat;
2812  const char *chanvar;
2813  int error = 0;
2814  struct minivm_template *template;
2815  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2816 
2817  cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
2818  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2819  return 0;
2820  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2821  ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
2822  return 0;
2823  }
2824 
2826 
2827  /* Destroy lists to reconfigure */
2828  message_destroy_list(); /* Destroy list of voicemail message templates */
2829  timezone_destroy_list(); /* Destroy list of timezones */
2830  vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */
2831  ast_debug(2, "Destroyed memory objects...\n");
2832 
2833  /* First, set some default settings */
2834  global_externnotify[0] = '\0';
2835  global_logfile[0] = '\0';
2836  global_vmmaxmessage = 2000;
2837  global_maxgreet = 2000;
2838  global_vmminmessage = 0;
2839  strcpy(global_mailcmd, SENDMAIL);
2840  global_maxsilence = 0;
2845  /* Reset statistics */
2846  memset(&global_stats, 0, sizeof(global_stats));
2848 
2850 
2851  /* Make sure we could load configuration file */
2852  if (!cfg) {
2853  ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n");
2855  return 0;
2856  }
2857 
2858  ast_debug(2, "Loaded configuration file, now parsing\n");
2859 
2860  /* General settings */
2861 
2862  cat = ast_category_browse(cfg, NULL);
2863  while (cat) {
2864  ast_debug(3, "Found configuration section [%s]\n", cat);
2865  if (!strcasecmp(cat, "general")) {
2866  /* Nothing right now */
2867  error += apply_general_options(ast_variable_browse(cfg, cat));
2868  } else if (!strncasecmp(cat, "template-", 9)) {
2869  /* Template */
2870  char *name = cat + 9;
2871 
2872  /* Now build and link template to list */
2873  error += message_template_build(name, ast_variable_browse(cfg, cat));
2874  } else {
2875  var = ast_variable_browse(cfg, cat);
2876  if (!strcasecmp(cat, "zonemessages")) {
2877  /* Timezones in this context */
2878  while (var) {
2879  timezone_add(var->name, var->value);
2880  var = var->next;
2881  }
2882  } else {
2883  /* Create mailbox from this */
2884  error += create_vmaccount(cat, var, FALSE);
2885  }
2886  }
2887  /* Find next section in configuration file */
2888  cat = ast_category_browse(cfg, cat);
2889  }
2890 
2891  /* Configure the default email template */
2892  message_template_build("email-default", NULL);
2893  template = message_template_find("email-default");
2894 
2895  /* Load date format config for voicemail mail */
2896  if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat")))
2897  ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat));
2898  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring")))
2899  ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress));
2900  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress")))
2901  ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail));
2902  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset")))
2903  ast_copy_string(template->charset, chanvar, sizeof(template->charset));
2904  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject")))
2905  ast_copy_string(template->subject, chanvar, sizeof(template->subject));
2906  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody")))
2907  template->body = message_template_parse_emailbody(chanvar);
2908  template->attachment = TRUE;
2909 
2910  message_template_build("pager-default", NULL);
2911  template = message_template_find("pager-default");
2912  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
2913  ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress));
2914  if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress")))
2915  ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail));
2916  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset")))
2917  ast_copy_string(template->charset, chanvar, sizeof(template->charset));
2918  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject")))
2919  ast_copy_string(template->subject, chanvar,sizeof(template->subject));
2920  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody")))
2921  template->body = message_template_parse_emailbody(chanvar);
2922  template->attachment = FALSE;
2923 
2924  if (error)
2925  ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error);
2926 
2928  ast_config_destroy(cfg);
2929 
2930  /* Close log file if it's open and disabled */
2931  if(minivmlogfile)
2932  fclose(minivmlogfile);
2933 
2934  /* Open log file if it's enabled */
2936  minivmlogfile = fopen(global_logfile, "a");
2937  if(!minivmlogfile)
2938  ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno));
2939  if (minivmlogfile)
2940  ast_debug(3, "Opened log file %s \n", global_logfile);
2941  }
2942 
2943  return 0;
2944 }
static struct minivm_template * message_template_find(const char *name)
Definition: app_minivm.c:801
static int reload(void)
Reload mini voicemail module.
Definition: app_minivm.c:3492
struct timeval reset
Definition: app_minivm.c:666
#define FALSE
Definition: app_minivm.c:506
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define MVM_REVIEW
Definition: app_minivm.c:510
static int create_vmaccount(char *name, struct ast_variable *var, int realtime)
Append new mailbox to mailbox list from configuration file.
Definition: app_minivm.c:2538
static int message_template_build(const char *name, struct ast_variable *var)
Definition: app_minivm.c:738
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
static int global_vmminmessage
Definition: app_minivm.c:679
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static int timezone_add(const char *zonename, const char *config)
Add time zone to memory list.
Definition: app_minivm.c:2650
static void vmaccounts_destroy_list(void)
Definition: app_minivm.c:1040
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static int global_vmmaxmessage
Definition: app_minivm.c:680
#define ast_mutex_lock(a)
Definition: lock.h:155
static int global_silencethreshold
Definition: app_minivm.c:683
static char global_mailcmd[160]
Definition: app_minivm.c:684
static char * chanvar
Definition: app_system.c:105
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:672
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void timezone_destroy_list(void)
Clear list of timezones.
Definition: app_minivm.c:2638
const char * value
Definition: config.h:79
#define MVM_OPERATOR
Definition: app_minivm.c:511
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int global_maxgreet
Definition: app_minivm.c:682
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
static int global_maxsilence
Definition: app_minivm.c:681
static FILE * minivmlogfile
Definition: app_minivm.c:677
static char default_vmformat[80]
Definition: app_minivm.c:687
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static int global_saydurationminfo
Definition: app_minivm.c:690
static const char name[]
static char * message_template_parse_emailbody(const char *body)
Parse emailbody template from configuration file.
Definition: app_minivm.c:2722
static char global_externnotify[160]
Definition: app_minivm.c:685
Structure used to handle boolean flags.
Definition: utils.h:200
#define SENDMAIL
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
Definition: app_minivm.c:520
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
#define VOICEMAIL_CONFIG
Definition: app_minivm.c:533
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static ast_mutex_t minivmlock
Definition: app_minivm.c:674
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1880
static void message_destroy_list(void)
Definition: app_minivm.c:823
static struct ast_flags globalflags
Definition: app_minivm.c:689
static int apply_general_options(struct ast_variable *var)
Apply general configuration options.
Definition: app_minivm.c:2749
static char global_logfile[PATH_MAX]
Definition: app_minivm.c:686
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int load_module ( void  )
static

Load mini voicemail module.

Definition at line 3464 of file app_minivm.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_register_application_xml, cli_minivm, load_config(), minivm_accmess_exec(), minivm_account_function, minivm_counter_function, minivm_delete_exec(), minivm_greet_exec(), minivm_mwi_exec(), minivm_notify_exec(), and minivm_record_exec().

3465 {
3466  int res;
3467 
3474 
3477  if (res)
3478  return(res);
3479 
3480  if ((res = load_config(0)))
3481  return(res);
3482 
3484 
3485  /* compute the location of the voicemail spool directory */
3486  snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
3487 
3488  return res;
3489 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_custom_function minivm_counter_function
Definition: app_minivm.c:3452
static char * app_minivm_notify
Definition: app_minivm.c:548
static int minivm_mwi_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2040
static char * app_minivm_record
Definition: app_minivm.c:546
static int minivm_notify_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2078
static struct ast_cli_entry cli_minivm[]
CLI commands for Mini-voicemail.
Definition: app_minivm.c:3443
static char * app_minivm_mwi
Definition: app_minivm.c:551
const char * ast_config_AST_SPOOL_DIR
Definition: asterisk.c:259
static int load_config(int reload)
Load minivoicemail configuration.
Definition: app_minivm.c:2807
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
Record specific messages for voicemail account.
Definition: app_minivm.c:2440
static char * app_minivm_accmess
Definition: app_minivm.c:550
static int minivm_greet_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2210
static char * app_minivm_greet
Definition: app_minivm.c:547
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
static int minivm_record_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2157
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static char * app_minivm_delete
Definition: app_minivm.c:549
static int minivm_delete_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2402
static struct ast_custom_function minivm_account_function
Definition: app_minivm.c:3458
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:543
static int make_dir ( char *  dest,
int  len,
const char *  domain,
const char *  username,
const char *  folder 
)
static

Definition at line 1490 of file app_minivm.c.

References ast_strlen_zero().

Referenced by check_dirpath(), and create_dirpath().

1491 {
1492  return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : "");
1493 }
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:543
static void message_destroy_list ( void  )
static

Definition at line 823 of file app_minivm.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and message_template_free().

Referenced by load_config(), and unload_module().

824 {
825  struct minivm_template *this;
827  while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list))) {
828  message_template_free(this);
829  }
830 
832 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static void message_template_free(struct minivm_template *template)
Definition: app_minivm.c:728
struct minivm_template::@48 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
The list of e-mail templates.
Definition: app_minivm.c:632
static int message_template_build ( const char *  name,
struct ast_variable var 
)
static

Definition at line 738 of file app_minivm.c.

References ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_true(), global_stats, LOG_ERROR, message_template_create(), message_template_parse_emailbody(), message_template_parse_filebody(), ast_variable::name, ast_variable::next, minivm_stats::templates, and ast_variable::value.

Referenced by load_config().

739 {
740  struct minivm_template *template;
741  int error = 0;
742 
743  template = message_template_create(name);
744  if (!template) {
745  ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name);
746  return -1;
747  }
748 
749  while (var) {
750  ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name);
751  if (!strcasecmp(var->name, "fromaddress")) {
752  ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress));
753  } else if (!strcasecmp(var->name, "fromemail")) {
754  ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail));
755  } else if (!strcasecmp(var->name, "subject")) {
756  ast_copy_string(template->subject, var->value, sizeof(template->subject));
757  } else if (!strcasecmp(var->name, "locale")) {
758  ast_copy_string(template->locale, var->value, sizeof(template->locale));
759  } else if (!strcasecmp(var->name, "attachmedia")) {
760  template->attachment = ast_true(var->value);
761  } else if (!strcasecmp(var->name, "dateformat")) {
762  ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat));
763  } else if (!strcasecmp(var->name, "charset")) {
764  ast_copy_string(template->charset, var->value, sizeof(template->charset));
765  } else if (!strcasecmp(var->name, "templatefile")) {
766  if (template->body)
767  ast_free(template->body);
768  template->body = message_template_parse_filebody(var->value);
769  if (!template->body) {
770  ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value);
771  error++;
772  }
773  } else if (!strcasecmp(var->name, "messagebody")) {
774  if (template->body)
775  ast_free(template->body);
776  template->body = message_template_parse_emailbody(var->value);
777  if (!template->body) {
778  ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value);
779  error++;
780  }
781  } else {
782  ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value);
783  error++;
784  }
785  var = var->next;
786  }
787  if (error)
788  ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name);
789 
793 
795 
796  return error;
797 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:672
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
struct minivm_template::@48 list
const char * name
Definition: config.h:77
static char * message_template_parse_filebody(const char *filename)
Read message template from file.
Definition: app_minivm.c:2682
static struct minivm_template * message_template_create(const char *name)
Definition: app_minivm.c:708
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
static char * message_template_parse_emailbody(const char *body)
Parse emailbody template from configuration file.
Definition: app_minivm.c:2722
The list of e-mail templates.
Definition: app_minivm.c:632
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
static struct minivm_template* message_template_create ( const char *  name)
static

Definition at line 708 of file app_minivm.c.

References ast_calloc, ast_copy_string(), DEFAULT_CHARSET, DEFAULT_DATEFORMAT, and TRUE.

Referenced by message_template_build().

709 {
710  struct minivm_template *template;
711 
712  template = ast_calloc(1, sizeof(*template));
713  if (!template)
714  return NULL;
715 
716  /* Set some defaults for templates */
717  ast_copy_string(template->name, name, sizeof(template->name));
718  ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat));
719  ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset));
720  ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject));
721  template->attachment = TRUE;
722 
723  return template;
724 }
#define DEFAULT_DATEFORMAT
Definition: app_minivm.c:696
static const char name[]
#define DEFAULT_CHARSET
Definition: app_minivm.c:697
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
static struct minivm_template* message_template_find ( const char *  name)
static

Definition at line 801 of file app_minivm.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().

Referenced by load_config(), and notify_new_message().

802 {
803  struct minivm_template *this, *res = NULL;
804 
805  if (ast_strlen_zero(name))
806  return NULL;
807 
810  if (!strcasecmp(this->name, name)) {
811  res = this;
812  break;
813  }
814  }
816 
817  return res;
818 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct minivm_template::@48 list
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
The list of e-mail templates.
Definition: app_minivm.c:632
static void message_template_free ( struct minivm_template template)
static

Definition at line 728 of file app_minivm.c.

References ast_free.

Referenced by message_destroy_list().

729 {
730  if (template->body)
731  ast_free(template->body);
732 
733  ast_free (template);
734 }
#define ast_free(a)
Definition: astmm.h:97
static char * message_template_parse_emailbody ( const char *  body)
static

Parse emailbody template from configuration file.

Definition at line 2722 of file app_minivm.c.

References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.

Referenced by load_config(), and message_template_build().

2723 {
2724  char *tmpread, *tmpwrite;
2725  char *emailbody = ast_strdup(configuration);
2726 
2727  /* substitute strings \t and \n into the apropriate characters */
2728  tmpread = tmpwrite = emailbody;
2729  while ((tmpwrite = strchr(tmpread,'\\'))) {
2730  int len = strlen("\n");
2731  switch (tmpwrite[1]) {
2732  case 'n':
2733  memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
2734  strncpy(tmpwrite, "\n", len);
2735  break;
2736  case 't':
2737  memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
2738  strncpy(tmpwrite, "\t", len);
2739  break;
2740  default:
2741  ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
2742  }
2743  tmpread = tmpwrite + len;
2744  }
2745  return emailbody;
2746 }
#define ast_strdup(a)
Definition: astmm.h:109
static char * emailbody
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static char * message_template_parse_filebody ( const char *  filename)
static

Read message template from file.

Definition at line 2682 of file app_minivm.c.

References ast_calloc, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), and LOG_ERROR.

Referenced by message_template_build().

2682  {
2683  char buf[BUFSIZ * 6];
2684  char readbuf[BUFSIZ];
2685  char filenamebuf[BUFSIZ];
2686  char *writepos;
2687  char *messagebody;
2688  FILE *fi;
2689  int lines = 0;
2690 
2691  if (ast_strlen_zero(filename))
2692  return NULL;
2693  if (*filename == '/')
2694  ast_copy_string(filenamebuf, filename, sizeof(filenamebuf));
2695  else
2696  snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
2697 
2698  if (!(fi = fopen(filenamebuf, "r"))) {
2699  ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf);
2700  return NULL;
2701  }
2702  writepos = buf;
2703  while (fgets(readbuf, sizeof(readbuf), fi)) {
2704  lines ++;
2705  if (writepos != buf) {
2706  *writepos = '\n'; /* Replace EOL with new line */
2707  writepos++;
2708  }
2709  ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf));
2710  writepos += strlen(readbuf) - 1;
2711  }
2712  fclose(fi);
2713  messagebody = ast_calloc(1, strlen(buf + 1));
2714  ast_copy_string(messagebody, buf, strlen(buf) + 1);
2715  ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) );
2716  ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody);
2717 
2718  return messagebody;
2719 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define LOG_ERROR
Definition: logger.h:155
const char * ast_config_AST_CONFIG_DIR
Definition: asterisk.c:256
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int minivm_accmess_exec ( struct ast_channel chan,
const char *  data 
)
static

Record specific messages for voicemail account.

Definition at line 2440 of file app_minivm.c.

References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_copy_string(), ast_debug, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, default_vmformat, minivm_account::domain, FALSE, find_account(), minivm_account::flags, free_user(), global_maxgreet, LOG_ERROR, LOG_WARNING, minivm_accmess_options, MVM_ALLOCED, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_NAME_GREETING, OPT_TEMP_GREETING, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), play_record_review(), prompt, TRUE, and minivm_account::username.

Referenced by load_module().

2441 {
2442  int argc = 0;
2443  char *argv[2];
2444  char filename[PATH_MAX];
2445  char tmp[PATH_MAX];
2446  char *domain;
2447  char *tmpptr = NULL;
2448  struct minivm_account *vmu;
2449  char *username;
2450  struct ast_flags flags = { 0 };
2451  char *opts[OPT_ARG_ARRAY_SIZE];
2452  int error = FALSE;
2453  char *message = NULL;
2454  char *prompt = NULL;
2455  int duration;
2456 
2457  if (ast_strlen_zero(data)) {
2458  ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
2459  error = TRUE;
2460  } else {
2461  tmpptr = ast_strdupa((char *)data);
2462  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2463  }
2464 
2465  if (argc <=1) {
2466  ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
2467  error = TRUE;
2468  }
2469  if (!error && strlen(argv[1]) > 1) {
2470  ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]);
2471  error = TRUE;
2472  }
2473 
2474  if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) {
2475  ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]);
2476  error = TRUE;
2477  }
2478 
2479  if (error) {
2480  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
2481  return -1;
2482  }
2483 
2484  ast_copy_string(tmp, argv[0], sizeof(tmp));
2485  username = tmp;
2486  domain = strchr(tmp, '@');
2487  if (domain) {
2488  *domain = '\0';
2489  domain++;
2490  }
2491  if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
2492  ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
2493  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
2494  return -1;
2495  }
2496 
2497  if(!(vmu = find_account(domain, username, TRUE))) {
2498  /* We could not find user, let's exit */
2499  ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
2500  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
2501  return -1;
2502  }
2503 
2504  /* Answer channel if it's not already answered */
2505  if (chan->_state != AST_STATE_UP)
2506  ast_answer(chan);
2507 
2508  /* Here's where the action is */
2509  if (ast_test_flag(&flags, OPT_BUSY_GREETING)) {
2510  message = "busy";
2511  prompt = "vm-rec-busy";
2512  } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) {
2513  message = "unavailable";
2514  prompt = "vm-rec-unv";
2515  } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) {
2516  message = "temp";
2517  prompt = "vm-rec-temp";
2518  } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) {
2519  message = "greet";
2520  prompt = "vm-rec-name";
2521  }
2522  snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message);
2523  /* Maybe we should check the result of play_record_review ? */
2524  play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, NULL, FALSE);
2525 
2526  ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration);
2527 
2528  if(ast_test_flag(vmu, MVM_ALLOCED))
2529  free_user(vmu);
2530 
2531  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS");
2532 
2533  /* Ok, we're ready to rock and roll. Return to dialplan */
2534  return 0;
2535 }
#define FALSE
Definition: app_minivm.c:506
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define MVM_ALLOCED
Definition: app_minivm.c:516
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
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)
Definition: app_minivm.c:1610
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:974
unsigned int flags
Definition: utils.h:201
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int global_maxgreet
Definition: app_minivm.c:682
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static char default_vmformat[80]
Definition: app_minivm.c:687
#define LOG_ERROR
Definition: logger.h:155
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_app_option minivm_accmess_options[128]
Definition: app_minivm.c:581
Structure used to handle boolean flags.
Definition: utils.h:200
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
Definition: app.c:1453
static struct ast_str * prompt
Definition: asterisk.c:2395
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:543
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 3170 of file app_minivm.c.

References minivm_account::accountcode, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, minivm_account::chanvars, check_dirpath(), minivm_account::domain, minivm_account::email, minivm_account::etemplate, find_account(), free_user(), minivm_account::fullname, minivm_account::language, LOG_ERROR, MVM_ALLOCED, ast_variable::name, ast_variable::next, minivm_account::pager, minivm_account::pincode, minivm_account::ptemplate, TRUE, minivm_account::username, ast_variable::value, var, and minivm_account::zonetag.

3171 {
3172  struct minivm_account *vmu;
3173  char *username, *domain, *colname;
3174 
3175  username = ast_strdupa(data);
3176 
3177  if ((colname = strchr(username, ':'))) {
3178  *colname = '\0';
3179  colname++;
3180  } else {
3181  colname = "path";
3182  }
3183  if ((domain = strchr(username, '@'))) {
3184  *domain = '\0';
3185  domain++;
3186  }
3187  if (ast_strlen_zero(username) || ast_strlen_zero(domain)) {
3188  ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n");
3189  return 0;
3190  }
3191 
3192  if (!(vmu = find_account(domain, username, TRUE)))
3193  return 0;
3194 
3195  if (!strcasecmp(colname, "hasaccount")) {
3196  ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len);
3197  } else if (!strcasecmp(colname, "fullname")) {
3198  ast_copy_string(buf, vmu->fullname, len);
3199  } else if (!strcasecmp(colname, "email")) {
3200  if (!ast_strlen_zero(vmu->email))
3201  ast_copy_string(buf, vmu->email, len);
3202  else
3203  snprintf(buf, len, "%s@%s", vmu->username, vmu->domain);
3204  } else if (!strcasecmp(colname, "pager")) {
3205  ast_copy_string(buf, vmu->pager, len);
3206  } else if (!strcasecmp(colname, "etemplate")) {
3207  if (!ast_strlen_zero(vmu->etemplate))
3208  ast_copy_string(buf, vmu->etemplate, len);
3209  else
3210  ast_copy_string(buf, "email-default", len);
3211  } else if (!strcasecmp(colname, "language")) {
3212  ast_copy_string(buf, vmu->language, len);
3213  } else if (!strcasecmp(colname, "timezone")) {
3214  ast_copy_string(buf, vmu->zonetag, len);
3215  } else if (!strcasecmp(colname, "ptemplate")) {
3216  if (!ast_strlen_zero(vmu->ptemplate))
3217  ast_copy_string(buf, vmu->ptemplate, len);
3218  else
3219  ast_copy_string(buf, "email-default", len);
3220  } else if (!strcasecmp(colname, "accountcode")) {
3221  ast_copy_string(buf, vmu->accountcode, len);
3222  } else if (!strcasecmp(colname, "pincode")) {
3223  ast_copy_string(buf, vmu->pincode, len);
3224  } else if (!strcasecmp(colname, "path")) {
3225  check_dirpath(buf, len, vmu->domain, vmu->username, NULL);
3226  } else { /* Look in channel variables */
3227  struct ast_variable *var;
3228 
3229  for (var = vmu->chanvars ; var ; var = var->next)
3230  if (!strcmp(var->name, colname)) {
3231  ast_copy_string(buf, var->value, len);
3232  break;
3233  }
3234  }
3235 
3236  if(ast_test_flag(vmu, MVM_ALLOCED))
3237  free_user(vmu);
3238 
3239  return 0;
3240 }
char etemplate[80]
Definition: app_minivm.c:601
#define MVM_ALLOCED
Definition: app_minivm.c:516
#define ast_test_flag(p, flag)
Definition: utils.h:63
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:974
char language[MAX_LANGUAGE]
Definition: app_minivm.c:596
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: app_minivm.c:593
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
char pincode[10]
Definition: app_minivm.c:589
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1504
const char * value
Definition: config.h:79
char email[80]
Definition: app_minivm.c:591
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char zonetag[80]
Definition: app_minivm.c:597
const char * name
Definition: config.h:77
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
struct ast_variable * chanvars
Definition: app_minivm.c:604
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char fullname[120]
Definition: app_minivm.c:590
char ptemplate[80]
Definition: app_minivm.c:602
char pager[80]
Definition: app_minivm.c:592
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
struct ast_variable * next
Definition: config.h:82
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 3317 of file app_minivm.c.

References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), minivm_account::domain, FALSE, find_account(), LOG_ERROR, and minivm_account::username.

3318 {
3319  char *username, *domain, *countername;
3320  struct minivm_account *vmu = NULL;
3321  char userpath[BUFSIZ];
3322  int res;
3323 
3324  *buf = '\0';
3325 
3326  username = ast_strdupa(data);
3327 
3328  if ((countername = strchr(username, ':'))) {
3329  *countername = '\0';
3330  countername++;
3331  }
3332 
3333  if ((domain = strchr(username, '@'))) {
3334  *domain = '\0';
3335  domain++;
3336  }
3337 
3338  /* If we have neither username nor domain now, let's give up */
3339  if (ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3340  ast_log(LOG_ERROR, "No account given\n");
3341  return -1;
3342  }
3343 
3344  if (ast_strlen_zero(countername)) {
3345  ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n");
3346  return -1;
3347  }
3348 
3349  /* We only have a domain, no username */
3350  if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3351  domain = username;
3352  username = NULL;
3353  }
3354 
3355  /* If we can't find account or if the account is temporary, return. */
3356  if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) {
3357  ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
3358  return 0;
3359  }
3360 
3361  create_dirpath(userpath, sizeof(userpath), domain, username, NULL);
3362 
3363  /* We have the path, now read the counter file */
3364  res = access_counter_file(userpath, countername, 0, 0);
3365  if (res >= 0)
3366  snprintf(buf, len, "%d", res);
3367  return 0;
3368 }
#define FALSE
Definition: app_minivm.c:506
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1523
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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.
Definition: app_minivm.c:3264
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 3371 of file app_minivm.c.

References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), minivm_account::domain, FALSE, find_account(), LOG_ERROR, and minivm_account::username.

3372 {
3373  char *username, *domain, *countername, *operand;
3374  char userpath[BUFSIZ];
3375  struct minivm_account *vmu;
3376  int change = 0;
3377  int operation = 0;
3378 
3379  if(!value)
3380  return -1;
3381  change = atoi(value);
3382 
3383  username = ast_strdupa(data);
3384 
3385  if ((countername = strchr(username, ':'))) {
3386  *countername = '\0';
3387  countername++;
3388  }
3389  if ((operand = strchr(countername, ':'))) {
3390  *operand = '\0';
3391  operand++;
3392  }
3393 
3394  if ((domain = strchr(username, '@'))) {
3395  *domain = '\0';
3396  domain++;
3397  }
3398 
3399  /* If we have neither username nor domain now, let's give up */
3400  if (ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3401  ast_log(LOG_ERROR, "No account given\n");
3402  return -1;
3403  }
3404 
3405  /* We only have a domain, no username */
3406  if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3407  domain = username;
3408  username = NULL;
3409  }
3410 
3411  if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) {
3412  ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n");
3413  return -1;
3414  }
3415 
3416  /* If we can't find account or if the account is temporary, return. */
3417  if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) {
3418  ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
3419  return 0;
3420  }
3421 
3422  create_dirpath(userpath, sizeof(userpath), domain, username, NULL);
3423  /* Now, find out our operator */
3424  if (*operand == 'i') /* Increment */
3425  operation = 2;
3426  else if (*operand == 'd') {
3427  change = change * -1;
3428  operation = 2;
3429  } else if (*operand == 's')
3430  operation = 1;
3431  else {
3432  ast_log(LOG_ERROR, "Unknown operator: %s\n", operand);
3433  return -1;
3434  }
3435 
3436  /* We have the path, now read the counter file */
3437  access_counter_file(userpath, countername, change, operation);
3438  return 0;
3439 }
#define FALSE
Definition: app_minivm.c:506
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
int value
Definition: syslog.c:39
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1523
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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.
Definition: app_minivm.c:3264
static int minivm_delete_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2402 of file app_minivm.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_fileexists(), ast_log(), ast_strlen_zero(), LOG_ERROR, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and vm_delete().

Referenced by load_module().

2403 {
2404  int res = 0;
2405  char filename[BUFSIZ];
2406 
2407  if (!ast_strlen_zero(data)) {
2408  ast_copy_string(filename, (char *) data, sizeof(filename));
2409  } else {
2410  ast_channel_lock(chan);
2411  ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename));
2412  ast_channel_unlock(chan);
2413  }
2414 
2415  if (ast_strlen_zero(filename)) {
2416  ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n");
2417  return res;
2418  }
2419 
2420  /* Go ahead and delete audio files from system, they're not needed any more */
2421  /* We should look for both audio and text files here */
2422  if (ast_fileexists(filename, NULL, NULL) > 0) {
2423  res = vm_delete(filename);
2424  if (res) {
2425  ast_debug(2, "Can't delete file: %s\n", filename);
2426  pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED");
2427  } else {
2428  ast_debug(2, "Deleted voicemail file :: %s \n", filename);
2429  pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS");
2430  }
2431  } else {
2432  ast_debug(2, "Filename does not exist: %s\n", filename);
2433  pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED");
2434  }
2435 
2436  return res;
2437 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
static int vm_delete(char *file)
Definition: app_minivm.c:1596
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static int minivm_greet_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2210 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(), ast_channel::caller, check_dirpath(), ast_channel::context, minivm_account::domain, minivm_account::exit, ast_channel::exten, find_account(), minivm_account::flags, free_user(), ast_party_caller::id, invent_message(), ast_channel::language, LOG_ERROR, ast_channel::macrocontext, minivm_app_options, MVM_ALLOCED, MVM_OPERATOR, ast_party_id::number, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), ast_channel::priority, S_COR, SOUND_INTRO, ast_party_number::str, TRUE, minivm_account::username, and ast_party_number::valid.

Referenced by load_module().

2211 {
2212  struct leave_vm_options leave_options = { 0, '\0'};
2213  int argc;
2214  char *argv[2];
2215  struct ast_flags flags = { 0 };
2216  char *opts[OPT_ARG_ARRAY_SIZE];
2217  int res = 0;
2218  int ausemacro = 0;
2219  int ousemacro = 0;
2220  int ouseexten = 0;
2221  char tmp[PATH_MAX];
2222  char dest[PATH_MAX];
2223  char prefile[PATH_MAX] = "";
2224  char tempfile[PATH_MAX] = "";
2225  char ext_context[256] = "";
2226  char *domain;
2227  char ecodes[16] = "#";
2228  char *tmpptr;
2229  struct minivm_account *vmu;
2230  char *username = argv[0];
2231 
2232  if (ast_strlen_zero(data)) {
2233  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2234  return -1;
2235  }
2236  tmpptr = ast_strdupa((char *)data);
2237  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2238 
2239  if (argc == 2) {
2240  if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1]))
2241  return -1;
2242  ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
2243  }
2244 
2245  ast_copy_string(tmp, argv[0], sizeof(tmp));
2246  username = tmp;
2247  domain = strchr(tmp, '@');
2248  if (domain) {
2249  *domain = '\0';
2250  domain++;
2251  }
2252  if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
2253  ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]);
2254  return -1;
2255  }
2256  ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain);
2257 
2258  if (!(vmu = find_account(domain, username, TRUE))) {
2259  ast_log(LOG_ERROR, "Could not allocate memory. \n");
2260  return -1;
2261  }
2262 
2263  /* Answer channel if it's not already answered */
2264  if (chan->_state != AST_STATE_UP)
2265  ast_answer(chan);
2266 
2267  /* Setup pre-file if appropriate */
2268  if (strcmp(vmu->domain, "localhost"))
2269  snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain);
2270  else
2271  ast_copy_string(ext_context, vmu->domain, sizeof(ext_context));
2272 
2273  if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) {
2274  res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy");
2275  if (res)
2276  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username);
2277  } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) {
2278  res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail");
2279  if (res)
2280  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username);
2281  }
2282  /* Check for temporary greeting - it overrides busy and unavail */
2283  snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username);
2284  if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) {
2285  ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile);
2286  ast_copy_string(prefile, tempfile, sizeof(prefile));
2287  }
2288  ast_debug(2, "Preparing to play message ...\n");
2289 
2290  /* Check current or macro-calling context for special extensions */
2291  if (ast_test_flag(vmu, MVM_OPERATOR)) {
2292  if (!ast_strlen_zero(vmu->exit)) {
2293  if (ast_exists_extension(chan, vmu->exit, "o", 1,
2294  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
2295  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
2296  ouseexten = 1;
2297  }
2298  } else if (ast_exists_extension(chan, chan->context, "o", 1,
2299  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
2300  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
2301  ouseexten = 1;
2302  }
2303  else if (!ast_strlen_zero(chan->macrocontext)
2304  && ast_exists_extension(chan, chan->macrocontext, "o", 1,
2305  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
2306  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
2307  ousemacro = 1;
2308  }
2309  }
2310 
2311  if (!ast_strlen_zero(vmu->exit)) {
2312  if (ast_exists_extension(chan, vmu->exit, "a", 1,
2313  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
2314  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
2315  }
2316  } else if (ast_exists_extension(chan, chan->context, "a", 1,
2317  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
2318  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
2319  } else if (!ast_strlen_zero(chan->macrocontext)
2320  && ast_exists_extension(chan, chan->macrocontext, "a", 1,
2321  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
2322  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
2323  ausemacro = 1;
2324  }
2325 
2326  res = 0; /* Reset */
2327  /* Play the beginning intro if desired */
2328  if (!ast_strlen_zero(prefile)) {
2329  if (ast_streamfile(chan, prefile, chan->language) > -1)
2330  res = ast_waitstream(chan, ecodes);
2331  } else {
2332  ast_debug(2, "%s doesn't exist, doing what we can\n", prefile);
2333  res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes);
2334  }
2335  if (res < 0) {
2336  ast_debug(2, "Hang up during prefile playback\n");
2337  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED");
2338  if(ast_test_flag(vmu, MVM_ALLOCED))
2339  free_user(vmu);
2340  return -1;
2341  }
2342  if (res == '#') {
2343  /* On a '#' we skip the instructions */
2344  ast_set_flag(&leave_options, OPT_SILENT);
2345  res = 0;
2346  }
2347  if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) {
2348  res = ast_streamfile(chan, SOUND_INTRO, chan->language);
2349  if (!res)
2350  res = ast_waitstream(chan, ecodes);
2351  if (res == '#') {
2352  ast_set_flag(&leave_options, OPT_SILENT);
2353  res = 0;
2354  }
2355  }
2356  if (res > 0)
2357  ast_stopstream(chan);
2358  /* Check for a '*' here in case the caller wants to escape from voicemail to something
2359  other than the operator -- an automated attendant or mailbox login for example */
2360  if (res == '*') {
2361  chan->exten[0] = 'a';
2362  chan->exten[1] = '\0';
2363  if (!ast_strlen_zero(vmu->exit)) {
2364  ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
2365  } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
2366  ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
2367  }
2368  chan->priority = 0;
2369  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
2370  res = 0;
2371  } else if (res == '0') { /* Check for a '0' here */
2372  if(ouseexten || ousemacro) {
2373  chan->exten[0] = 'o';
2374  chan->exten[1] = '\0';
2375  if (!ast_strlen_zero(vmu->exit)) {
2376  ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
2377  } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
2378  ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
2379  }
2380  ast_play_and_wait(chan, "transfer");
2381  chan->priority = 0;
2382  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
2383  }
2384  res = 0;
2385  } else if (res < 0) {
2386  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED");
2387  res = -1;
2388  } else
2389  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS");
2390 
2391  if(ast_test_flag(vmu, MVM_ALLOCED))
2392  free_user(vmu);
2393 
2394 
2395  /* Ok, we're ready to rock and roll. Return to dialplan */
2396  return res;
2397 
2398 }
static struct ast_app_option minivm_app_options[128]
Definition: app_minivm.c:574
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
#define MVM_ALLOCED
Definition: app_minivm.c:516
#define ast_test_flag(p, flag)
Definition: utils.h:63
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:974
unsigned int flags
Definition: utils.h:201
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1504
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int invent_message(struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes)
Definition: app_minivm.c:1539
char exit[80]
Definition: app_minivm.c:599
#define MVM_OPERATOR
Definition: app_minivm.c:511
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
Structure used to handle boolean flags.
Definition: utils.h:200
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:635
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
Definition: app.c:1453
#define SOUND_INTRO
Definition: app_minivm.c:522
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:543
static int minivm_mwi_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2040 of file app_minivm.c.

References ARRAY_LEN, ast_app_separate_args(), ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), minivm_account::domain, LOG_ERROR, mailbox, and queue_mwi_event().

Referenced by load_module().

2041 {
2042  int argc;
2043  char *argv[4];
2044  int res = 0;
2045  char *tmpptr;
2046  char tmp[PATH_MAX];
2047  char *mailbox;
2048  char *domain;
2049  if (ast_strlen_zero(data)) {
2050  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2051  return -1;
2052  }
2053  tmpptr = ast_strdupa((char *)data);
2054  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2055  if (argc < 4) {
2056  ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc);
2057  return -1;
2058  }
2059  ast_copy_string(tmp, argv[0], sizeof(tmp));
2060  mailbox = tmp;
2061  domain = strchr(tmp, '@');
2062  if (domain) {
2063  *domain = '\0';
2064  domain++;
2065  }
2066  if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) {
2067  ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]);
2068  return -1;
2069  }
2070  queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
2071 
2072  return res;
2073 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static void queue_mwi_event(const char *mbx, const char *ctx, int urgent, int new, int old)
Definition: app_minivm.c:2015
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
Definition: app.c:1453
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int minivm_notify_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2078 of file app_minivm.c.

References ARRAY_LEN, ast_app_separate_args(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::caller, minivm_account::domain, find_account(), format, free_user(), ast_party_caller::id, LOG_ERROR, LOG_WARNING, MVM_ALLOCED, ast_party_id::name, notify_new_message(), ast_party_id::number, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_COR, ast_party_name::str, ast_party_number::str, TRUE, minivm_account::username, ast_party_name::valid, and ast_party_number::valid.

Referenced by load_module().

2079 {
2080  int argc;
2081  char *argv[2];
2082  int res = 0;
2083  char tmp[PATH_MAX];
2084  char *domain;
2085  char *tmpptr;
2086  struct minivm_account *vmu;
2087  char *username;
2088  const char *template = "";
2089  const char *filename;
2090  const char *format;
2091  const char *duration_string;
2092 
2093  if (ast_strlen_zero(data)) {
2094  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2095  return -1;
2096  }
2097  tmpptr = ast_strdupa((char *)data);
2098  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2099 
2100  if (argc == 2 && !ast_strlen_zero(argv[1]))
2101  template = argv[1];
2102 
2103  ast_copy_string(tmp, argv[0], sizeof(tmp));
2104  username = tmp;
2105  domain = strchr(tmp, '@');
2106  if (domain) {
2107  *domain = '\0';
2108  domain++;
2109  }
2110  if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
2111  ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
2112  return -1;
2113  }
2114 
2115  if(!(vmu = find_account(domain, username, TRUE))) {
2116  /* We could not find user, let's exit */
2117  ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
2118  pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED");
2119  return -1;
2120  }
2121 
2122  ast_channel_lock(chan);
2123  if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) {
2124  filename = ast_strdupa(filename);
2125  }
2126  ast_channel_unlock(chan);
2127  /* Notify of new message to e-mail and pager */
2128  if (!ast_strlen_zero(filename)) {
2129  ast_channel_lock(chan);
2130  if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) {
2131  format = ast_strdupa(format);
2132  }
2133  if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) {
2134  duration_string = ast_strdupa(duration_string);
2135  }
2136  ast_channel_unlock(chan);
2137  res = notify_new_message(chan, template, vmu, filename, atoi(duration_string),
2138  format,
2139  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
2140  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL));
2141  }
2142 
2143  pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED");
2144 
2145 
2146  if(ast_test_flag(vmu, MVM_ALLOCED))
2147  free_user(vmu);
2148 
2149  /* Ok, we're ready to rock and roll. Return to dialplan */
2150 
2151  return res;
2152 
2153 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define MVM_ALLOCED
Definition: app_minivm.c:516
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
#define LOG_WARNING
Definition: logger.h:144
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:974
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char * str
Subscriber name (Malloced)
Definition: channel.h:214
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)
Definition: app_minivm.c:1763
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1052
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define TRUE
Definition: app_minivm.c:503
unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
Definition: app.c:1453
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
static snd_pcm_format_t format
Definition: chan_alsa.c:93
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int minivm_record_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2157 of file app_minivm.c.

References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args(), ast_copy_flags, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, minivm_account::flags, leave_voicemail(), LOG_ERROR, LOG_WARNING, minivm_app_options, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), and leave_vm_options::record_gain.

Referenced by load_module().

2158 {
2159  int res = 0;
2160  char *tmp;
2161  struct leave_vm_options leave_options;
2162  int argc;
2163  char *argv[2];
2164  struct ast_flags flags = { 0 };
2165  char *opts[OPT_ARG_ARRAY_SIZE];
2166 
2167  memset(&leave_options, 0, sizeof(leave_options));
2168 
2169  /* Answer channel if it's not already answered */
2170  if (chan->_state != AST_STATE_UP)
2171  ast_answer(chan);
2172 
2173  if (ast_strlen_zero(data)) {
2174  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2175  return -1;
2176  }
2177  tmp = ast_strdupa((char *)data);
2178  argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv));
2179  if (argc == 2) {
2180  if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
2181  return -1;
2182  }
2183  ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
2184  if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
2185  int gain;
2186 
2187  if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
2188  ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
2189  return -1;
2190  } else
2191  leave_options.record_gain = (signed char) gain;
2192  }
2193  }
2194 
2195  /* Now run the appliation and good luck to you! */
2196  res = leave_voicemail(chan, argv[0], &leave_options);
2197 
2198  if (res == ERROR_LOCK_PATH) {
2199  ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
2200  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
2201  res = 0;
2202  }
2203  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS");
2204 
2205  return res;
2206 }
static struct ast_app_option minivm_app_options[128]
Definition: app_minivm.c:574
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
unsigned int flags
Definition: utils.h:201
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
static int leave_voicemail(struct ast_channel *chan, char *username, struct leave_vm_options *options)
Definition: app_minivm.c:1843
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:635
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define ERROR_LOCK_PATH
Definition: app_minivm.c:530
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
Definition: app.c:1453
static struct minivm_account* mvm_user_alloc ( void  )
static

Definition at line 1025 of file app_minivm.c.

References ast_calloc, and populate_defaults().

Referenced by find_account(), and find_user_realtime().

1026 {
1027  struct minivm_account *new;
1028 
1029  new = ast_calloc(1, sizeof(*new));
1030  if (!new)
1031  return NULL;
1032  populate_defaults(new);
1033 
1034  return new;
1035 }
static void populate_defaults(struct minivm_account *vmu)
Definition: app_minivm.c:1016
#define ast_calloc(a, b)
Definition: astmm.h:82
static int notify_new_message ( struct ast_channel chan,
const char *  templatename,
struct minivm_account vmu,
const char *  filename,
long  duration,
const char *  format,
char *  cidnum,
char *  cidname 
)
static

Definition at line 1763 of file app_minivm.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_log(), ast_manager_event, ast_strdupa, ast_strlen_zero(), minivm_account::attachfmt, minivm_template::attachment, minivm_account::domain, minivm_account::etemplate, EVENT_FLAG_CALL, minivm_template::locale, LOG_WARNING, message_template_find(), MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_account::pager, pbx_builtin_getvar_helper(), minivm_account::ptemplate, run_externnotify(), sendmail(), strsep(), and minivm_account::username.

Referenced by minivm_notify_exec().

1764 {
1765  char *stringp;
1766  struct minivm_template *etemplate;
1767  char *messageformat;
1768  int res = 0;
1769  char oldlocale[100];
1770  const char *counter;
1771 
1772  if (!ast_strlen_zero(vmu->attachfmt)) {
1773  if (strstr(format, vmu->attachfmt)) {
1774  format = vmu->attachfmt;
1775  } else {
1776  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);
1777  }
1778  }
1779 
1780  etemplate = message_template_find(vmu->etemplate);
1781  if (!etemplate)
1782  etemplate = message_template_find(templatename);
1783  if (!etemplate)
1784  etemplate = message_template_find("email-default");
1785 
1786  /* Attach only the first format */
1787  stringp = messageformat = ast_strdupa(format);
1788  strsep(&stringp, "|");
1789 
1790  if (!ast_strlen_zero(etemplate->locale)) {
1791  char *new_locale;
1792  ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale));
1793  ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale);
1794  new_locale = setlocale(LC_TIME, etemplate->locale);
1795  if (new_locale == NULL) {
1796  ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale);
1797  }
1798  }
1799 
1800 
1801 
1802  /* Read counter if available */
1803  ast_channel_lock(chan);
1804  if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) {
1805  counter = ast_strdupa(counter);
1806  }
1807  ast_channel_unlock(chan);
1808 
1809  if (ast_strlen_zero(counter)) {
1810  ast_debug(2, "MVM_COUNTER not found\n");
1811  } else {
1812  ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter);
1813  }
1814 
1815  res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter);
1816 
1817  if (res == 0 && !ast_strlen_zero(vmu->pager)) {
1818  /* Find template for paging */
1819  etemplate = message_template_find(vmu->ptemplate);
1820  if (!etemplate)
1821  etemplate = message_template_find("pager-default");
1822  if (etemplate->locale) {
1823  ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale));
1824  setlocale(LC_TIME, etemplate->locale);
1825  }
1826 
1827  res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter);
1828  }
1829 
1830  ast_manager_event(chan, EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter);
1831 
1832  run_externnotify(chan, vmu); /* Run external notification */
1833 
1834  if (etemplate->locale) {
1835  setlocale(LC_TIME, oldlocale); /* Rest to old locale */
1836  }
1837  return res;
1838 }
static struct minivm_template * message_template_find(const char *name)
Definition: app_minivm.c:801
char attachfmt[80]
Definition: app_minivm.c:600
#define ast_channel_lock(chan)
Definition: channel.h:2466
char * strsep(char **str, const char *delims)
char etemplate[80]
Definition: app_minivm.c:601
#define LOG_WARNING
Definition: logger.h:144
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
#define EVENT_FLAG_CALL
Definition: manager.h:72
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
char locale[20]
Definition: app_minivm.c:625
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
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)
Definition: app_minivm.c:1219
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
char ptemplate[80]
Definition: app_minivm.c:602
char pager[80]
Definition: app_minivm.c:592
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static void run_externnotify(struct ast_channel *chan, struct minivm_account *vmu)
Run external notification for voicemail message.
Definition: app_minivm.c:1742
static snd_pcm_format_t format
Definition: chan_alsa.c:93
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

Definition at line 1610 of file app_minivm.c.

References acceptdtmf, ast_channel_setoption(), AST_DIGIT_ANY, ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_streamfile(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_waitstream(), global_maxsilence, global_silencethreshold, ast_channel::language, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and vm_delete().

Referenced by leave_voicemail(), and minivm_accmess_exec().

1613 {
1614  int cmd = 0;
1615  int max_attempts = 3;
1616  int attempts = 0;
1617  int recorded = 0;
1618  int message_exists = 0;
1619  signed char zero_gain = 0;
1620  char *acceptdtmf = "#";
1621  char *canceldtmf = "";
1622 
1623  /* Note that urgent and private are for flagging messages as such in the future */
1624 
1625  /* barf if no pointer passed to store duration in */
1626  if (duration == NULL) {
1627  ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
1628  return -1;
1629  }
1630 
1631  cmd = '3'; /* Want to start by recording */
1632 
1633  while ((cmd >= 0) && (cmd != 't')) {
1634  switch (cmd) {
1635  case '1':
1636  ast_verb(3, "Saving message as is\n");
1637  ast_stream_and_wait(chan, "vm-msgsaved", "");
1638  cmd = 't';
1639  break;
1640  case '2':
1641  /* Review */
1642  ast_verb(3, "Reviewing the message\n");
1643  ast_streamfile(chan, recordfile, chan->language);
1644  cmd = ast_waitstream(chan, AST_DIGIT_ANY);
1645  break;
1646  case '3':
1647  message_exists = 0;
1648  /* Record */
1649  if (recorded == 1)
1650  ast_verb(3, "Re-recording the message\n");
1651  else
1652  ast_verb(3, "Recording the message\n");
1653  if (recorded && outsidecaller)
1654  cmd = ast_play_and_wait(chan, "beep");
1655  recorded = 1;
1656  /* 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 */
1657  if (record_gain)
1658  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
1659  if (ast_test_flag(vmu, MVM_OPERATOR))
1660  canceldtmf = "0";
1661  cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf);
1662  if (record_gain)
1663  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
1664  if (cmd == -1) /* User has hung up, no options to give */
1665  return cmd;
1666  if (cmd == '0')
1667  break;
1668  else if (cmd == '*')
1669  break;
1670  else {
1671  /* If all is well, a message exists */
1672  message_exists = 1;
1673  cmd = 0;
1674  }
1675  break;
1676  case '4':
1677  case '5':
1678  case '6':
1679  case '7':
1680  case '8':
1681  case '9':
1682  case '*':
1683  case '#':
1684  cmd = ast_play_and_wait(chan, "vm-sorry");
1685  break;
1686  case '0':
1687  if(!ast_test_flag(vmu, MVM_OPERATOR)) {
1688  cmd = ast_play_and_wait(chan, "vm-sorry");
1689  break;
1690  }
1691  if (message_exists || recorded) {
1692  cmd = ast_play_and_wait(chan, "vm-saveoper");
1693  if (!cmd)
1694  cmd = ast_waitfordigit(chan, 3000);
1695  if (cmd == '1') {
1696  ast_play_and_wait(chan, "vm-msgsaved");
1697  cmd = '0';
1698  } else {
1699  ast_play_and_wait(chan, "vm-deleted");
1700  vm_delete(recordfile);
1701  cmd = '0';
1702  }
1703  }
1704  return cmd;
1705  default:
1706  /* If the caller is an ouside caller, and the review option is enabled,
1707  allow them to review the message, but let the owner of the box review
1708  their OGM's */
1709  if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW))
1710  return cmd;
1711  if (message_exists) {
1712  cmd = ast_play_and_wait(chan, "vm-review");
1713  } else {
1714  cmd = ast_play_and_wait(chan, "vm-torerecord");
1715  if (!cmd)
1716  cmd = ast_waitfordigit(chan, 600);
1717  }
1718 
1719  if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) {
1720  cmd = ast_play_and_wait(chan, "vm-reachoper");
1721  if (!cmd)
1722  cmd = ast_waitfordigit(chan, 600);
1723  }
1724  if (!cmd)
1725  cmd = ast_waitfordigit(chan, 6000);
1726  if (!cmd) {
1727  attempts++;
1728  }
1729  if (attempts > max_attempts) {
1730  cmd = 't';
1731  }
1732  }
1733  }
1734  if (outsidecaller)
1735  ast_play_and_wait(chan, "vm-goodbye");
1736  if (cmd == 't')
1737  cmd = 0;
1738  return cmd;
1739 }
static int vm_delete(char *file)
Definition: app_minivm.c:1596
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf)
Record a file based on input from a channel This function will play &quot;auth-thankyou&quot; upon successful r...
Definition: app.c:1178
#define MVM_REVIEW
Definition: app_minivm.c:510
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
static int global_silencethreshold
Definition: app_minivm.c:683
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7795
#define ast_verb(level,...)
Definition: logger.h:243
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define MVM_OPERATOR
Definition: app_minivm.c:511
static int global_maxsilence
Definition: app_minivm.c:681
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
static char acceptdtmf
Definition: chan_agent.c:227
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
#define AST_OPTION_RXGAIN
Definition: frame.h:463
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
const ast_string_field language
Definition: channel.h:787
static void populate_defaults ( struct minivm_account vmu)
static

Definition at line 1016 of file app_minivm.c.

References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, minivm_account::attachfmt, default_vmformat, global_volgain, globalflags, and minivm_account::volgain.

Referenced by create_vmaccount(), find_user_realtime(), and mvm_user_alloc().

1017 {
1019  ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt));
1020  vmu->volgain = global_volgain;
1021 }
char attachfmt[80]
Definition: app_minivm.c:600
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
double volgain
Definition: app_minivm.c:605
static char default_vmformat[80]
Definition: app_minivm.c:687
#define AST_FLAGS_ALL
Definition: utils.h:196
static double global_volgain
Definition: app_minivm.c:692
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static struct ast_flags globalflags
Definition: app_minivm.c:689
static void prep_email_sub_vars ( struct ast_channel channel,
const struct minivm_account vmu,
const char *  cidnum,
const char *  cidname,
const char *  dur,
const char *  date,
const char *  counter 
)
static

Definition at line 987 of file app_minivm.c.

References ast_callerid_merge(), ast_log(), ast_strlen_zero(), minivm_account::chanvars, minivm_account::domain, minivm_account::fullname, LOG_ERROR, ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), minivm_account::username, ast_variable::value, and var.

Referenced by sendmail().

988 {
989  char callerid[256];
990  struct ast_variable *var;
991 
992  if (!channel) {
993  ast_log(LOG_ERROR, "No allocated channel, giving up...\n");
994  return;
995  }
996 
997  for (var = vmu->chanvars ; var ; var = var->next) {
998  pbx_builtin_setvar_helper(channel, var->name, var->value);
999  }
1000 
1001  /* Prepare variables for substition in email body and subject */
1002  pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname);
1003  pbx_builtin_setvar_helper(channel, "MVM_DUR", dur);
1004  pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain);
1005  pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username);
1006  pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
1007  pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller"));
1008  pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
1009  pbx_builtin_setvar_helper(channel, "MVM_DATE", date);
1010  if (!ast_strlen_zero(counter))
1011  pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter);
1012 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
const char * value
Definition: config.h:79
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1074
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const char * name
Definition: config.h:77
#define LOG_ERROR
Definition: logger.h:155
struct ast_variable * chanvars
Definition: app_minivm.c:604
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char fullname[120]
Definition: app_minivm.c:590
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
struct ast_variable * next
Definition: config.h:82
static void queue_mwi_event ( const char *  mbx,
const char *  ctx,
int  urgent,
int  new,
int  old 
)
static

Definition at line 2015 of file app_minivm.c.

References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, ast_strlen_zero(), context, and mailbox.

Referenced by minivm_mwi_exec().

2016 {
2017  struct ast_event *event;
2018  char *mailbox, *context;
2019 
2020  mailbox = ast_strdupa(mbx);
2021  context = ast_strdupa(ctx);
2022  if (ast_strlen_zero(context)) {
2023  context = "default";
2024  }
2025 
2026  if (!(event = ast_event_new(AST_EVENT_MWI,
2031  AST_EVENT_IE_END))) {
2032  return;
2033  }
2034 
2036 }
An event.
Definition: event.c:85
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
Definition: event.c:1465
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
Number of Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:77
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:1202
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
Mailbox name.
Definition: event_defs.h:83
static int reload ( void  )
static

Reload mini voicemail module.

Definition at line 3492 of file app_minivm.c.

References load_config().

Referenced by handle_minivm_reload().

3493 {
3494  return(load_config(1));
3495 }
static int load_config(int reload)
Load minivoicemail configuration.
Definition: app_minivm.c:2807
static void run_externnotify ( struct ast_channel chan,
struct minivm_account vmu 
)
static

Run external notification for voicemail message.

Definition at line 1742 of file app_minivm.c.

References ast_debug, ast_safe_system(), ast_strlen_zero(), ast_channel::caller, minivm_account::domain, minivm_account::externnotify, global_externnotify, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_name::str, ast_party_number::str, minivm_account::username, ast_party_name::valid, and ast_party_number::valid.

Referenced by notify_new_message().

1743 {
1744  char arguments[BUFSIZ];
1745 
1747  return;
1748 
1749  snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&",
1751  vmu->username, vmu->domain,
1752  (chan->caller.id.name.valid && chan->caller.id.name.str)
1753  ? chan->caller.id.name.str : "",
1754  (chan->caller.id.number.valid && chan->caller.id.number.str)
1755  ? chan->caller.id.number.str : "");
1756 
1757  ast_debug(1, "Executing: %s\n", arguments);
1758  ast_safe_system(arguments);
1759 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
char * str
Subscriber name (Malloced)
Definition: channel.h:214
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char global_externnotify[160]
Definition: app_minivm.c:685
char externnotify[160]
Definition: app_minivm.c:595
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int sendmail ( struct minivm_template template,
struct minivm_account vmu,
char *  cidnum,
char *  cidname,
const char *  filename,
char *  format,
int  duration,
int  attach_user_voicemail,
enum mvm_messagetype  type,
const char *  counter 
)
static

Definition at line 1219 of file app_minivm.c.

References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_tvnow(), base_encode(), check_mime(), minivm_account::domain, minivm_account::email, errno, first_line, minivm_account::fullname, global_mailcmd, LOG_WARNING, MAXHOSTNAMELEN, MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_zone::name, option_debug, minivm_account::pager, prep_email_sub_vars(), minivm_account::serveremail, minivm_zone::timezone, minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.

Referenced by notify_new_message().

1220 {
1221  FILE *p = NULL;
1222  int pfd;
1223  char email[256] = "";
1224  char who[256] = "";
1225  char date[256];
1226  char bound[256];
1227  char fname[PATH_MAX];
1228  char dur[PATH_MAX];
1229  char tmp[80] = "/tmp/astmail-XXXXXX";
1230  char tmp2[PATH_MAX];
1231  char newtmp[PATH_MAX]; /* Only used with volgain */
1232  struct timeval now;
1233  struct ast_tm tm;
1234  struct minivm_zone *the_zone = NULL;
1235  struct ast_channel *ast;
1236  char *finalfilename = "";
1237  struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
1238  char *fromaddress;
1239  char *fromemail;
1240 
1241  if (!str1 || !str2) {
1242  ast_free(str1);
1243  ast_free(str2);
1244  return -1;
1245  }
1246 
1247  if (type == MVM_MESSAGE_EMAIL) {
1248  if (vmu && !ast_strlen_zero(vmu->email)) {
1249  ast_copy_string(email, vmu->email, sizeof(email));
1250  } else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain))
1251  snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain);
1252  } else if (type == MVM_MESSAGE_PAGE) {
1253  ast_copy_string(email, vmu->pager, sizeof(email));
1254  }
1255 
1256  if (ast_strlen_zero(email)) {
1257  ast_log(LOG_WARNING, "No address to send message to.\n");
1258  ast_free(str1);
1259  ast_free(str2);
1260  return -1;
1261  }
1262 
1263  ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name);
1264 
1265  if (!strcmp(format, "wav49"))
1266  format = "WAV";
1267 
1268 
1269  /* If we have a gain option, process it now with sox */
1270  if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) {
1271  char tmpcmd[PATH_MAX];
1272  int tmpfd;
1273 
1274  ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp));
1275  ast_debug(3, "newtmp: %s\n", newtmp);
1276  tmpfd = mkstemp(newtmp);
1277  if (tmpfd < 0) {
1278  ast_log(LOG_WARNING, "Failed to create temporary file for volgain: %d\n", errno);
1279  ast_free(str1);
1280  ast_free(str2);
1281  return -1;
1282  }
1283  snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format);
1284  ast_safe_system(tmpcmd);
1285  close(tmpfd);
1286  finalfilename = newtmp;
1287  ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
1288  } else {
1289  finalfilename = ast_strdupa(filename);
1290  }
1291 
1292  /* Create file name */
1293  snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format);
1294 
1295  if (template->attachment)
1296  ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail);
1297 
1298  /* Make a temporary file instead of piping directly to sendmail, in case the mail
1299  command hangs */
1300  pfd = mkstemp(tmp);
1301  if (pfd > -1) {
1302  p = fdopen(pfd, "w");
1303  if (!p) {
1304  close(pfd);
1305  pfd = -1;
1306  }
1307  ast_debug(1, "Opening temp file for e-mail: %s\n", tmp);
1308  }
1309  if (!p) {
1310  ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp);
1311  ast_free(str1);
1312  ast_free(str2);
1313  return -1;
1314  }
1315  /* Allocate channel used for chanvar substitution */
1316  ast = ast_dummy_channel_alloc();
1317  if (!ast) {
1318  ast_free(str1);
1319  ast_free(str2);
1320  return -1;
1321  }
1322 
1323  snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
1324 
1325  /* Does this user have a timezone specified? */
1326  if (!ast_strlen_zero(vmu->zonetag)) {
1327  /* Find the zone in the list */
1328  struct minivm_zone *z;
1331  if (strcmp(z->name, vmu->zonetag))
1332  continue;
1333  the_zone = z;
1334  }
1336  }
1337 
1338  now = ast_tvnow();
1339  ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL);
1340  ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
1341 
1342  /* Start printing the email to the temporary file */
1343  fprintf(p, "Date: %s\n", date);
1344 
1345  /* Set date format for voicemail mail */
1346  ast_strftime(date, sizeof(date), template->dateformat, &tm);
1347 
1348 
1349  /* Populate channel with channel variables for substitution */
1350  prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter);
1351 
1352  /* Find email address to use */
1353  /* If there's a server e-mail adress in the account, user that, othterwise template */
1354  fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail;
1355 
1356  /* Find name to user for server e-mail */
1357  fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress;
1358 
1359  /* If needed, add hostname as domain */
1360  if (ast_strlen_zero(fromemail))
1361  fromemail = "asterisk";
1362 
1363  if (strchr(fromemail, '@'))
1364  ast_copy_string(who, fromemail, sizeof(who));
1365  else {
1366  char host[MAXHOSTNAMELEN];
1367  gethostname(host, sizeof(host)-1);
1368  snprintf(who, sizeof(who), "%s@%s", fromemail, host);
1369  }
1370 
1371  if (ast_strlen_zero(fromaddress)) {
1372  fprintf(p, "From: Asterisk PBX <%s>\n", who);
1373  } else {
1374  ast_debug(4, "Fromaddress template: %s\n", fromaddress);
1375  ast_str_substitute_variables(&str1, 0, ast, fromaddress);
1376  if (check_mime(ast_str_buffer(str1))) {
1377  int first_line = 1;
1378  char *ptr;
1379  ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3);
1380  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
1381  *ptr = '\0';
1382  fprintf(p, "%s %s\n", first_line ? "From:" : "", ast_str_buffer(str2));
1383  first_line = 0;
1384  /* Substring is smaller, so this will never grow */
1385  ast_str_set(&str2, 0, "%s", ptr + 1);
1386  }
1387  fprintf(p, "%s %s <%s>\n", first_line ? "From:" : "", ast_str_buffer(str2), who);
1388  } else {
1389  fprintf(p, "From: %s <%s>\n", ast_str_quote(&str2, 0, ast_str_buffer(str1)), who);
1390  }
1391  }
1392 
1393  fprintf(p, "Message-ID: <Asterisk-%u-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who);
1394 
1395  if (ast_strlen_zero(vmu->email)) {
1396  snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain);
1397  } else {
1398  ast_copy_string(email, vmu->email, sizeof(email));
1399  }
1400 
1401  if (check_mime(vmu->fullname)) {
1402  int first_line = 1;
1403  char *ptr;
1404  ast_str_encode_mime(&str2, 0, template->charset, vmu->fullname, strlen("To: "), strlen(email) + 3);
1405  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
1406  *ptr = '\0';
1407  fprintf(p, "%s %s\n", first_line ? "To:" : "", ast_str_buffer(str2));
1408  first_line = 0;
1409  /* Substring is smaller, so this will never grow */
1410  ast_str_set(&str2, 0, "%s", ptr + 1);
1411  }
1412  fprintf(p, "%s %s <%s>\n", first_line ? "To:" : "", ast_str_buffer(str2), email);
1413  } else {
1414  fprintf(p, "To: %s <%s>\n", ast_str_quote(&str2, 0, vmu->fullname), email);
1415  }
1416 
1417  if (!ast_strlen_zero(template->subject)) {
1418  ast_str_substitute_variables(&str1, 0, ast, template->subject);
1419  if (check_mime(ast_str_buffer(str1))) {
1420  int first_line = 1;
1421  char *ptr;
1422  ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("Subject: "), 0);
1423  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
1424  *ptr = '\0';
1425  fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2));
1426  first_line = 0;
1427  /* Substring is smaller, so this will never grow */
1428  ast_str_set(&str2, 0, "%s", ptr + 1);
1429  }
1430  fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2));
1431  } else {
1432  fprintf(p, "Subject: %s\n", ast_str_buffer(str1));
1433  }
1434  } else {
1435  fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain);
1436  ast_debug(1, "Using default subject for this email \n");
1437  }
1438 
1439  if (option_debug > 2)
1440  fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain);
1441  fprintf(p, "MIME-Version: 1.0\n");
1442 
1443  /* Something unique. */
1444  snprintf(bound, sizeof(bound), "voicemail_%s%d%u", vmu->username, (int)getpid(), (unsigned int)ast_random());
1445 
1446  fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound);
1447 
1448  fprintf(p, "--%s\n", bound);
1449  fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", template->charset);
1450  if (!ast_strlen_zero(template->body)) {
1451  ast_str_substitute_variables(&str1, 0, ast, template->body);
1452  ast_debug(3, "Message now: %s\n-----\n", ast_str_buffer(str1));
1453  fprintf(p, "%s\n", ast_str_buffer(str1));
1454  } else {
1455  fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n"
1456  "in mailbox %s from %s, on %s so you might\n"
1457  "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname,
1458  dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
1459  ast_debug(3, "Using default message body (no template)\n-----\n");
1460  }
1461  /* Eww. We want formats to tell us their own MIME type */
1462  if (template->attachment) {
1463  char *ctype = "audio/x-";
1464  ast_debug(3, "Attaching file to message: %s\n", fname);
1465  if (!strcasecmp(format, "ogg"))
1466  ctype = "application/";
1467 
1468  fprintf(p, "--%s\n", bound);
1469  fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format);
1470  fprintf(p, "Content-Transfer-Encoding: base64\n");
1471  fprintf(p, "Content-Description: Voicemail sound attachment.\n");
1472  fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format);
1473 
1474  base_encode(fname, p);
1475  fprintf(p, "\n\n--%s--\n.\n", bound);
1476  }
1477  fclose(p);
1478  snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp);
1479  ast_safe_system(tmp2);
1480  ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : "");
1481  ast_debug(3, "Actual command used: %s\n", tmp2);
1482  ast = ast_channel_unref(ast);
1483  ast_free(str1);
1484  ast_free(str2);
1485  return 0;
1486 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
char name[80]
Definition: app_minivm.c:651
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
int option_debug
Definition: asterisk.c:182
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
static char email[80]
Definition: pbx_dundi.c:197
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:586
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Definition: pbx.c:4468
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define MAXHOSTNAMELEN
Definition: network.h:69
static char global_mailcmd[160]
Definition: app_minivm.c:684
static int base_encode(char *filename, FILE *so)
Definition: app_minivm.c:890
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:587
char subject[100]
Definition: app_minivm.c:623
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char email[80]
Definition: app_minivm.c:591
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
long int ast_random(void)
Definition: utils.c:1640
char zonetag[80]
Definition: app_minivm.c:597
char timezone[80]
Definition: app_minivm.c:652
static const char * ast_str_quote(struct ast_str **buf, ssize_t maxlen, const char *from)
Definition: app_minivm.c:1199
double volgain
Definition: app_minivm.c:605
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int check_mime(const char *str)
Definition: app_minivm.c:1129
char name[80]
Definition: app_minivm.c:619
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
Voicemail time zones.
Definition: app_minivm.c:650
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int errno
#define ast_free(a)
Definition: astmm.h:97
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
static const char type[]
Definition: chan_nbs.c:57
The list of e-mail time zones.
Definition: app_minivm.c:658
char charset[32]
Definition: app_minivm.c:624
char fullname[120]
Definition: app_minivm.c:590
char pager[80]
Definition: app_minivm.c:592
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct minivm_zone::@49 list
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)
Definition: app_minivm.c:1158
char fromaddress[100]
Definition: app_minivm.c:621
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
static snd_pcm_format_t format
Definition: chan_alsa.c:93
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)
Definition: app_minivm.c:987
char dateformat[80]
Definition: app_minivm.c:626
char serveremail[80]
Definition: app_minivm.c:594
yylloc first_line
Definition: ast_expr2.c:1857
static int timezone_add ( const char *  zonename,
const char *  config 
)
static

Add time zone to memory list.

Definition at line 2650 of file app_minivm.c.

References ast_calloc, ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, global_stats, LOG_WARNING, minivm_zone::msg_format, minivm_zone::name, strsep(), minivm_zone::timezone, and minivm_stats::timezones.

Referenced by load_config().

2651 {
2652  struct minivm_zone *newzone;
2653  char *msg_format, *timezone_str;
2654 
2655  newzone = ast_calloc(1, sizeof(*newzone));
2656  if (newzone == NULL)
2657  return 0;
2658 
2659  msg_format = ast_strdupa(config);
2660 
2661  timezone_str = strsep(&msg_format, "|");
2662  if (!msg_format) {
2663  ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename);
2664  ast_free(newzone);
2665  return 0;
2666  }
2667 
2668  ast_copy_string(newzone->name, zonename, sizeof(newzone->name));
2669  ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone));
2670  ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format));
2671 
2675 
2677 
2678  return 0;
2679 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static const char config[]
Definition: cdr_csv.c:57
char * strsep(char **str, const char *delims)
char name[80]
Definition: app_minivm.c:651
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:672
char timezone[80]
Definition: app_minivm.c:652
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
char msg_format[BUFSIZ]
Definition: app_minivm.c:653
Voicemail time zones.
Definition: app_minivm.c:650
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
The list of e-mail time zones.
Definition: app_minivm.c:658
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct minivm_zone::@49 list
static void timezone_destroy_list ( void  )
static

Clear list of timezones.

Definition at line 2638 of file app_minivm.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().

Referenced by load_config(), and unload_module().

2639 {
2640  struct minivm_zone *this;
2641 
2643  while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list)))
2644  free_zone(this);
2645 
2647 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static void free_zone(struct minivm_zone *z)
Free Mini Voicemail timezone.
Definition: app_minivm.c:2632
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
Voicemail time zones.
Definition: app_minivm.c:650
The list of e-mail time zones.
Definition: app_minivm.c:658
struct minivm_zone::@49 list
static int unload_module ( void  )
static

Unload mini voicemail module.

Definition at line 3518 of file app_minivm.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_unregister_application(), cli_minivm, message_destroy_list(), minivm_account_function, minivm_counter_function, timezone_destroy_list(), and vmaccounts_destroy_list().

3519 {
3520  int res;
3521 
3528 
3532 
3533  message_destroy_list(); /* Destroy list of voicemail message templates */
3534  timezone_destroy_list(); /* Destroy list of timezones */
3535  vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */
3536 
3537  return res;
3538 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_custom_function minivm_counter_function
Definition: app_minivm.c:3452
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
static char * app_minivm_notify
Definition: app_minivm.c:548
static void vmaccounts_destroy_list(void)
Definition: app_minivm.c:1040
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static void timezone_destroy_list(void)
Clear list of timezones.
Definition: app_minivm.c:2638
static char * app_minivm_record
Definition: app_minivm.c:546
static struct ast_cli_entry cli_minivm[]
CLI commands for Mini-voicemail.
Definition: app_minivm.c:3443
static char * app_minivm_mwi
Definition: app_minivm.c:551
static char * app_minivm_accmess
Definition: app_minivm.c:550
static char * app_minivm_greet
Definition: app_minivm.c:547
static void message_destroy_list(void)
Definition: app_minivm.c:823
static char * app_minivm_delete
Definition: app_minivm.c:549
static struct ast_custom_function minivm_account_function
Definition: app_minivm.c:3458
static int vm_delete ( char *  file)
static

Definition at line 1596 of file app_minivm.c.

References ast_debug, and ast_filedelete().

Referenced by minivm_delete_exec(), and play_record_review().

1597 {
1598  int res;
1599 
1600  ast_debug(1, "Deleting voicemail file %s\n", file);
1601 
1602  res = unlink(file); /* Remove the meta data file */
1603  res |= ast_filedelete(file, NULL); /* remove the media file */
1604  return res;
1605 }
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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 3247 of file app_minivm.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

Referenced by access_counter_file().

3248 {
3249  switch (ast_lock_path(path)) {
3250  case AST_LOCK_TIMEOUT:
3251  return -1;
3252  default:
3253  return 0;
3254  }
3255 }
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Definition: app.c:1652
static void vmaccounts_destroy_list ( void  )
static

Definition at line 1040 of file app_minivm.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.

Referenced by load_config(), and unload_module().

1041 {
1042  struct minivm_account *this;
1044  while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list)))
1045  ast_free(this);
1047 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct minivm_account::@47 list
#define ast_free(a)
Definition: astmm.h:97

Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 3545 of file app_minivm.c.

char* app_minivm_accmess = "MinivmAccMess"
static

Definition at line 550 of file app_minivm.c.

char* app_minivm_delete = "MinivmDelete"
static

Definition at line 549 of file app_minivm.c.

char* app_minivm_greet = "MinivmGreet"
static

Definition at line 547 of file app_minivm.c.

char* app_minivm_mwi = "MinivmMWI"
static

Definition at line 551 of file app_minivm.c.

char* app_minivm_notify = "MinivmNotify"
static

Definition at line 548 of file app_minivm.c.

char* app_minivm_record = "MinivmRecord"
static

Definition at line 546 of file app_minivm.c.

Definition at line 3545 of file app_minivm.c.

struct ast_cli_entry cli_minivm[]
static

CLI commands for Mini-voicemail.

Definition at line 3443 of file app_minivm.c.

Referenced by load_module(), and unload_module().

char default_vmformat[80]
static
char global_externnotify[160]
static

External notification application

Definition at line 685 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 686 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 684 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 682 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 681 of file app_minivm.c.

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

int global_saydurationminfo
static

Definition at line 690 of file app_minivm.c.

Referenced by load_config().

int global_silencethreshold = 128
static
struct minivm_stats global_stats
static

Statistics for voicemail.

Definition at line 672 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 680 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 679 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 692 of file app_minivm.c.

Referenced by populate_defaults().

struct ast_flags globalflags = {0}
static

Global voicemail flags

Definition at line 689 of file app_minivm.c.

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

struct message_templates message_templates = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
struct ast_app_option minivm_accmess_options[128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING }, }
static

Definition at line 581 of file app_minivm.c.

Referenced by minivm_accmess_exec().

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:3170

Definition at line 3458 of file app_minivm.c.

Referenced by load_module(), and unload_module().

struct minivm_accounts minivm_accounts = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
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 574 of file app_minivm.c.

Referenced by minivm_greet_exec(), and minivm_record_exec().

struct ast_custom_function minivm_counter_function
static
Initial value:
= {
.name = "MINIVMCOUNTER",
}
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:3317
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:3371

Definition at line 3452 of file app_minivm.c.

Referenced by load_module(), and unload_module().

struct minivm_zones minivm_zones = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
ast_mutex_t minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Lock to protect voicemail system

Definition at line 674 of file app_minivm.c.

Referenced by load_config().

FILE* minivmlogfile
static

The minivm log file

Definition at line 677 of file app_minivm.c.

Referenced by leave_voicemail(), and load_config().

ast_mutex_t minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Lock to protect voicemail system log file

Definition at line 675 of file app_minivm.c.

Referenced by leave_voicemail().

char MVM_SPOOL_DIR[PATH_MAX]
static

Definition at line 543 of file app_minivm.c.