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

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

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

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...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static const char * ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *charset, const char *start, size_t preamble, size_t postamble)
 
static const char * ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from)
 
static int 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 *channel_id, 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
 
static char * app_minivm_accmess = "MinivmAccMess"
 
static char * app_minivm_delete = "MinivmDelete"
 
static char * app_minivm_greet = "MinivmGreet"
 
static char * app_minivm_mwi = "MinivmMWI"
 
static char * app_minivm_notify = "MinivmNotify"
 
static char * app_minivm_record = "MinivmRecord"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_minivm []
 CLI commands for Mini-voicemail. 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, 0} } , }
 
static const struct ast_app_option minivm_accmess_options [128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING }, }
 
static struct ast_custom_function minivm_account_function
 
static struct minivm_accounts minivm_accounts = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static const struct ast_app_option minivm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, }
 
static struct ast_custom_function minivm_counter_function
 
static struct minivm_zones minivm_zones = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static ast_mutex_t minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static FILE * minivmlogfile
 
static ast_mutex_t minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static char MVM_SPOOL_DIR [PATH_MAX]
 

Detailed Description

MiniVoiceMail - A Minimal Voicemail System for Asterisk.

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

See also

Definition in file app_minivm.c.

Macro Definition Documentation

◆ ASTERISK_USERNAME

#define ASTERISK_USERNAME   "asterisk"

Default username for sending mail is asterisk@localhost

Definition at line 549 of file app_minivm.c.

◆ B64_BASELINELEN

#define B64_BASELINELEN   72

Line length for Base 64 endoded messages

Definition at line 539 of file app_minivm.c.

Referenced by b64_ochar().

◆ B64_BASEMAXINLINE

#define B64_BASEMAXINLINE   256

Buffer size for Base 64 attachment encoding

Definition at line 538 of file app_minivm.c.

Referenced by b64_inbuf(), and base_encode().

◆ DEFAULT_CHARSET

#define DEFAULT_CHARSET   "ISO-8859-1"

Definition at line 712 of file app_minivm.c.

Referenced by message_template_create().

◆ DEFAULT_DATEFORMAT

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

Definition at line 711 of file app_minivm.c.

Referenced by message_template_create().

◆ EOL

#define EOL   "\r\n"

Definition at line 540 of file app_minivm.c.

Referenced by b64_ochar(), and base_encode().

◆ ERROR_LOCK_PATH

#define ERROR_LOCK_PATH   -100

Definition at line 545 of file app_minivm.c.

Referenced by minivm_record_exec().

◆ FALSE

#define FALSE   0

Definition at line 521 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_dialog_unlink_sched_items(), do_monitor(), expire_register(), extensionstate_update(), find_sdp(), function_sippeer(), getremainingfilelength(), handle_cli_ooh323_set_debug(), handle_incoming(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_response(), handle_response_invite(), interpret_t38_parameters(), invent_message(), load_config(), main(), manager_sip_peer_status(), minivm_accmess_exec(), minivm_counter_func_read(), minivm_counter_func_write(), ooh323c_call_thread(), ooh323c_set_capability(), ooh323c_set_capability_for_call(), parse_register_contact(), parse_sip_options(), parseargs(), parsedoublearg(), parsefreq(), parseintarg(), parseswitch(), parseswitcharg(), parsetime(), parsetimearg(), parsevolarg(), parsevolume(), pidf_validate_presence(), pidf_validate_tuple(), proc_session_timer(), process_crypto(), process_sdp(), process_sdp_a_audio(), process_sdp_a_dtls(), process_sdp_a_ice(), process_sdp_a_image(), process_sdp_a_rtcp_mux(), 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(), readwavheader(), register_realtime_peers_with_callbackextens(), 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_find_peer_by_ip_and_exten(), 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_report_security_event(), sip_sendhtml(), sip_set_history(), sip_set_rtp_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(), update_connectedline(), and workloop().

◆ HMSU_OUTPUT_FORMAT

#define HMSU_OUTPUT_FORMAT   "%-23s %-15s %-15s %-10s %-10s %-50s\n"

◆ HMSZ_OUTPUT_FORMAT

#define HMSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"

◆ HVLT_OUTPUT_FORMAT

#define HVLT_OUTPUT_FORMAT   "%-15s %-10s %-10s %-15.15s %-50s\n"

◆ MAX_DATETIME_FORMAT

#define MAX_DATETIME_FORMAT   512

Definition at line 542 of file app_minivm.c.

◆ MAX_NUM_CID_CONTEXTS

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 543 of file app_minivm.c.

◆ MVM_ALLOCED

#define MVM_ALLOCED   (1 << 13)

◆ MVM_ENVELOPE

#define MVM_ENVELOPE   (1 << 4)

Definition at line 529 of file app_minivm.c.

◆ MVM_OPERATOR

#define MVM_OPERATOR   (1 << 1)

Operator exit during voicemail recording

Definition at line 526 of file app_minivm.c.

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

◆ MVM_PBXSKIP

#define MVM_PBXSKIP   (1 << 9)

Definition at line 530 of file app_minivm.c.

◆ MVM_REALTIME

#define MVM_REALTIME   (1 << 2)

This user is a realtime account

Definition at line 527 of file app_minivm.c.

◆ MVM_REVIEW

#define MVM_REVIEW   (1 << 0)

Review message

Definition at line 525 of file app_minivm.c.

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

◆ MVM_SVMAIL

#define MVM_SVMAIL   (1 << 3)

Definition at line 528 of file app_minivm.c.

◆ SENDMAIL

#define SENDMAIL   "/usr/sbin/sendmail -t"

Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.

Definition at line 535 of file app_minivm.c.

Referenced by load_config().

◆ SOUND_INTRO

#define SOUND_INTRO   "vm-intro"

Definition at line 537 of file app_minivm.c.

Referenced by minivm_greet_exec().

◆ TRUE

#define TRUE   1

Definition at line 518 of file app_minivm.c.

Referenced by __sip_ack(), __sip_alloc(), __sip_autodestruct(), __sip_semi_ack(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), acl_change_stasis_cb(), 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(), forked_invite_init(), function_sippeer(), get_sip_pvt_from_replaces(), getremainingfilelength(), gmtload(), handle_cli_ooh323_set_debug(), handle_request_invite(), handle_request_invite_st(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), interpret_t38_parameters(), leave_voicemail(), load_config(), local_attended_transfer(), main(), manager_sip_peer_status(), message_template_create(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), ooh323_call(), ooh323c_start_call_thread(), parse_ok_contact(), parse_register_contact(), parse_sip_options(), parsedoublearg(), parsefreq(), parseintarg(), parseswitch(), parseswitcharg(), parsetime(), parsetimearg(), parsevolarg(), parsevolume(), pidf_validate_presence(), pidf_validate_tuple(), proc_session_timer(), process_crypto(), process_sdp(), process_sdp_a_audio(), process_sdp_a_dtls(), process_sdp_a_ice(), process_sdp_a_image(), process_sdp_a_rtcp_mux(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), proxy_update(), rcvfax_exec(), readwavheader(), realtime_peer(), receive_message(), reg_source_db(), register_realtime_peers_with_callbackextens(), register_verify(), reload_config(), reqprep(), respprep(), restart_session_timer(), set_destination(), sip_addheader(), sip_answer(), sip_cc_agent_respond(), sip_devicestate(), sip_do_debug_peer(), sip_find_peer_by_ip_and_exten(), sip_hangup(), sip_indicate(), sip_is_xml_parsable(), sip_msg_send(), sip_pidf_validate(), sip_prune_realtime(), sip_reload(), sip_report_security_event(), sip_request_call(), sip_set_history(), sip_show_channel(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), sip_write(), sndfax_exec(), spandsp_fax_gateway_start(), spandsp_fax_start(), st_get_se(), start_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(), update_connectedline(), and workloop().

◆ VOICEMAIL_CONFIG

#define VOICEMAIL_CONFIG   "minivm.conf"

Definition at line 548 of file app_minivm.c.

Referenced by load_config().

◆ VOICEMAIL_DIR_MODE

#define VOICEMAIL_DIR_MODE   0700

Definition at line 546 of file app_minivm.c.

Enumeration Type Documentation

◆ minivm_option_args

Enumerator
OPT_ARG_RECORDGAIN 
OPT_ARG_ARRAY_SIZE 

Definition at line 579 of file app_minivm.c.

◆ minivm_option_flags

Enumerator
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_TEMP_GREETING 
OPT_NAME_GREETING 
OPT_RECORDGAIN 

Definition at line 570 of file app_minivm.c.

570  {
571  OPT_SILENT = (1 << 0),
572  OPT_BUSY_GREETING = (1 << 1),
573  OPT_UNAVAIL_GREETING = (1 << 2),
574  OPT_TEMP_GREETING = (1 << 3),
575  OPT_NAME_GREETING = (1 << 4),
576  OPT_RECORDGAIN = (1 << 5),
577 };

◆ mvm_messagetype

Message types for notification.

Enumerator
MVM_MESSAGE_EMAIL 
MVM_MESSAGE_PAGE 

Definition at line 552 of file app_minivm.c.

552  {
555  /* For trunk: MVM_MESSAGE_JABBER, */
556 };

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 3599 of file app_minivm.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 3599 of file app_minivm.c.

◆ access_counter_file()

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 3319 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().

3320 {
3321  char filename[BUFSIZ];
3322  char readbuf[BUFSIZ];
3323  FILE *counterfile;
3324  int old = 0, counter = 0;
3325 
3326  /* Lock directory */
3327  if (vm_lock_path(directory)) {
3328  return -1; /* Could not lock directory */
3329  }
3330  snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername);
3331  if (operand != 1) {
3332  counterfile = fopen(filename, "r");
3333  if (counterfile) {
3334  if(fgets(readbuf, sizeof(readbuf), counterfile)) {
3335  ast_debug(3, "Read this string from counter file: %s\n", readbuf);
3336  old = counter = atoi(readbuf);
3337  }
3338  fclose(counterfile);
3339  }
3340  }
3341  switch (operand) {
3342  case 0: /* Read only */
3343  ast_unlock_path(directory);
3344  ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter);
3345  return counter;
3346  break;
3347  case 1: /* Set new value */
3348  counter = value;
3349  break;
3350  case 2: /* Change value */
3351  counter += value;
3352  if (counter < 0) /* Don't allow counters to fall below zero */
3353  counter = 0;
3354  break;
3355  }
3356 
3357  /* Now, write the new value to the file */
3358  counterfile = fopen(filename, "w");
3359  if (!counterfile) {
3360  ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno));
3361  ast_unlock_path(directory);
3362  return -1; /* Could not open file for writing */
3363  }
3364  fprintf(counterfile, "%d\n\n", counter);
3365  fclose(counterfile);
3366  ast_unlock_path(directory);
3367  ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter);
3368  return counter;
3369 }
int ast_unlock_path(const char *path)
Unlock a path.
Definition: main/app.c:2473
int value
Definition: syslog.c:37
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
int errno
static int vm_lock_path(const char *path)
lock directory
Definition: app_minivm.c:3302

◆ apply_general_options()

static int apply_general_options ( struct ast_variable var)
static

Apply general configuration options.

Definition at line 2806 of file app_minivm.c.

References ast_config_AST_LOG_DIR, ast_copy_string(), ast_log, ast_set2_flag, ast_strlen_zero, ast_true(), error(), LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by load_config().

2807 {
2808  int error = 0;
2809 
2810  while (var) {
2811  /* Mail command */
2812  if (!strcmp(var->name, "mailcmd")) {
2813  ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */
2814  } else if (!strcmp(var->name, "maxgreet")) {
2815  global_maxgreet = atoi(var->value);
2816  } else if (!strcmp(var->name, "maxsilence")) {
2817  global_maxsilence = atoi(var->value);
2818  if (global_maxsilence > 0)
2819  global_maxsilence *= 1000;
2820  } else if (!strcmp(var->name, "logfile")) {
2821  if (!ast_strlen_zero(var->value) ) {
2822  if(*(var->value) == '/')
2824  else
2825  snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value);
2826  }
2827  } else if (!strcmp(var->name, "externnotify")) {
2828  /* External voicemail notify application */
2830  } else if (!strcmp(var->name, "silencetreshold")) {
2831  /* Silence treshold */
2832  global_silencethreshold = atoi(var->value);
2833  } else if (!strcmp(var->name, "maxmessage")) {
2834  int x;
2835  if (sscanf(var->value, "%30d", &x) == 1) {
2836  global_vmmaxmessage = x;
2837  } else {
2838  error ++;
2839  ast_log(LOG_WARNING, "Invalid max message time length\n");
2840  }
2841  } else if (!strcmp(var->name, "minmessage")) {
2842  int x;
2843  if (sscanf(var->value, "%30d", &x) == 1) {
2844  global_vmminmessage = x;
2846  ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
2847  } else {
2848  error ++;
2849  ast_log(LOG_WARNING, "Invalid min message time length\n");
2850  }
2851  } else if (!strcmp(var->name, "format")) {
2853  } else if (!strcmp(var->name, "review")) {
2855  } else if (!strcmp(var->name, "operator")) {
2857  }
2858  var = var->next;
2859  }
2860  return error;
2861 }
struct ast_variable * next
#define MVM_REVIEW
Definition: app_minivm.c:525
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
static int global_vmminmessage
Definition: app_minivm.c:694
#define LOG_WARNING
Definition: logger.h:274
static int global_vmmaxmessage
Definition: app_minivm.c:695
static int global_silencethreshold
Definition: app_minivm.c:698
static char global_mailcmd[160]
Definition: app_minivm.c:699
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define MVM_OPERATOR
Definition: app_minivm.c:526
static int global_maxgreet
Definition: app_minivm.c:697
static int global_maxsilence
Definition: app_minivm.c:696
static char default_vmformat[80]
Definition: app_minivm.c:702
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
const char * ast_config_AST_LOG_DIR
Definition: options.c:159
static char global_externnotify[160]
Definition: app_minivm.c:700
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int error(const char *format,...)
Definition: utils/frame.c:999
static struct ast_flags globalflags
Definition: app_minivm.c:704
static char global_logfile[PATH_MAX]
Definition: app_minivm.c:701

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 3599 of file app_minivm.c.

◆ ast_str_encode_mime()

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

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

Referenced by sendmail().

1174 {
1175  struct ast_str *tmp = ast_str_alloca(80);
1176  int first_section = 1;
1177 
1178  ast_str_reset(*end);
1179  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
1180  for (; *start; start++) {
1181  int need_encoding = 0;
1182  if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
1183  need_encoding = 1;
1184  }
1185  if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) ||
1186  (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) ||
1187  (!first_section && need_encoding && ast_str_strlen(tmp) > 70) ||
1188  (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) {
1189  /* Start new line */
1190  ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp));
1191  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
1192  first_section = 0;
1193  }
1194  if (need_encoding && *start == ' ') {
1195  ast_str_append(&tmp, -1, "_");
1196  } else if (need_encoding) {
1197  ast_str_append(&tmp, -1, "=%hhX", *start);
1198  } else {
1199  ast_str_append(&tmp, -1, "%c", *start);
1200  }
1201  }
1202  ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : "");
1203  return ast_str_buffer(*end);
1204 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
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:1091
#define ast_str_alloca(init_len)
Definition: strings.h:800
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:1065
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
charset
Definition: chan_unistim.c:336
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:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688

◆ ast_str_quote()

static const char* ast_str_quote ( struct ast_str **  buf,
ssize_t  maxlen,
const char *  from 
)
static

Definition at line 1214 of file app_minivm.c.

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

Referenced by sendmail().

1215 {
1216  const char *ptr;
1217 
1218  /* We're only ever passing 0 to maxlen, so short output isn't possible */
1219  ast_str_set(buf, maxlen, "\"");
1220  for (ptr = from; *ptr; ptr++) {
1221  if (*ptr == '"' || *ptr == '\\') {
1222  ast_str_append(buf, maxlen, "\\%c", *ptr);
1223  } else {
1224  ast_str_append(buf, maxlen, "%c", *ptr);
1225  }
1226  }
1227  ast_str_append(buf, maxlen, "\"");
1228 
1229  return ast_str_buffer(*buf);
1230 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
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:1091
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:1065

◆ b64_inbuf()

static int b64_inbuf ( struct b64_baseio bio,
FILE *  fi 
)
static

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

852 {
853  int l;
854 
855  if (bio->ateof)
856  return 0;
857 
858  if ((l = fread(bio->iobuf, 1, B64_BASEMAXINLINE, fi)) != B64_BASEMAXINLINE) {
859  bio->ateof = 1;
860  if (l == 0) {
861  /* Assume EOF */
862  return 0;
863  }
864  }
865 
866  bio->iolen = l;
867  bio->iocp = 0;
868 
869  return 1;
870 }
#define B64_BASEMAXINLINE
Definition: app_minivm.c:538
unsigned char iobuf[B64_BASEMAXINLINE]
Definition: app_minivm.c:661

◆ b64_inchar()

static int b64_inchar ( struct b64_baseio bio,
FILE *  fi 
)
static

Definition at line 874 of file app_minivm.c.

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

Referenced by base_encode().

875 {
876  if (bio->iocp >= bio->iolen) {
877  if (!b64_inbuf(bio, fi))
878  return EOF;
879  }
880 
881  return bio->iobuf[bio->iocp++];
882 }
unsigned char iobuf[B64_BASEMAXINLINE]
Definition: app_minivm.c:661
static int b64_inbuf(struct b64_baseio *bio, FILE *fi)
Definition: app_minivm.c:851

◆ b64_ochar()

static int b64_ochar ( struct b64_baseio bio,
int  c,
FILE *  so 
)
static

Definition at line 886 of file app_minivm.c.

References B64_BASELINELEN, EOL, and b64_baseio::linelength.

Referenced by base_encode().

887 {
888  if (bio->linelength >= B64_BASELINELEN) {
889  if (fputs(EOL,so) == EOF)
890  return -1;
891 
892  bio->linelength= 0;
893  }
894 
895  if (putc(((unsigned char) c), so) == EOF)
896  return -1;
897 
898  bio->linelength++;
899 
900  return 1;
901 }
static struct test_val c
#define B64_BASELINELEN
Definition: app_minivm.c:539
int linelength
Definition: app_minivm.c:659
#define EOL
Definition: app_minivm.c:540

◆ base_encode()

static int base_encode ( char *  filename,
FILE *  so 
)
static

Definition at line 905 of file app_minivm.c.

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

Referenced by sendmail().

906 {
907  unsigned char dtable[B64_BASEMAXINLINE];
908  int i,hiteof= 0;
909  FILE *fi;
910  struct b64_baseio bio;
911 
912  memset(&bio, 0, sizeof(bio));
913  bio.iocp = B64_BASEMAXINLINE;
914 
915  if (!(fi = fopen(filename, "rb"))) {
916  ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
917  return -1;
918  }
919 
920  for (i= 0; i<9; i++) {
921  dtable[i]= 'A'+i;
922  dtable[i+9]= 'J'+i;
923  dtable[26+i]= 'a'+i;
924  dtable[26+i+9]= 'j'+i;
925  }
926  for (i= 0; i < 8; i++) {
927  dtable[i+18]= 'S'+i;
928  dtable[26+i+18]= 's'+i;
929  }
930  for (i= 0; i < 10; i++) {
931  dtable[52+i]= '0'+i;
932  }
933  dtable[62]= '+';
934  dtable[63]= '/';
935 
936  while (!hiteof){
937  unsigned char igroup[3], ogroup[4];
938  int c,n;
939 
940  igroup[0]= igroup[1]= igroup[2]= 0;
941 
942  for (n= 0; n < 3; n++) {
943  if ((c = b64_inchar(&bio, fi)) == EOF) {
944  hiteof= 1;
945  break;
946  }
947  igroup[n]= (unsigned char)c;
948  }
949 
950  if (n> 0) {
951  ogroup[0]= dtable[igroup[0]>>2];
952  ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)];
953  ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)];
954  ogroup[3]= dtable[igroup[2]&0x3F];
955 
956  if (n<3) {
957  ogroup[3]= '=';
958 
959  if (n<2)
960  ogroup[2]= '=';
961  }
962 
963  for (i= 0;i<4;i++)
964  b64_ochar(&bio, ogroup[i], so);
965  }
966  }
967 
968  /* Put end of line - line feed */
969  if (fputs(EOL, so) == EOF)
970  return 0;
971 
972  fclose(fi);
973 
974  return 1;
975 }
static int b64_inchar(struct b64_baseio *bio, FILE *fi)
Definition: app_minivm.c:874
#define LOG_WARNING
Definition: logger.h:274
static struct test_val c
static int b64_ochar(struct b64_baseio *bio, int c, FILE *so)
Definition: app_minivm.c:886
#define ast_log
Definition: astobj2.c:42
#define B64_BASEMAXINLINE
Definition: app_minivm.c:538
int errno
Structure for base64 encoding.
Definition: app_minivm.c:656
#define EOL
Definition: app_minivm.c:540

◆ check_dirpath()

static int check_dirpath ( char *  dest,
int  len,
char *  domain,
char *  username,
char *  folder 
)
static

Definition at line 1538 of file app_minivm.c.

References FALSE, make_dir(), and TRUE.

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

1539 {
1540  struct stat filestat;
1541  make_dir(dest, len, domain, username, folder ? folder : "");
1542  if (stat(dest, &filestat)== -1)
1543  return FALSE;
1544  else
1545  return TRUE;
1546 }
#define FALSE
Definition: app_minivm.c:521
Domain data structure.
Definition: sip.h:888
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define TRUE
Definition: app_minivm.c:518
static int make_dir(char *dest, int len, const char *domain, const char *username, const char *folder)
Definition: app_minivm.c:1524

◆ check_mime()

static int check_mime ( const char *  str)
static

Definition at line 1144 of file app_minivm.c.

References str.

Referenced by sendmail().

1145 {
1146  for (; *str; str++) {
1147  if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
1148  return 1;
1149  }
1150  }
1151  return 0;
1152 }
const char * str
Definition: app_jack.c:147

◆ complete_minivm_show_users()

static char* complete_minivm_show_users ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 3045 of file app_minivm.c.

References AST_LIST_TRAVERSE, ast_strdup, minivm_account::domain, minivm_account::list, and NULL.

Referenced by handle_minivm_show_users().

3046 {
3047  int which = 0;
3048  int wordlen;
3049  struct minivm_account *vmu;
3050  const char *domain = "";
3051 
3052  /* 0 - minivm; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */
3053  if (pos > 4)
3054  return NULL;
3055  wordlen = strlen(word);
3057  if (!strncasecmp(word, vmu->domain, wordlen)) {
3058  if (domain && strcmp(domain, vmu->domain) && ++which > state)
3059  return ast_strdup(vmu->domain);
3060  /* ignore repeated domains ? */
3061  domain = vmu->domain;
3062  }
3063  }
3064  return NULL;
3065 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
struct minivm_account::@54 list
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
short word

◆ create_dirpath()

static int create_dirpath ( char *  dest,
int  len,
char *  domain,
char *  username,
char *  folder 
)
static

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

1558 {
1559  int res;
1560  make_dir(dest, len, domain, username, folder);
1561  if ((res = ast_mkdir(dest, 0777))) {
1562  ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res));
1563  return -1;
1564  }
1565  ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest);
1566  return 0;
1567 }
#define LOG_WARNING
Definition: logger.h:274
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
Domain data structure.
Definition: sip.h:888
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int make_dir(char *dest, int len, const char *domain, const char *username, const char *folder)
Definition: app_minivm.c:1524
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: main/utils.c:2231

◆ create_vmaccount()

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 2594 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_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, minivm_account::list, 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().

2595 {
2596  struct minivm_account *vmu;
2597  char *domain;
2598  char *username;
2599  char accbuf[BUFSIZ];
2600 
2601  ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name);
2602 
2603  ast_copy_string(accbuf, name, sizeof(accbuf));
2604  username = accbuf;
2605  domain = strchr(accbuf, '@');
2606  if (domain) {
2607  *domain = '\0';
2608  domain++;
2609  }
2610  if (ast_strlen_zero(domain)) {
2611  ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name);
2612  return 0;
2613  }
2614 
2615  ast_debug(3, "Creating static account for user %s domain %s\n", username, domain);
2616 
2617  /* Allocate user account */
2618  vmu = ast_calloc(1, sizeof(*vmu));
2619  if (!vmu)
2620  return 0;
2621 
2622  ast_copy_string(vmu->domain, domain, sizeof(vmu->domain));
2623  ast_copy_string(vmu->username, username, sizeof(vmu->username));
2624 
2625  populate_defaults(vmu);
2626 
2627  ast_debug(3, "...Configuring account %s\n", name);
2628 
2629  while (var) {
2630  ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name);
2631  if (!strcasecmp(var->name, "serveremail")) {
2632  ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail));
2633  } else if (!strcasecmp(var->name, "email")) {
2634  ast_copy_string(vmu->email, var->value, sizeof(vmu->email));
2635  } else if (!strcasecmp(var->name, "accountcode")) {
2636  ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode));
2637  } else if (!strcasecmp(var->name, "pincode")) {
2638  ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode));
2639  } else if (!strcasecmp(var->name, "domain")) {
2640  ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain));
2641  } else if (!strcasecmp(var->name, "language")) {
2642  ast_copy_string(vmu->language, var->value, sizeof(vmu->language));
2643  } else if (!strcasecmp(var->name, "timezone")) {
2644  ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag));
2645  } else if (!strcasecmp(var->name, "externnotify")) {
2646  ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify));
2647  } else if (!strcasecmp(var->name, "etemplate")) {
2648  ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate));
2649  } else if (!strcasecmp(var->name, "ptemplate")) {
2650  ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate));
2651  } else if (!strcasecmp(var->name, "fullname")) {
2652  ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname));
2653  } else if (!strcasecmp(var->name, "setvar")) {
2654  char *varval;
2655  char varname[strlen(var->value) + 1];
2656  struct ast_variable *tmpvar;
2657 
2658  strcpy(varname, var->value); /* safe */
2659  if ((varval = strchr(varname, '='))) {
2660  *varval = '\0';
2661  varval++;
2662  if ((tmpvar = ast_variable_new(varname, varval, ""))) {
2663  tmpvar->next = vmu->chanvars;
2664  vmu->chanvars = tmpvar;
2665  }
2666  }
2667  } else if (!strcasecmp(var->name, "pager")) {
2668  ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager));
2669  } else if (!strcasecmp(var->name, "volgain")) {
2670  sscanf(var->value, "%30lf", &vmu->volgain);
2671  } else {
2672  ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name);
2673  }
2674  var = var->next;
2675  }
2676  ast_debug(3, "...Linking account %s\n", name);
2677 
2681 
2683 
2684  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)" : "");
2685  return 0;
2686 }
struct ast_variable * next
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char etemplate[80]
Definition: app_minivm.c:616
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char language[MAX_LANGUAGE]
Definition: app_minivm.c:611
Structure for variables, used for configurations and for channel variables.
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: app_minivm.c:608
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
int voicemailaccounts
Definition: app_minivm.c:677
char pincode[10]
Definition: app_minivm.c:604
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:687
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
char email[80]
Definition: app_minivm.c:606
char zonetag[80]
Definition: app_minivm.c:612
#define ast_variable_new(name, value, filename)
static void populate_defaults(struct minivm_account *vmu)
Definition: app_minivm.c:1031
double volgain
Definition: app_minivm.c:620
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct ast_variable * chanvars
Definition: app_minivm.c:619
static const char name[]
Definition: cdr_mysql.c:74
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
char fullname[120]
Definition: app_minivm.c:605
char ptemplate[80]
Definition: app_minivm.c:617
char pager[80]
Definition: app_minivm.c:607
char externnotify[160]
Definition: app_minivm.c:610
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char serveremail[80]
Definition: app_minivm.c:609

◆ find_account()

static struct minivm_account* find_account ( const char *  domain,
const char *  username,
int  createtemp 
)
static

Definition at line 1067 of file app_minivm.c.

References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_set2_flag, ast_strlen_zero, minivm_account::domain, find_user_realtime(), minivm_account::list, LOG_NOTICE, MVM_ALLOCED, mvm_user_alloc(), NULL, 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().

1068 {
1069  struct minivm_account *vmu = NULL, *cur;
1070 
1071 
1073  ast_log(LOG_NOTICE, "No username or domain? \n");
1074  return NULL;
1075  }
1076  ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain);
1077 
1080  /* Is this the voicemail account we're looking for? */
1081  if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username))
1082  break;
1083  }
1085 
1086  if (cur) {
1087  ast_debug(3, "Found account for %s@%s\n", username, domain);
1088  vmu = cur;
1089 
1090  } else
1092 
1093  if (createtemp && !vmu) {
1094  /* Create a temporary user, send e-mail and be gone */
1095  vmu = mvm_user_alloc();
1097  if (vmu) {
1098  ast_copy_string(vmu->username, username, sizeof(vmu->username));
1099  ast_copy_string(vmu->domain, domain, sizeof(vmu->domain));
1100  ast_debug(1, "Created temporary account\n");
1101  }
1102 
1103  }
1104  return vmu;
1105 }
#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:1111
#define MVM_ALLOCED
Definition: app_minivm.c:531
#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:601
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
struct minivm_account::@54 list
static struct minivm_account * mvm_user_alloc(void)
Definition: app_minivm.c:1040
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
char domain[MAXHOSTNAMELEN]
Definition: sip.h:889

◆ find_user_realtime()

static struct minivm_account * find_user_realtime ( const char *  domain,
const char *  username 
)
static

Definition at line 1111 of file app_minivm.c.

References ast_copy_string(), ast_free, ast_load_realtime(), ast_variables_destroy(), create_vmaccount(), MAXHOSTNAMELEN, mvm_user_alloc(), name, NULL, populate_defaults(), retval, SENTINEL, TRUE, minivm_account::username, and var.

Referenced by find_account().

1112 {
1113  struct ast_variable *var;
1114  struct minivm_account *retval;
1115  char name[MAXHOSTNAMELEN];
1116 
1117  retval = mvm_user_alloc();
1118  if (!retval)
1119  return NULL;
1120 
1121  if (username)
1122  ast_copy_string(retval->username, username, sizeof(retval->username));
1123 
1124  populate_defaults(retval);
1125  var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL);
1126 
1127  if (!var) {
1128  ast_free(retval);
1129  return NULL;
1130  }
1131 
1132  snprintf(name, sizeof(name), "%s@%s", username, domain);
1133  create_vmaccount(name, var, TRUE);
1134 
1135  ast_variables_destroy(var);
1136  return retval;
1137 }
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Definition: main/config.c:3339
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:2594
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
#define MAXHOSTNAMELEN
Definition: network.h:69
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define SENTINEL
Definition: compiler.h:87
static void populate_defaults(struct minivm_account *vmu)
Definition: app_minivm.c:1031
static struct minivm_account * mvm_user_alloc(void)
Definition: app_minivm.c:1040
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
static ENTRY retval
Definition: hsearch.c:50

◆ free_user()

static void free_user ( struct minivm_account vmu)
static

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

990 {
991  if (vmu->chanvars)
993  ast_free(vmu);
994 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
struct ast_variable * chanvars
Definition: app_minivm.c:619
#define ast_free(a)
Definition: astmm.h:182

◆ free_zone()

static void free_zone ( struct minivm_zone z)
static

Free Mini Voicemail timezone.

Definition at line 2689 of file app_minivm.c.

References ast_free.

Referenced by timezone_destroy_list().

2690 {
2691  ast_free(z);
2692 }
#define ast_free(a)
Definition: astmm.h:182

◆ get_date()

static int get_date ( char *  s,
int  len 
)
static

Definition at line 977 of file app_minivm.c.

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

Referenced by leave_voicemail().

978 {
979  struct ast_tm tm;
980  struct timeval now = ast_tvnow();
981 
982  ast_localtime(&now, &tm, NULL);
983  return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm);
984 }
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:1739
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
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:2524

◆ handle_minivm_list_templates()

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

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

3005 {
3006  struct minivm_template *this;
3007 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n"
3008  int count = 0;
3009 
3010  switch (cmd) {
3011  case CLI_INIT:
3012  e->command = "minivm list templates";
3013  e->usage =
3014  "Usage: minivm list templates\n"
3015  " Lists message templates for e-mail, paging and IM\n";
3016  return NULL;
3017  case CLI_GENERATE:
3018  return NULL;
3019  }
3020 
3021  if (a->argc > 3)
3022  return CLI_SHOWUSAGE;
3023 
3026  ast_cli(a->fd, "There are no message templates defined\n");
3028  return CLI_FAILURE;
3029  }
3030  ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject");
3031  ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------");
3033  ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name,
3034  S_OR(this->charset, "-"),
3035  S_OR(this->locale, "-"),
3036  this->attachment ? "Yes" : "No",
3037  S_OR(this->subject, "-"));
3038  count++;
3039  }
3041  ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count);
3042  return CLI_SUCCESS;
3043 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct minivm_template::@55 list
const int argc
Definition: cli.h:160
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:152
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
static char locale[20]
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char subject[100]
Definition: app_minivm.c:638
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
#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:46
char * command
Definition: cli.h:186
charset
Definition: chan_unistim.c:336
const char * usage
Definition: cli.h:177
The list of e-mail templates.
Definition: app_minivm.c:647
#define CLI_SUCCESS
Definition: cli.h:44
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
#define HVLT_OUTPUT_FORMAT

◆ handle_minivm_reload()

static char * handle_minivm_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Reload cofiguration.

Definition at line 3551 of file app_minivm.c.

References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, reload(), and ast_cli_entry::usage.

3552 {
3553 
3554  switch (cmd) {
3555  case CLI_INIT:
3556  e->command = "minivm reload";
3557  e->usage =
3558  "Usage: minivm reload\n"
3559  " Reload mini-voicemail configuration and reset statistics\n";
3560  return NULL;
3561  case CLI_GENERATE:
3562  return NULL;
3563  }
3564 
3565  reload();
3566  ast_cli(a->fd, "\n-- Mini voicemail re-configured \n");
3567  return CLI_SUCCESS;
3568 }
static int reload(void)
Reload mini voicemail module.
Definition: app_minivm.c:3545
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_minivm_show_settings()

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

References ast_cli(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MVM_OPERATOR, MVM_REVIEW, NULL, and ast_cli_entry::usage.

3154 {
3155  switch (cmd) {
3156  case CLI_INIT:
3157  e->command = "minivm show settings";
3158  e->usage =
3159  "Usage: minivm show settings\n"
3160  " Display Mini-Voicemail general settings\n";
3161  return NULL;
3162  case CLI_GENERATE:
3163  return NULL;
3164  }
3165 
3166  ast_cli(a->fd, "* Mini-Voicemail general settings\n");
3167  ast_cli(a->fd, " -------------------------------\n");
3168  ast_cli(a->fd, "\n");
3169  ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd);
3170  ast_cli(a->fd, " Max silence: %d\n", global_maxsilence);
3171  ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold);
3172  ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage);
3173  ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage);
3174  ast_cli(a->fd, " Default format: %s\n", default_vmformat);
3175  ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify);
3176  ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>");
3177  ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No");
3178  ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No");
3179 
3180  ast_cli(a->fd, "\n");
3181  return CLI_SUCCESS;
3182 }
#define MVM_REVIEW
Definition: app_minivm.c:525
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int global_vmminmessage
Definition: app_minivm.c:694
Definition: cli.h:152
static int global_vmmaxmessage
Definition: app_minivm.c:695
static int global_silencethreshold
Definition: app_minivm.c:698
static char global_mailcmd[160]
Definition: app_minivm.c:699
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define MVM_OPERATOR
Definition: app_minivm.c:526
const int fd
Definition: cli.h:159
static int global_maxsilence
Definition: app_minivm.c:696
static char default_vmformat[80]
Definition: app_minivm.c:702
char * command
Definition: cli.h:186
static char global_externnotify[160]
Definition: app_minivm.c:700
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
static struct ast_flags globalflags
Definition: app_minivm.c:704
static char global_logfile[PATH_MAX]
Definition: app_minivm.c:701

◆ handle_minivm_show_stats()

static char* handle_minivm_show_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Show stats.

Definition at line 3185 of file app_minivm.c.

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

3186 {
3187  struct ast_tm timebuf;
3188  char buf[BUFSIZ];
3189 
3190  switch (cmd) {
3191 
3192  case CLI_INIT:
3193  e->command = "minivm show stats";
3194  e->usage =
3195  "Usage: minivm show stats\n"
3196  " Display Mini-Voicemail counters\n";
3197  return NULL;
3198  case CLI_GENERATE:
3199  return NULL;
3200  }
3201 
3202  ast_cli(a->fd, "* Mini-Voicemail statistics\n");
3203  ast_cli(a->fd, " -------------------------\n");
3204  ast_cli(a->fd, "\n");
3205  ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts);
3206  ast_cli(a->fd, " Templates: %5d\n", global_stats.templates);
3207  ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones);
3208  if (global_stats.receivedmessages == 0) {
3209  ast_cli(a->fd, " Received messages since last reset: <none>\n");
3210  } else {
3211  ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages);
3213  ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf);
3214  ast_cli(a->fd, " Last received voicemail: %s\n", buf);
3215  }
3216  ast_localtime(&global_stats.reset, &timebuf, NULL);
3217  ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf);
3218  ast_cli(a->fd, " Last reset: %s\n", buf);
3219 
3220  ast_cli(a->fd, "\n");
3221  return CLI_SUCCESS;
3222 }
struct timeval reset
Definition: app_minivm.c:681
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
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:1739
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct timeval lastreceived
Definition: app_minivm.c:683
int voicemailaccounts
Definition: app_minivm.c:677
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:687
const int fd
Definition: cli.h:159
int receivedmessages
Definition: app_minivm.c:682
char * command
Definition: cli.h:186
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:2524
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ handle_minivm_show_users()

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

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

3069 {
3070  struct minivm_account *vmu;
3071 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n"
3072  int count = 0;
3073 
3074  switch (cmd) {
3075  case CLI_INIT:
3076  e->command = "minivm list accounts [for]";
3077  e->usage =
3078  "Usage: minivm list accounts [for <domain>]\n"
3079  " Lists all mailboxes currently set up\n";
3080  return NULL;
3081  case CLI_GENERATE:
3082  return complete_minivm_show_users(a->line, a->word, a->pos, a->n);
3083  }
3084 
3085  if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
3086  return CLI_SHOWUSAGE;
3087  if ((a->argc == 5) && strcmp(a->argv[3],"for"))
3088  return CLI_SHOWUSAGE;
3089 
3092  ast_cli(a->fd, "There are no voicemail users currently defined\n");
3094  return CLI_FAILURE;
3095  }
3096  ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name");
3097  ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------");
3099  char tmp[256] = "";
3100  if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) {
3101  count++;
3102  snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain);
3103  ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, S_OR(vmu->etemplate, "-"),
3104  S_OR(vmu->ptemplate, "-"),
3105  S_OR(vmu->zonetag, "-"),
3106  S_OR(vmu->attachfmt, "-"),
3107  vmu->fullname);
3108  }
3109  }
3111  ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count);
3112  return CLI_SUCCESS;
3113 }
char attachfmt[80]
Definition: app_minivm.c:615
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char etemplate[80]
Definition: app_minivm.c:616
#define HMSU_OUTPUT_FORMAT
const int argc
Definition: cli.h:160
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static int tmp()
Definition: bt_open.c:389
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
Definition: cli.h:152
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
const char * line
Definition: cli.h:162
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
struct minivm_account::@54 list
char zonetag[80]
Definition: app_minivm.c:612
const char *const * argv
Definition: cli.h:161
static char * complete_minivm_show_users(const char *line, const char *word, int pos, int state)
Definition: app_minivm.c:3045
#define CLI_SHOWUSAGE
Definition: cli.h:45
#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:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
char fullname[120]
Definition: app_minivm.c:605
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
char ptemplate[80]
Definition: app_minivm.c:617
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const int pos
Definition: cli.h:164

◆ handle_minivm_show_zones()

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

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

3117 {
3118  struct minivm_zone *zone;
3119 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
3120  char *res = CLI_SUCCESS;
3121 
3122  switch (cmd) {
3123  case CLI_INIT:
3124  e->command = "minivm list zones";
3125  e->usage =
3126  "Usage: minivm list zones\n"
3127  " Lists zone message formats\n";
3128  return NULL;
3129  case CLI_GENERATE:
3130  return NULL;
3131  }
3132 
3133  if (a->argc != e->args)
3134  return CLI_SHOWUSAGE;
3135 
3137  if (!AST_LIST_EMPTY(&minivm_zones)) {
3138  ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format");
3139  ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------");
3141  ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format);
3142  }
3143  } else {
3144  ast_cli(a->fd, "There are no voicemail zones currently defined\n");
3145  res = CLI_FAILURE;
3146  }
3148 
3149  return res;
3150 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char name[80]
Definition: app_minivm.c:666
const int argc
Definition: cli.h:160
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:152
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
struct minivm_zone::@56 list
char timezone[80]
Definition: app_minivm.c:667
#define HMSZ_OUTPUT_FORMAT
#define CLI_SHOWUSAGE
Definition: cli.h:45
char msg_format[BUFSIZ]
Definition: app_minivm.c:668
Voicemail time zones.
Definition: app_minivm.c:665
#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:46
char * command
Definition: cli.h:186
The list of e-mail time zones.
Definition: app_minivm.c:673
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44

◆ invent_message()

static int invent_message ( struct ast_channel chan,
char *  domain,
char *  username,
int  busy,
char *  ecodes 
)
static

Definition at line 1573 of file app_minivm.c.

References ast_channel_language(), ast_debug, ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), FALSE, MVM_SPOOL_DIR, NULL, PATH_MAX, and minivm_account::username.

Referenced by minivm_greet_exec().

1574 {
1575  int res;
1576  char fn[PATH_MAX];
1577 
1578  ast_debug(2, "Still preparing to play message ...\n");
1579 
1580  snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username);
1581 
1582  if (ast_fileexists(fn, NULL, NULL) > 0) {
1583  res = ast_streamfile(chan, fn, ast_channel_language(chan));
1584  if (res)
1585  return -1;
1586  res = ast_waitstream(chan, ecodes);
1587  if (res)
1588  return res;
1589  } else {
1590  int numericusername = 1;
1591  char *i = username;
1592 
1593  ast_debug(2, "No personal prompts. Using default prompt set for language\n");
1594 
1595  while (*i) {
1596  ast_debug(2, "Numeric? Checking %c\n", *i);
1597  if (!isdigit(*i)) {
1598  numericusername = FALSE;
1599  break;
1600  }
1601  i++;
1602  }
1603 
1604  if (numericusername) {
1605  if (ast_streamfile(chan, "vm-theperson", ast_channel_language(chan)))
1606  return -1;
1607  if ((res = ast_waitstream(chan, ecodes)))
1608  return res;
1609 
1610  res = ast_say_digit_str(chan, username, ecodes, ast_channel_language(chan));
1611  if (res)
1612  return res;
1613  } else {
1614  if (ast_streamfile(chan, "vm-theextensionis", ast_channel_language(chan)))
1615  return -1;
1616  if ((res = ast_waitstream(chan, ecodes)))
1617  return res;
1618  }
1619  }
1620 
1621  res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", ast_channel_language(chan));
1622  if (res)
1623  return -1;
1624  res = ast_waitstream(chan, ecodes);
1625  return res;
1626 }
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define FALSE
Definition: app_minivm.c:521
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:8355
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
const char * ast_channel_language(const struct ast_channel *chan)
#define PATH_MAX
Definition: asterisk.h:40
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:558

◆ leave_voicemail()

static int leave_voicemail ( struct ast_channel chan,
char *  username,
struct leave_vm_options options 
)
static

Definition at line 1912 of file app_minivm.c.

References minivm_account::accountcode, ast_callerid_merge(), ast_channel_caller(), ast_channel_context(), ast_channel_exten(), ast_channel_language(), ast_channel_macrocontext(), ast_channel_name(), ast_channel_priority(), ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_localtime(), ast_log, ast_mutex_lock, ast_mutex_unlock, ast_streamfile(), ast_strftime(), ast_strlen_zero, ast_test_flag, ast_tvnow(), ast_verb, ast_waitstream(), minivm_account::attachfmt, check_dirpath(), create_dirpath(), minivm_account::domain, errno, find_account(), free_user(), get_date(), global_stats, minivm_stats::lastreceived, LOG_ERROR, LOG_WARNING, minivmloglock, MVM_ALLOCED, name, NULL, PATH_MAX, pbx_builtin_setvar_helper(), play_record_review(), minivm_stats::receivedmessages, leave_vm_options::record_gain, S_COR, tmp(), and TRUE.

Referenced by minivm_record_exec().

1913 {
1914  char tmptxtfile[PATH_MAX];
1915  char callerid[256];
1916  FILE *txt;
1917  int res = 0, txtdes;
1918  int duration = 0;
1919  int sound_duration = 0;
1920  char date[256];
1921  char tmpdir[PATH_MAX];
1922  char ext_context[256] = "";
1923  char fmt[80];
1924  char *domain;
1925  char tmp[256] = "";
1926  struct minivm_account *vmu;
1927  int userdir;
1928 
1929  ast_copy_string(tmp, username, sizeof(tmp));
1930  username = tmp;
1931  domain = strchr(tmp, '@');
1932  if (domain) {
1933  *domain = '\0';
1934  domain++;
1935  }
1936 
1937  if (!(vmu = find_account(domain, username, TRUE))) {
1938  /* We could not find user, let's exit */
1939  ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain);
1940  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1941  return 0;
1942  }
1943 
1944  /* Setup pre-file if appropriate */
1945  if (strcmp(vmu->domain, "localhost"))
1946  snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain);
1947  else
1948  ast_copy_string(ext_context, vmu->domain, sizeof(ext_context));
1949 
1950  /* The meat of recording the message... All the announcements and beeps have been played*/
1951  if (ast_strlen_zero(vmu->attachfmt))
1952  ast_copy_string(fmt, default_vmformat, sizeof(fmt));
1953  else
1954  ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt));
1955 
1956  if (ast_strlen_zero(fmt)) {
1957  ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat);
1958  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1959  return res;
1960  }
1961 
1962  userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp");
1963 
1964  /* If we have no user directory, use generic temporary directory */
1965  if (!userdir) {
1966  create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", "");
1967  ast_debug(3, "Creating temporary directory %s\n", tmpdir);
1968  }
1969 
1970 
1971  snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
1972 
1973  /* XXX This file needs to be in temp directory */
1974  txtdes = mkstemp(tmptxtfile);
1975  if (txtdes < 0) {
1976  ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno));
1977  res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan));
1978  if (!res)
1979  res = ast_waitstream(chan, "");
1980  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
1981  return res;
1982  }
1983 
1984  if (res >= 0) {
1985  /* Unless we're *really* silent, try to send the beep */
1986  res = ast_streamfile(chan, "beep", ast_channel_language(chan));
1987  if (!res)
1988  res = ast_waitstream(chan, "");
1989  }
1990 
1991  /* OEJ XXX Maybe this can be turned into a log file? Hmm. */
1992  /* Store information */
1993  ast_debug(2, "Open file for metadata: %s\n", tmptxtfile);
1994 
1995  res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain);
1996 
1997  txt = fdopen(txtdes, "w+");
1998  if (!txt) {
1999  ast_log(LOG_WARNING, "Error opening text file for output\n");
2000  } else {
2001  struct ast_tm tm;
2002  struct timeval now = ast_tvnow();
2003  char timebuf[30];
2004  char logbuf[BUFSIZ];
2005  get_date(date, sizeof(date));
2006  ast_localtime(&now, &tm, NULL);
2007  ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm);
2008 
2009  ast_callerid_merge(callerid, sizeof(callerid),
2010  S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL),
2011  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
2012  "Unknown");
2013  snprintf(logbuf, sizeof(logbuf),
2014  /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */
2015  "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n",
2016  username,
2017  ast_channel_context(chan),
2019  ast_channel_exten(chan),
2020  ast_channel_priority(chan),
2021  ast_channel_name(chan),
2022  callerid,
2023  date,
2024  timebuf,
2025  duration,
2026  duration < global_vmminmessage ? "IGNORED" : "OK",
2027  vmu->accountcode
2028  );
2029  fprintf(txt, "%s", logbuf);
2030  if (minivmlogfile) {
2032  fprintf(minivmlogfile, "%s", logbuf);
2034  }
2035 
2036  if (sound_duration < global_vmminmessage) {
2037  ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, global_vmminmessage);
2038  fclose(txt);
2039  ast_filedelete(tmptxtfile, NULL);
2040  unlink(tmptxtfile);
2041  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
2042  return 0;
2043  }
2044  fclose(txt); /* Close log file */
2045  if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
2046  ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
2047  unlink(tmptxtfile);
2048  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
2049  if(ast_test_flag(vmu, MVM_ALLOCED))
2050  free_user(vmu);
2051  return 0;
2052  }
2053 
2054  /* Set channel variables for the notify application */
2055  pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile);
2056  snprintf(timebuf, sizeof(timebuf), "%d", duration);
2057  pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf);
2058  pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt);
2059 
2060  }
2063 #if 0
2064  /* Go ahead and delete audio files from system, they're not needed any more */
2065  if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
2066  ast_filedelete(tmptxtfile, NULL);
2067  /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */
2068  ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile);
2069  }
2070 #endif
2071 
2072  if (res > 0)
2073  res = 0;
2074 
2075  if(ast_test_flag(vmu, MVM_ALLOCED))
2076  free_user(vmu);
2077 
2078  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS");
2079  return res;
2080 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char attachfmt[80]
Definition: app_minivm.c:615
static int get_date(char *s, int len)
Definition: app_minivm.c:977
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define MVM_ALLOCED
Definition: app_minivm.c:531
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int global_vmminmessage
Definition: app_minivm.c:694
#define LOG_WARNING
Definition: logger.h:274
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:1644
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:989
static int tmp()
Definition: bt_open.c:389
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:1739
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static int global_vmmaxmessage
Definition: app_minivm.c:695
#define ast_mutex_lock(a)
Definition: lock.h:187
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: app_minivm.c:608
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
struct timeval lastreceived
Definition: app_minivm.c:683
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1557
int ast_channel_priority(const struct ast_channel *chan)
#define ast_verb(level,...)
Definition: logger.h:463
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:687
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1538
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1073
#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:85
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
const char * ast_channel_exten(const struct ast_channel *chan)
static FILE * minivmlogfile
Definition: app_minivm.c:692
static char default_vmformat[80]
Definition: app_minivm.c:702
#define LOG_ERROR
Definition: logger.h:285
int errno
int receivedmessages
Definition: app_minivm.c:682
static ast_mutex_t minivmloglock
Definition: app_minivm.c:690
static const char name[]
Definition: cdr_mysql.c:74
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:2524
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...
signed char record_gain
Definition: app_minivm.c:652
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_channel_name(const struct ast_channel *chan)
#define TRUE
Definition: app_minivm.c:518
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
#define PATH_MAX
Definition: asterisk.h:40
const char * ast_channel_macrocontext(const struct ast_channel *chan)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ load_config()

static int load_config ( int  reload)
static

Load minivoicemail configuration.

Definition at line 2864 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(), errno, error(), FALSE, global_stats, LOG_ERROR, LOG_WARNING, message_destroy_list(), message_template_build(), message_template_find(), message_template_parse_emailbody(), minivmlock, MVM_OPERATOR, MVM_REVIEW, name, ast_variable::name, ast_variable::next, NULL, 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().

2865 {
2866  struct ast_config *cfg;
2867  struct ast_variable *var;
2868  char *cat;
2869  const char *chanvar;
2870  int error = 0;
2871  struct minivm_template *template;
2872  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2873 
2874  cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags);
2875  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2876  return 0;
2877  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2878  ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
2879  return 0;
2880  }
2881 
2883 
2884  /* Destroy lists to reconfigure */
2885  message_destroy_list(); /* Destroy list of voicemail message templates */
2886  timezone_destroy_list(); /* Destroy list of timezones */
2887  vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */
2888  ast_debug(2, "Destroyed memory objects...\n");
2889 
2890  /* First, set some default settings */
2891  global_externnotify[0] = '\0';
2892  global_logfile[0] = '\0';
2893  global_vmmaxmessage = 2000;
2894  global_maxgreet = 2000;
2895  global_vmminmessage = 0;
2896  strcpy(global_mailcmd, SENDMAIL);
2897  global_maxsilence = 0;
2902  /* Reset statistics */
2903  memset(&global_stats, 0, sizeof(global_stats));
2905 
2907 
2908  /* Make sure we could load configuration file */
2909  if (!cfg) {
2910  ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n");
2912  return 0;
2913  }
2914 
2915  ast_debug(2, "Loaded configuration file, now parsing\n");
2916 
2917  /* General settings */
2918 
2919  cat = ast_category_browse(cfg, NULL);
2920  while (cat) {
2921  ast_debug(3, "Found configuration section [%s]\n", cat);
2922  if (!strcasecmp(cat, "general")) {
2923  /* Nothing right now */
2924  error += apply_general_options(ast_variable_browse(cfg, cat));
2925  } else if (!strncasecmp(cat, "template-", 9)) {
2926  /* Template */
2927  char *name = cat + 9;
2928 
2929  /* Now build and link template to list */
2930  error += message_template_build(name, ast_variable_browse(cfg, cat));
2931  } else {
2932  var = ast_variable_browse(cfg, cat);
2933  if (!strcasecmp(cat, "zonemessages")) {
2934  /* Timezones in this context */
2935  while (var) {
2936  timezone_add(var->name, var->value);
2937  var = var->next;
2938  }
2939  } else {
2940  /* Create mailbox from this */
2941  error += create_vmaccount(cat, var, FALSE);
2942  }
2943  }
2944  /* Find next section in configuration file */
2945  cat = ast_category_browse(cfg, cat);
2946  }
2947 
2948  /* Configure the default email template */
2949  message_template_build("email-default", NULL);
2950  template = message_template_find("email-default");
2951 
2952  /* Load date format config for voicemail mail */
2953  if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat")))
2954  ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat));
2955  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring")))
2956  ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress));
2957  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress")))
2958  ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail));
2959  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset")))
2960  ast_copy_string(template->charset, chanvar, sizeof(template->charset));
2961  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject")))
2962  ast_copy_string(template->subject, chanvar, sizeof(template->subject));
2963  if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody")))
2964  template->body = message_template_parse_emailbody(chanvar);
2965  template->attachment = TRUE;
2966 
2967  message_template_build("pager-default", NULL);
2968  template = message_template_find("pager-default");
2969  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
2970  ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress));
2971  if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress")))
2972  ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail));
2973  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset")))
2974  ast_copy_string(template->charset, chanvar, sizeof(template->charset));
2975  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject")))
2976  ast_copy_string(template->subject, chanvar,sizeof(template->subject));
2977  if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody")))
2978  template->body = message_template_parse_emailbody(chanvar);
2979  template->attachment = FALSE;
2980 
2981  if (error)
2982  ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error);
2983 
2985  ast_config_destroy(cfg);
2986 
2987  /* Close log file if it's open and disabled */
2988  if(minivmlogfile)
2989  fclose(minivmlogfile);
2990 
2991  /* Open log file if it's enabled */
2993  minivmlogfile = fopen(global_logfile, "a");
2994  if(!minivmlogfile)
2995  ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno));
2996  if (minivmlogfile)
2997  ast_debug(3, "Opened log file %s \n", global_logfile);
2998  }
2999 
3000  return 0;
3001 }
static struct minivm_template * message_template_find(const char *name)
Definition: app_minivm.c:816
struct ast_variable * next
static int reload(void)
Reload mini voicemail module.
Definition: app_minivm.c:3545
struct timeval reset
Definition: app_minivm.c:681
#define FALSE
Definition: app_minivm.c:521
#define MVM_REVIEW
Definition: app_minivm.c:525
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:2594
static int message_template_build(const char *name, struct ast_variable *var)
Definition: app_minivm.c:753
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static int global_vmminmessage
Definition: app_minivm.c:694
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static int timezone_add(const char *zonename, const char *config)
Add time zone to memory list.
Definition: app_minivm.c:2707
static void vmaccounts_destroy_list(void)
Definition: app_minivm.c:1055
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
static int global_vmmaxmessage
Definition: app_minivm.c:695
#define ast_mutex_lock(a)
Definition: lock.h:187
static int global_silencethreshold
Definition: app_minivm.c:698
static char global_mailcmd[160]
Definition: app_minivm.c:699
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
static char * chanvar
Definition: app_system.c:113
#define ast_strlen_zero(foo)
Definition: strings.h:52
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:687
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static void timezone_destroy_list(void)
Clear list of timezones.
Definition: app_minivm.c:2695
#define ast_config_load(filename, flags)
Load a config file.
#define MVM_OPERATOR
Definition: app_minivm.c:526
static int global_maxgreet
Definition: app_minivm.c:697
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
static int global_maxsilence
Definition: app_minivm.c:696
#define CONFIG_STATUS_FILEUNCHANGED
static FILE * minivmlogfile
Definition: app_minivm.c:692
static char default_vmformat[80]
Definition: app_minivm.c:702
#define LOG_ERROR
Definition: logger.h:285
int errno
static int global_saydurationminfo
Definition: app_minivm.c:705
static const char name[]
Definition: cdr_mysql.c:74
static char * message_template_parse_emailbody(const char *body)
Parse emailbody template from configuration file.
Definition: app_minivm.c:2779
static char global_externnotify[160]
Definition: app_minivm.c:700
Structure used to handle boolean flags.
Definition: utils.h:199
#define SENDMAIL
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
Definition: app_minivm.c:535
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
#define VOICEMAIL_CONFIG
Definition: app_minivm.c:548
int error(const char *format,...)
Definition: utils/frame.c:999
static ast_mutex_t minivmlock
Definition: app_minivm.c:689
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1996
static void message_destroy_list(void)
Definition: app_minivm.c:838
static struct ast_flags globalflags
Definition: app_minivm.c:704
static int apply_general_options(struct ast_variable *var)
Apply general configuration options.
Definition: app_minivm.c:2806
static char global_logfile[PATH_MAX]
Definition: app_minivm.c:701
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ load_module()

static int load_module ( void  )
static

Load mini voicemail module.

Definition at line 3517 of file app_minivm.c.

References app_minivm_accmess, app_minivm_delete, app_minivm_greet, app_minivm_mwi, app_minivm_notify, app_minivm_record, ARRAY_LEN, ast_cli_register_multiple, ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_register_application_xml, load_config(), minivm_accmess_exec(), minivm_delete_exec(), minivm_greet_exec(), minivm_mwi_exec(), minivm_notify_exec(), minivm_record_exec(), and MVM_SPOOL_DIR.

Referenced by unload_module().

3518 {
3519  int res;
3520 
3527 
3530  if (res)
3531  return(res);
3532 
3533  if ((res = load_config(0)))
3534  return(res);
3535 
3537 
3538  /* compute the location of the voicemail spool directory */
3539  snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
3540 
3541  return res;
3542 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_custom_function minivm_counter_function
Definition: app_minivm.c:3505
static char * app_minivm_notify
Definition: app_minivm.c:563
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int minivm_mwi_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2099
static char * app_minivm_record
Definition: app_minivm.c:561
static int minivm_notify_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2137
static struct ast_cli_entry cli_minivm[]
CLI commands for Mini-voicemail.
Definition: app_minivm.c:3496
static char * app_minivm_mwi
Definition: app_minivm.c:566
const char * ast_config_AST_SPOOL_DIR
Definition: options.c:154
static int load_config(int reload)
Load minivoicemail configuration.
Definition: app_minivm.c:2864
static int minivm_accmess_exec(struct ast_channel *chan, const char *data)
Record specific messages for voicemail account.
Definition: app_minivm.c:2496
static char * app_minivm_accmess
Definition: app_minivm.c:565
static int minivm_greet_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2268
static char * app_minivm_greet
Definition: app_minivm.c:562
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508
static int minivm_record_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2215
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626
static char * app_minivm_delete
Definition: app_minivm.c:564
static int minivm_delete_exec(struct ast_channel *chan, const char *data)
Definition: app_minivm.c:2458
static struct ast_custom_function minivm_account_function
Definition: app_minivm.c:3511
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:558

◆ make_dir()

static int make_dir ( char *  dest,
int  len,
const char *  domain,
const char *  username,
const char *  folder 
)
static

Definition at line 1524 of file app_minivm.c.

References ast_strlen_zero, and MVM_SPOOL_DIR.

Referenced by check_dirpath(), and create_dirpath().

1525 {
1526  return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : "");
1527 }
Domain data structure.
Definition: sip.h:888
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:558

◆ message_destroy_list()

static void message_destroy_list ( void  )
static

Definition at line 838 of file app_minivm.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, minivm_account::list, and message_template_free().

Referenced by load_config(), and unload_module().

839 {
840  struct minivm_template *this;
842  while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list))) {
843  message_template_free(this);
844  }
845 
847 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct minivm_template::@55 list
#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:743
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
The list of e-mail templates.
Definition: app_minivm.c:647

◆ message_template_build()

static int message_template_build ( const char *  name,
struct ast_variable var 
)
static

Definition at line 753 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(), error(), global_stats, minivm_account::list, 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().

754 {
755  struct minivm_template *template;
756  int error = 0;
757 
758  template = message_template_create(name);
759  if (!template) {
760  ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name);
761  return -1;
762  }
763 
764  while (var) {
765  ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name);
766  if (!strcasecmp(var->name, "fromaddress")) {
767  ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress));
768  } else if (!strcasecmp(var->name, "fromemail")) {
769  ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail));
770  } else if (!strcasecmp(var->name, "subject")) {
771  ast_copy_string(template->subject, var->value, sizeof(template->subject));
772  } else if (!strcasecmp(var->name, "locale")) {
773  ast_copy_string(template->locale, var->value, sizeof(template->locale));
774  } else if (!strcasecmp(var->name, "attachmedia")) {
775  template->attachment = ast_true(var->value);
776  } else if (!strcasecmp(var->name, "dateformat")) {
777  ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat));
778  } else if (!strcasecmp(var->name, "charset")) {
779  ast_copy_string(template->charset, var->value, sizeof(template->charset));
780  } else if (!strcasecmp(var->name, "templatefile")) {
781  if (template->body)
782  ast_free(template->body);
783  template->body = message_template_parse_filebody(var->value);
784  if (!template->body) {
785  ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value);
786  error++;
787  }
788  } else if (!strcasecmp(var->name, "messagebody")) {
789  if (template->body)
790  ast_free(template->body);
791  template->body = message_template_parse_emailbody(var->value);
792  if (!template->body) {
793  ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value);
794  error++;
795  }
796  } else {
797  ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value);
798  error++;
799  }
800  var = var->next;
801  }
802  if (error)
803  ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name);
804 
808 
810 
811  return error;
812 }
struct ast_variable * next
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct minivm_template::@55 list
#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:687
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char * message_template_parse_filebody(const char *filename)
Read message template from file.
Definition: app_minivm.c:2739
static struct minivm_template * message_template_create(const char *name)
Definition: app_minivm.c:723
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
static char * message_template_parse_emailbody(const char *body)
Parse emailbody template from configuration file.
Definition: app_minivm.c:2779
The list of e-mail templates.
Definition: app_minivm.c:647
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int error(const char *format,...)
Definition: utils/frame.c:999

◆ message_template_create()

static struct minivm_template* message_template_create ( const char *  name)
static

Definition at line 723 of file app_minivm.c.

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

Referenced by message_template_build().

724 {
725  struct minivm_template *template;
726 
727  template = ast_calloc(1, sizeof(*template));
728  if (!template)
729  return NULL;
730 
731  /* Set some defaults for templates */
732  ast_copy_string(template->name, name, sizeof(template->name));
733  ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat));
734  ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset));
735  ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject));
736  template->attachment = TRUE;
737 
738  return template;
739 }
#define DEFAULT_DATEFORMAT
Definition: app_minivm.c:711
#define NULL
Definition: resample.c:96
static const char name[]
Definition: cdr_mysql.c:74
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define DEFAULT_CHARSET
Definition: app_minivm.c:712
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518

◆ message_template_find()

static struct minivm_template* message_template_find ( const char *  name)
static

Definition at line 816 of file app_minivm.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero, minivm_account::list, and NULL.

Referenced by load_config(), and notify_new_message().

817 {
818  struct minivm_template *this, *res = NULL;
819 
820  if (ast_strlen_zero(name))
821  return NULL;
822 
825  if (!strcasecmp(this->name, name)) {
826  res = this;
827  break;
828  }
829  }
831 
832  return res;
833 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
struct minivm_template::@55 list
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
Definition: cdr_mysql.c:74
The list of e-mail templates.
Definition: app_minivm.c:647

◆ message_template_free()

static void message_template_free ( struct minivm_template template)
static

Definition at line 743 of file app_minivm.c.

References ast_free.

Referenced by message_destroy_list().

744 {
745  if (template->body)
746  ast_free(template->body);
747 
748  ast_free (template);
749 }
#define ast_free(a)
Definition: astmm.h:182

◆ message_template_parse_emailbody()

static char * message_template_parse_emailbody ( const char *  body)
static

Parse emailbody template from configuration file.

Definition at line 2779 of file app_minivm.c.

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

Referenced by load_config(), and message_template_build().

2780 {
2781  char *tmpread, *tmpwrite;
2782  char *emailbody = ast_strdup(configuration);
2783 
2784  /* substitute strings \t and \n into the apropriate characters */
2785  tmpread = tmpwrite = emailbody;
2786  while ((tmpwrite = strchr(tmpread,'\\'))) {
2787  int len = strlen("\n");
2788  switch (tmpwrite[1]) {
2789  case 'n':
2790  memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
2791  tmpwrite[0] = '\n';
2792  break;
2793  case 't':
2794  memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1);
2795  tmpwrite[0] = '\t';
2796  break;
2797  default:
2798  ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]);
2799  }
2800  tmpread = tmpwrite + len;
2801  }
2802  return emailbody;
2803 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static char * emailbody
#define ast_log
Definition: astobj2.c:42
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define LOG_NOTICE
Definition: logger.h:263

◆ message_template_parse_filebody()

static char * message_template_parse_filebody ( const char *  filename)
static

Read message template from file.

Definition at line 2739 of file app_minivm.c.

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

Referenced by message_template_build().

2739  {
2740  char buf[BUFSIZ * 6];
2741  char readbuf[BUFSIZ];
2742  char filenamebuf[BUFSIZ];
2743  char *writepos;
2744  char *messagebody;
2745  FILE *fi;
2746  int lines = 0;
2747 
2748  if (ast_strlen_zero(filename))
2749  return NULL;
2750  if (*filename == '/')
2751  ast_copy_string(filenamebuf, filename, sizeof(filenamebuf));
2752  else
2753  snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename);
2754 
2755  if (!(fi = fopen(filenamebuf, "r"))) {
2756  ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf);
2757  return NULL;
2758  }
2759  writepos = buf;
2760  while (fgets(readbuf, sizeof(readbuf), fi)) {
2761  lines ++;
2762  if (writepos != buf) {
2763  *writepos = '\n'; /* Replace EOL with new line */
2764  writepos++;
2765  }
2766  ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf));
2767  writepos += strlen(readbuf) - 1;
2768  }
2769  fclose(fi);
2770  messagebody = ast_calloc(1, strlen(buf + 1));
2771  ast_copy_string(messagebody, buf, strlen(buf) + 1);
2772  ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) );
2773  ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody);
2774 
2775  return messagebody;
2776 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ minivm_accmess_exec()

static int minivm_accmess_exec ( struct ast_channel chan,
const char *  data 
)
static

Record specific messages for voicemail account.

Definition at line 2496 of file app_minivm.c.

References 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, minivm_account::domain, error(), FALSE, find_account(), minivm_account::flags, free_user(), LOG_ERROR, LOG_WARNING, minivm_accmess_options, MVM_ALLOCED, MVM_SPOOL_DIR, NULL, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_NAME_GREETING, OPT_TEMP_GREETING, OPT_UNAVAIL_GREETING, PATH_MAX, pbx_builtin_setvar_helper(), play_record_review(), prompt, tmp(), TRUE, and minivm_account::username.

Referenced by load_module().

2497 {
2498  int argc = 0;
2499  char *argv[2];
2500  char filename[PATH_MAX];
2501  char tmp[PATH_MAX];
2502  char *domain;
2503  char *tmpptr = NULL;
2504  struct minivm_account *vmu;
2505  char *username;
2506  struct ast_flags flags = { 0 };
2507  char *opts[OPT_ARG_ARRAY_SIZE];
2508  int error = FALSE;
2509  char *message = NULL;
2510  char *prompt = NULL;
2511  int duration;
2512 
2513  if (ast_strlen_zero(data)) {
2514  ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
2515  error = TRUE;
2516  } else {
2517  tmpptr = ast_strdupa((char *)data);
2518  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2519  }
2520 
2521  if (argc <=1) {
2522  ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n");
2523  error = TRUE;
2524  }
2525  if (!error && strlen(argv[1]) > 1) {
2526  ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]);
2527  error = TRUE;
2528  }
2529 
2530  if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) {
2531  ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]);
2532  error = TRUE;
2533  }
2534 
2535  if (error) {
2536  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
2537  return -1;
2538  }
2539 
2540  ast_copy_string(tmp, argv[0], sizeof(tmp));
2541  username = tmp;
2542  domain = strchr(tmp, '@');
2543  if (domain) {
2544  *domain = '\0';
2545  domain++;
2546  }
2547  if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
2548  ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
2549  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
2550  return -1;
2551  }
2552 
2553  if(!(vmu = find_account(domain, username, TRUE))) {
2554  /* We could not find user, let's exit */
2555  ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
2556  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED");
2557  return -1;
2558  }
2559 
2560  /* Answer channel if it's not already answered */
2561  if (ast_channel_state(chan) != AST_STATE_UP)
2562  ast_answer(chan);
2563 
2564  /* Here's where the action is */
2565  if (ast_test_flag(&flags, OPT_BUSY_GREETING)) {
2566  message = "busy";
2567  prompt = "vm-rec-busy";
2568  } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) {
2569  message = "unavailable";
2570  prompt = "vm-rec-unv";
2571  } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) {
2572  message = "temp";
2573  prompt = "vm-rec-temp";
2574  } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) {
2575  message = "greet";
2576  prompt = "vm-rec-name";
2577  }
2578  snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message);
2579  /* Maybe we should check the result of play_record_review ? */
2580  play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, NULL, FALSE);
2581 
2582  ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration);
2583 
2584  if(ast_test_flag(vmu, MVM_ALLOCED))
2585  free_user(vmu);
2586 
2587  pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS");
2588 
2589  /* Ok, we're ready to rock and roll. Return to dialplan */
2590  return 0;
2591 }
#define FALSE
Definition: app_minivm.c:521
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define MVM_ALLOCED
Definition: app_minivm.c:531
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
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:1644
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:989
static int tmp()
Definition: bt_open.c:389
static const struct ast_app_option minivm_accmess_options[128]
Definition: app_minivm.c:596
unsigned int flags
Definition: utils.h:200
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int global_maxgreet
Definition: app_minivm.c:697
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
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: main/app.c:2906
static char default_vmformat[80]
Definition: app_minivm.c:702
#define LOG_ERROR
Definition: logger.h:285
Structure used to handle boolean flags.
Definition: utils.h:199
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...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
int error(const char *format,...)
Definition: utils/frame.c:999
#define PATH_MAX
Definition: asterisk.h:40
static struct ast_str * prompt
Definition: asterisk.c:2725
#define ast_app_separate_args(a, b, c, d)
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:558

◆ minivm_account_func_read()

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 3225 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, NULL, minivm_account::pager, minivm_account::pincode, minivm_account::ptemplate, TRUE, minivm_account::username, ast_variable::value, var, and minivm_account::zonetag.

3226 {
3227  struct minivm_account *vmu;
3228  char *username, *domain, *colname;
3229 
3230  username = ast_strdupa(data);
3231 
3232  if ((colname = strchr(username, ':'))) {
3233  *colname = '\0';
3234  colname++;
3235  } else {
3236  colname = "path";
3237  }
3238  if ((domain = strchr(username, '@'))) {
3239  *domain = '\0';
3240  domain++;
3241  }
3242  if (ast_strlen_zero(username) || ast_strlen_zero(domain)) {
3243  ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n");
3244  return 0;
3245  }
3246 
3247  if (!(vmu = find_account(domain, username, TRUE)))
3248  return 0;
3249 
3250  if (!strcasecmp(colname, "hasaccount")) {
3251  ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len);
3252  } else if (!strcasecmp(colname, "fullname")) {
3253  ast_copy_string(buf, vmu->fullname, len);
3254  } else if (!strcasecmp(colname, "email")) {
3255  if (!ast_strlen_zero(vmu->email))
3256  ast_copy_string(buf, vmu->email, len);
3257  else
3258  snprintf(buf, len, "%s@%s", vmu->username, vmu->domain);
3259  } else if (!strcasecmp(colname, "pager")) {
3260  ast_copy_string(buf, vmu->pager, len);
3261  } else if (!strcasecmp(colname, "etemplate")) {
3262  if (!ast_strlen_zero(vmu->etemplate))
3263  ast_copy_string(buf, vmu->etemplate, len);
3264  else
3265  ast_copy_string(buf, "email-default", len);
3266  } else if (!strcasecmp(colname, "language")) {
3267  ast_copy_string(buf, vmu->language, len);
3268  } else if (!strcasecmp(colname, "timezone")) {
3269  ast_copy_string(buf, vmu->zonetag, len);
3270  } else if (!strcasecmp(colname, "ptemplate")) {
3271  if (!ast_strlen_zero(vmu->ptemplate))
3272  ast_copy_string(buf, vmu->ptemplate, len);
3273  else
3274  ast_copy_string(buf, "email-default", len);
3275  } else if (!strcasecmp(colname, "accountcode")) {
3277  } else if (!strcasecmp(colname, "pincode")) {
3278  ast_copy_string(buf, vmu->pincode, len);
3279  } else if (!strcasecmp(colname, "path")) {
3280  check_dirpath(buf, len, vmu->domain, vmu->username, NULL);
3281  } else { /* Look in channel variables */
3282  struct ast_variable *var;
3283 
3284  for (var = vmu->chanvars ; var ; var = var->next)
3285  if (!strcmp(var->name, colname)) {
3286  ast_copy_string(buf, var->value, len);
3287  break;
3288  }
3289  }
3290 
3291  if(ast_test_flag(vmu, MVM_ALLOCED))
3292  free_user(vmu);
3293 
3294  return 0;
3295 }
struct ast_variable * next
char etemplate[80]
Definition: app_minivm.c:616
#define MVM_ALLOCED
Definition: app_minivm.c:531
#define ast_test_flag(p, flag)
Definition: utils.h:63
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:989
char language[MAX_LANGUAGE]
Definition: app_minivm.c:611
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: app_minivm.c:608
#define NULL
Definition: resample.c:96
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
char pincode[10]
Definition: app_minivm.c:604
#define ast_log
Definition: astobj2.c:42
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1538
char email[80]
Definition: app_minivm.c:606
char zonetag[80]
Definition: app_minivm.c:612
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
#define LOG_ERROR
Definition: logger.h:285
struct ast_variable * chanvars
Definition: app_minivm.c:619
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char fullname[120]
Definition: app_minivm.c:605
char ptemplate[80]
Definition: app_minivm.c:617
char pager[80]
Definition: app_minivm.c:607
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518

◆ minivm_counter_func_read()

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 3372 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, NULL, and minivm_account::username.

3373 {
3374  char *username, *domain, *countername;
3375  char userpath[BUFSIZ];
3376  int res;
3377 
3378  *buf = '\0';
3379 
3380  username = ast_strdupa(data);
3381 
3382  if ((countername = strchr(username, ':'))) {
3383  *countername = '\0';
3384  countername++;
3385  }
3386 
3387  if ((domain = strchr(username, '@'))) {
3388  *domain = '\0';
3389  domain++;
3390  }
3391 
3392  /* If we have neither username nor domain now, let's give up */
3393  if (ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3394  ast_log(LOG_ERROR, "No account given\n");
3395  return -1;
3396  }
3397 
3398  if (ast_strlen_zero(countername)) {
3399  ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n");
3400  return -1;
3401  }
3402 
3403  /* We only have a domain, no username */
3404  if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3405  domain = username;
3406  username = NULL;
3407  }
3408 
3409  /* If we can't find account or if the account is temporary, return. */
3410  if (!ast_strlen_zero(username) && !find_account(domain, username, FALSE)) {
3411  ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
3412  return 0;
3413  }
3414 
3415  create_dirpath(userpath, sizeof(userpath), domain, username, NULL);
3416 
3417  /* We have the path, now read the counter file */
3418  res = access_counter_file(userpath, countername, 0, 0);
3419  if (res >= 0)
3420  snprintf(buf, len, "%d", res);
3421  return 0;
3422 }
#define FALSE
Definition: app_minivm.c:521
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1557
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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:3319

◆ minivm_counter_func_write()

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 3425 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, NULL, and minivm_account::username.

3426 {
3427  char *username, *domain, *countername, *operand;
3428  char userpath[BUFSIZ];
3429  int change = 0;
3430  int operation = 0;
3431 
3432  if(!value)
3433  return -1;
3434  change = atoi(value);
3435 
3436  username = ast_strdupa(data);
3437 
3438  if ((countername = strchr(username, ':'))) {
3439  *countername = '\0';
3440  countername++;
3441  }
3442  if ((operand = strchr(countername, ':'))) {
3443  *operand = '\0';
3444  operand++;
3445  }
3446 
3447  if ((domain = strchr(username, '@'))) {
3448  *domain = '\0';
3449  domain++;
3450  }
3451 
3452  /* If we have neither username nor domain now, let's give up */
3453  if (ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3454  ast_log(LOG_ERROR, "No account given\n");
3455  return -1;
3456  }
3457 
3458  /* We only have a domain, no username */
3459  if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) {
3460  domain = username;
3461  username = NULL;
3462  }
3463 
3464  if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) {
3465  ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n");
3466  return -1;
3467  }
3468 
3469  /* If we can't find account or if the account is temporary, return. */
3470  if (!ast_strlen_zero(username) && !find_account(domain, username, FALSE)) {
3471  ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain);
3472  return 0;
3473  }
3474 
3475  create_dirpath(userpath, sizeof(userpath), domain, username, NULL);
3476  /* Now, find out our operator */
3477  if (*operand == 'i') /* Increment */
3478  operation = 2;
3479  else if (*operand == 'd') {
3480  change = change * -1;
3481  operation = 2;
3482  } else if (*operand == 's')
3483  operation = 1;
3484  else {
3485  ast_log(LOG_ERROR, "Unknown operator: %s\n", operand);
3486  return -1;
3487  }
3488 
3489  /* We have the path, now read the counter file */
3490  access_counter_file(userpath, countername, change, operation);
3491  return 0;
3492 }
#define FALSE
Definition: app_minivm.c:521
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
int value
Definition: syslog.c:37
static int create_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1557
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
#define LOG_ERROR
Definition: logger.h:285
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:3319

◆ minivm_delete_exec()

static int minivm_delete_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2458 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, NULL, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and vm_delete().

Referenced by load_module().

2459 {
2460  int res = 0;
2461  char filename[BUFSIZ];
2462 
2463  if (!ast_strlen_zero(data)) {
2464  ast_copy_string(filename, (char *) data, sizeof(filename));
2465  } else {
2466  ast_channel_lock(chan);
2467  ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename));
2468  ast_channel_unlock(chan);
2469  }
2470 
2471  if (ast_strlen_zero(filename)) {
2472  ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n");
2473  return res;
2474  }
2475 
2476  /* Go ahead and delete audio files from system, they're not needed any more */
2477  /* We should look for both audio and text files here */
2478  if (ast_fileexists(filename, NULL, NULL) > 0) {
2479  res = vm_delete(filename);
2480  if (res) {
2481  ast_debug(2, "Can't delete file: %s\n", filename);
2482  pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED");
2483  } else {
2484  ast_debug(2, "Deleted voicemail file :: %s \n", filename);
2485  pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS");
2486  }
2487  } else {
2488  ast_debug(2, "Filename does not exist: %s\n", filename);
2489  pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED");
2490  }
2491 
2492  return res;
2493 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static int vm_delete(char *file)
Definition: app_minivm.c:1630
#define NULL
Definition: resample.c:96
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:1086

◆ minivm_greet_exec()

static int minivm_greet_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2268 of file app_minivm.c.

References ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_channel_caller(), ast_channel_context(), ast_channel_context_set(), ast_channel_exten_set(), ast_channel_language(), ast_channel_macrocontext(), ast_channel_priority_set(), ast_copy_flags, ast_copy_string(), ast_debug, ast_exists_extension(), ast_log, ast_play_and_wait(), ast_set_flag, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero, ast_test_flag, ast_waitstream(), check_dirpath(), minivm_account::domain, minivm_account::exit, find_account(), minivm_account::flags, free_user(), invent_message(), LOG_ERROR, minivm_app_options, MVM_ALLOCED, MVM_OPERATOR, MVM_SPOOL_DIR, NULL, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_SILENT, OPT_UNAVAIL_GREETING, PATH_MAX, pbx_builtin_setvar_helper(), S_COR, SOUND_INTRO, tmp(), TRUE, and minivm_account::username.

Referenced by load_module().

2269 {
2270  struct leave_vm_options leave_options = { 0, '\0'};
2271  int argc;
2272  char *argv[2];
2273  struct ast_flags flags = { 0 };
2274  char *opts[OPT_ARG_ARRAY_SIZE];
2275  int res = 0;
2276  int ausemacro = 0;
2277  int ousemacro = 0;
2278  int ouseexten = 0;
2279  char tmp[PATH_MAX];
2280  char dest[PATH_MAX];
2281  char prefile[PATH_MAX] = "";
2282  char tempfile[PATH_MAX] = "";
2283  char ext_context[256] = "";
2284  char *domain;
2285  char ecodes[16] = "#";
2286  char *tmpptr;
2287  struct minivm_account *vmu;
2288  char *username;
2289 
2290  if (ast_strlen_zero(data)) {
2291  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2292  return -1;
2293  }
2294  tmpptr = ast_strdupa((char *)data);
2295  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2296 
2297  if (argc == 2) {
2298  if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1]))
2299  return -1;
2300  ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
2301  }
2302 
2303  ast_copy_string(tmp, argv[0], sizeof(tmp));
2304  username = tmp;
2305  domain = strchr(tmp, '@');
2306  if (domain) {
2307  *domain = '\0';
2308  domain++;
2309  }
2310  if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
2311  ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]);
2312  return -1;
2313  }
2314  ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain);
2315 
2316  if (!(vmu = find_account(domain, username, TRUE))) {
2317  ast_log(LOG_ERROR, "Could not allocate memory. \n");
2318  return -1;
2319  }
2320 
2321  /* Answer channel if it's not already answered */
2322  if (ast_channel_state(chan) != AST_STATE_UP)
2323  ast_answer(chan);
2324 
2325  /* Setup pre-file if appropriate */
2326  if (strcmp(vmu->domain, "localhost"))
2327  snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain);
2328  else
2329  ast_copy_string(ext_context, vmu->domain, sizeof(ext_context));
2330 
2331  if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) {
2332  res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy");
2333  if (res)
2334  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username);
2335  } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) {
2336  res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail");
2337  if (res)
2338  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username);
2339  }
2340  /* Check for temporary greeting - it overrides busy and unavail */
2341  snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username);
2342  if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) {
2343  ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile);
2344  ast_copy_string(prefile, tempfile, sizeof(prefile));
2345  }
2346  ast_debug(2, "Preparing to play message ...\n");
2347 
2348  /* Check current or macro-calling context for special extensions */
2349  if (ast_test_flag(vmu, MVM_OPERATOR)) {
2350  if (!ast_strlen_zero(vmu->exit)) {
2351  if (ast_exists_extension(chan, vmu->exit, "o", 1,
2352  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
2353  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
2354  ouseexten = 1;
2355  }
2356  } else if (ast_exists_extension(chan, ast_channel_context(chan), "o", 1,
2357  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
2358  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
2359  ouseexten = 1;
2360  }
2361  else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
2362  && ast_exists_extension(chan, ast_channel_macrocontext(chan), "o", 1,
2363  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
2364  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
2365  ousemacro = 1;
2366  }
2367  }
2368 
2369  if (!ast_strlen_zero(vmu->exit)) {
2370  if (ast_exists_extension(chan, vmu->exit, "a", 1,
2371  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
2372  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
2373  }
2374  } else if (ast_exists_extension(chan, ast_channel_context(chan), "a", 1,
2375  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
2376  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
2377  } else if (!ast_strlen_zero(ast_channel_macrocontext(chan))
2378  && ast_exists_extension(chan, ast_channel_macrocontext(chan), "a", 1,
2379  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) {
2380  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
2381  ausemacro = 1;
2382  }
2383 
2384  res = 0; /* Reset */
2385  /* Play the beginning intro if desired */
2386  if (!ast_strlen_zero(prefile)) {
2387  if (ast_streamfile(chan, prefile, ast_channel_language(chan)) > -1)
2388  res = ast_waitstream(chan, ecodes);
2389  } else {
2390  ast_debug(2, "%s doesn't exist, doing what we can\n", prefile);
2391  res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes);
2392  }
2393  if (res < 0) {
2394  ast_debug(2, "Hang up during prefile playback\n");
2395  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED");
2396  if(ast_test_flag(vmu, MVM_ALLOCED))
2397  free_user(vmu);
2398  return -1;
2399  }
2400  if (res == '#') {
2401  /* On a '#' we skip the instructions */
2402  ast_set_flag(&leave_options, OPT_SILENT);
2403  res = 0;
2404  }
2405  if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) {
2406  res = ast_streamfile(chan, SOUND_INTRO, ast_channel_language(chan));
2407  if (!res)
2408  res = ast_waitstream(chan, ecodes);
2409  if (res == '#') {
2410  ast_set_flag(&leave_options, OPT_SILENT);
2411  res = 0;
2412  }
2413  }
2414  if (res > 0)
2415  ast_stopstream(chan);
2416  /* Check for a '*' here in case the caller wants to escape from voicemail to something
2417  other than the operator -- an automated attendant or mailbox login for example */
2418  if (res == '*') {
2419  ast_channel_exten_set(chan, "a");
2420  if (!ast_strlen_zero(vmu->exit)) {
2421  ast_channel_context_set(chan, vmu->exit);
2422  } else if (ausemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
2424  }
2425  ast_channel_priority_set(chan, 0);
2426  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
2427  res = 0;
2428  } else if (res == '0') { /* Check for a '0' here */
2429  if(ouseexten || ousemacro) {
2430  ast_channel_exten_set(chan, "o");
2431  if (!ast_strlen_zero(vmu->exit)) {
2432  ast_channel_context_set(chan, vmu->exit);
2433  } else if (ousemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) {
2435  }
2436  ast_play_and_wait(chan, "transfer");
2437  ast_channel_priority_set(chan, 0);
2438  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT");
2439  }
2440  res = 0;
2441  } else if (res < 0) {
2442  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED");
2443  res = -1;
2444  } else
2445  pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS");
2446 
2447  if(ast_test_flag(vmu, MVM_ALLOCED))
2448  free_user(vmu);
2449 
2450 
2451  /* Ok, we're ready to rock and roll. Return to dialplan */
2452  return res;
2453 
2454 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define MVM_ALLOCED
Definition: app_minivm.c:531
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:989
static int tmp()
Definition: bt_open.c:389
unsigned int flags
Definition: utils.h:200
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define NULL
Definition: resample.c:96
Domain data structure.
Definition: sip.h:888
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int check_dirpath(char *dest, int len, char *domain, char *username, char *folder)
Definition: app_minivm.c:1538
static int invent_message(struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes)
Definition: app_minivm.c:1573
char exit[80]
Definition: app_minivm.c:614
#define MVM_OPERATOR
Definition: app_minivm.c:526
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: main/app.c:1470
#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:85
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
static const struct ast_app_option minivm_app_options[128]
Definition: app_minivm.c:589
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:4179
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: main/app.c:2906
#define LOG_ERROR
Definition: logger.h:285
Structure used to handle boolean flags.
Definition: utils.h:199
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:650
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
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...
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
const char * ast_channel_language(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
#define PATH_MAX
Definition: asterisk.h:40
const char * ast_channel_macrocontext(const struct ast_channel *chan)
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define SOUND_INTRO
Definition: app_minivm.c:537
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187
#define ast_app_separate_args(a, b, c, d)
static char MVM_SPOOL_DIR[PATH_MAX]
Definition: app_minivm.c:558

◆ minivm_mwi_exec()

static int minivm_mwi_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2099 of file app_minivm.c.

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

Referenced by load_module().

2100 {
2101  int argc;
2102  char *argv[4];
2103  int res = 0;
2104  char *tmpptr;
2105  char tmp[PATH_MAX];
2106  char *mailbox;
2107  char *domain;
2108  if (ast_strlen_zero(data)) {
2109  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2110  return -1;
2111  }
2112  tmpptr = ast_strdupa((char *)data);
2113  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2114  if (argc < 4) {
2115  ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc);
2116  return -1;
2117  }
2118  ast_copy_string(tmp, argv[0], sizeof(tmp));
2119  mailbox = tmp;
2120  domain = strchr(tmp, '@');
2121  if (domain) {
2122  *domain = '\0';
2123  domain++;
2124  }
2125  if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) {
2126  ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]);
2127  return -1;
2128  }
2129  queue_mwi_event(ast_channel_uniqueid(chan), mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
2130 
2131  return res;
2132 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int tmp()
Definition: bt_open.c:389
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static void queue_mwi_event(const char *channel_id, const char *mbx, const char *ctx, int urgent, int new, int old)
Definition: app_minivm.c:2084
#define PATH_MAX
Definition: asterisk.h:40
#define ast_app_separate_args(a, b, c, d)

◆ minivm_notify_exec()

static int minivm_notify_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2137 of file app_minivm.c.

References ARRAY_LEN, ast_app_separate_args, ast_channel_caller(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log, ast_strdupa, ast_strlen_zero, ast_test_flag, minivm_account::domain, find_account(), format, free_user(), LOG_ERROR, LOG_WARNING, MVM_ALLOCED, name, notify_new_message(), NULL, PATH_MAX, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_COR, tmp(), TRUE, and minivm_account::username.

Referenced by load_module().

2138 {
2139  int argc;
2140  char *argv[2];
2141  int res = 0;
2142  char tmp[PATH_MAX];
2143  char *domain;
2144  char *tmpptr;
2145  struct minivm_account *vmu;
2146  char *username;
2147  const char *template = "";
2148  const char *filename;
2149  const char *format;
2150  const char *duration_string;
2151  if (ast_strlen_zero(data)) {
2152  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2153  return -1;
2154  }
2155  tmpptr = ast_strdupa((char *)data);
2156  argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv));
2157 
2158  if (argc == 2 && !ast_strlen_zero(argv[1]))
2159  template = argv[1];
2160 
2161  ast_copy_string(tmp, argv[0], sizeof(tmp));
2162  username = tmp;
2163  domain = strchr(tmp, '@');
2164  if (domain) {
2165  *domain = '\0';
2166  domain++;
2167  }
2168  if (ast_strlen_zero(domain) || ast_strlen_zero(username)) {
2169  ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]);
2170  return -1;
2171  }
2172 
2173  if(!(vmu = find_account(domain, username, TRUE))) {
2174  /* We could not find user, let's exit */
2175  ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain);
2176  pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED");
2177  return -1;
2178  }
2179 
2180  ast_channel_lock(chan);
2181  if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) {
2182  filename = ast_strdupa(filename);
2183  }
2184  ast_channel_unlock(chan);
2185  /* Notify of new message to e-mail and pager */
2186  if (!ast_strlen_zero(filename)) {
2187  ast_channel_lock(chan);
2188  if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) {
2189  format = ast_strdupa(format);
2190  }
2191  if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) {
2192  duration_string = ast_strdupa(duration_string);
2193  }
2194  ast_channel_unlock(chan);
2195  res = notify_new_message(chan, template, vmu, filename, atoi(duration_string),
2196  format,
2197  S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
2198  S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL));
2199  }
2200 
2201  pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED");
2202 
2203 
2204  if(ast_test_flag(vmu, MVM_ALLOCED))
2205  free_user(vmu);
2206 
2207  /* Ok, we're ready to rock and roll. Return to dialplan */
2208 
2209  return res;
2210 
2211 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define MVM_ALLOCED
Definition: app_minivm.c:531
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
static void free_user(struct minivm_account *vmu)
Definition: app_minivm.c:989
static int tmp()
Definition: bt_open.c:389
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
#define NULL
Definition: resample.c:96
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:1811
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
Number structure.
Definition: app_followme.c:154
#define ast_log
Definition: astobj2.c:42
#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:85
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static struct minivm_account * find_account(const char *domain, const char *username, int createtemp)
Definition: app_minivm.c:1067
#define LOG_ERROR
Definition: logger.h:285
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static const char name[]
Definition: cdr_mysql.c:74
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...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define TRUE
Definition: app_minivm.c:518
#define PATH_MAX
Definition: asterisk.h:40
static snd_pcm_format_t format
Definition: chan_alsa.c:102
#define ast_app_separate_args(a, b, c, d)

◆ minivm_record_exec()

static int minivm_record_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 2215 of file app_minivm.c.

References 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(), leave_vm_options::record_gain, and tmp().

Referenced by load_module().

2216 {
2217  int res = 0;
2218  char *tmp;
2219  struct leave_vm_options leave_options;
2220  int argc;
2221  char *argv[2];
2222  struct ast_flags flags = { 0 };
2223  char *opts[OPT_ARG_ARRAY_SIZE];
2224 
2225  memset(&leave_options, 0, sizeof(leave_options));
2226 
2227  /* Answer channel if it's not already answered */
2228  if (ast_channel_state(chan) != AST_STATE_UP)
2229  ast_answer(chan);
2230 
2231  if (ast_strlen_zero(data)) {
2232  ast_log(LOG_ERROR, "Minivm needs at least an account argument \n");
2233  return -1;
2234  }
2235  tmp = ast_strdupa((char *)data);
2236  argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv));
2237  if (argc == 2) {
2238  if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) {
2239  return -1;
2240  }
2241  ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING );
2242  if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
2243  int gain;
2244 
2245  if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
2246  ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
2247  return -1;
2248  } else
2249  leave_options.record_gain = (signed char) gain;
2250  }
2251  }
2252 
2253  /* Now run the appliation and good luck to you! */
2254  res = leave_voicemail(chan, argv[0], &leave_options);
2255 
2256  if (res == ERROR_LOCK_PATH) {
2257  ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
2258  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED");
2259  res = 0;
2260  }
2261  pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS");
2262 
2263  return res;
2264 }
#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:274
static int tmp()
Definition: bt_open.c:389
unsigned int flags
Definition: utils.h:200
ast_channel_state
ast_channel states
Definition: channelstate.h:35
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int leave_voicemail(struct ast_channel *chan, char *username, struct leave_vm_options *options)
Definition: app_minivm.c:1912
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static const struct ast_app_option minivm_app_options[128]
Definition: app_minivm.c:589
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: main/app.c:2906
#define LOG_ERROR
Definition: logger.h:285
Structure used to handle boolean flags.
Definition: utils.h:199
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:650
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...
#define ERROR_LOCK_PATH
Definition: app_minivm.c:545
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
#define ast_app_separate_args(a, b, c, d)

◆ mvm_user_alloc()

static struct minivm_account* mvm_user_alloc ( void  )
static

Definition at line 1040 of file app_minivm.c.

References ast_calloc, NULL, and populate_defaults().

Referenced by find_account(), and find_user_realtime().

1041 {
1042  struct minivm_account *new;
1043 
1044  new = ast_calloc(1, sizeof(*new));
1045  if (!new)
1046  return NULL;
1047  populate_defaults(new);
1048 
1049  return new;
1050 }
#define NULL
Definition: resample.c:96
static void populate_defaults(struct minivm_account *vmu)
Definition: app_minivm.c:1031
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ notify_new_message()

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

References ao2_cleanup, ast_channel_lock, ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_channel_unlock, ast_copy_string(), ast_debug, ast_json_pack(), ast_json_unref(), ast_log, ast_mwi_blob_create(), ast_mwi_create(), ast_mwi_topic(), ast_mwi_vm_app_type(), ast_strdupa, ast_strlen_zero, minivm_account::attachfmt, minivm_template::attachment, minivm_account::domain, minivm_account::etemplate, minivm_template::locale, LOG_WARNING, message_template_find(), MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, NULL, minivm_account::pager, pbx_builtin_getvar_helper(), minivm_account::ptemplate, RAII_VAR, run_externnotify(), sendmail(), stasis_publish(), strsep(), and minivm_account::username.

Referenced by minivm_notify_exec().

1812 {
1813  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1815  RAII_VAR(struct ast_mwi_state *, mwi_state, NULL, ao2_cleanup);
1816  char *stringp;
1817  struct minivm_template *etemplate;
1818  char *messageformat;
1819  int res = 0;
1820  char oldlocale[100];
1821  const char *counter;
1822 
1823  if (!ast_strlen_zero(vmu->attachfmt)) {
1824  if (strstr(format, vmu->attachfmt)) {
1825  format = vmu->attachfmt;
1826  } else {
1827  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);
1828  }
1829  }
1830 
1831  etemplate = message_template_find(vmu->etemplate);
1832  if (!etemplate)
1833  etemplate = message_template_find(templatename);
1834  if (!etemplate)
1835  etemplate = message_template_find("email-default");
1836 
1837  /* Attach only the first format */
1838  stringp = messageformat = ast_strdupa(format);
1839  strsep(&stringp, "|");
1840 
1841  if (!ast_strlen_zero(etemplate->locale)) {
1842  char *new_locale;
1843  ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale));
1844  ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale);
1845  new_locale = setlocale(LC_TIME, etemplate->locale);
1846  if (new_locale == NULL) {
1847  ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale);
1848  }
1849  }
1850 
1851 
1852 
1853  /* Read counter if available */
1854  ast_channel_lock(chan);
1855  if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) {
1856  counter = ast_strdupa(counter);
1857  }
1858  ast_channel_unlock(chan);
1859 
1860  if (ast_strlen_zero(counter)) {
1861  ast_debug(2, "MVM_COUNTER not found\n");
1862  } else {
1863  ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter);
1864  }
1865 
1866  res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter);
1867 
1868  if (res == 0 && !ast_strlen_zero(vmu->pager)) {
1869  /* Find template for paging */
1870  etemplate = message_template_find(vmu->ptemplate);
1871  if (!etemplate)
1872  etemplate = message_template_find("pager-default");
1873 
1874  if (!ast_strlen_zero(etemplate->locale)) {
1875  ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale));
1876  setlocale(LC_TIME, etemplate->locale);
1877  }
1878 
1879  res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter);
1880  }
1881 
1882  mwi_state = ast_mwi_create(vmu->username, vmu->domain);
1883  if (!mwi_state) {
1884  goto notify_cleanup;
1885  }
1886  mwi_state->snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
1887 
1888  json_object = ast_json_pack("{s: s, s: s, s: s}",
1889  "Event", "MiniVoiceMail",
1890  "Action", "SentNotification",
1891  "Counter", counter ?: "");
1892  if (!json_object) {
1893  goto notify_cleanup;
1894  }
1895  message = ast_mwi_blob_create(mwi_state, ast_mwi_vm_app_type(), json_object);
1896  if (!message) {
1897  goto notify_cleanup;
1898  }
1899  stasis_publish(ast_mwi_topic(mwi_state->uniqueid), message);
1900 
1901 notify_cleanup:
1902  run_externnotify(chan, vmu); /* Run external notification */
1903  if (!ast_strlen_zero(etemplate->locale)) {
1904  setlocale(LC_TIME, oldlocale); /* Reset to old locale */
1905  }
1906  return res;
1907 }
static struct minivm_template * message_template_find(const char *name)
Definition: app_minivm.c:816
char attachfmt[80]
Definition: app_minivm.c:615
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
char etemplate[80]
Definition: app_minivm.c:616
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_mwi_state * ast_mwi_create(const char *mailbox, const char *context)
Create a ast_mwi_state object.
Definition: mwi.c:148
#define LOG_WARNING
Definition: logger.h:274
struct stasis_message * ast_mwi_blob_create(struct ast_mwi_state *mwi_state, struct stasis_message_type *message_type, struct ast_json *blob)
Creates a ast_mwi_blob message.
Definition: mwi.c:462
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
#define NULL
Definition: resample.c:96
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
#define ast_strlen_zero(foo)
Definition: strings.h:52
char locale[20]
Definition: app_minivm.c:640
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_channel_uniqueid(const struct ast_channel *chan)
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:1234
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
char ptemplate[80]
Definition: app_minivm.c:617
char * strsep(char **str, const char *delims)
char pager[80]
Definition: app_minivm.c:607
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
Abstract JSON element (object, array, string, int, ...).
static void run_externnotify(struct ast_channel *chan, struct minivm_account *vmu)
Run external notification for voicemail message.
Definition: app_minivm.c:1776
The structure that contains MWI state.
Definition: mwi.h:457
struct stasis_topic * ast_mwi_topic(const char *uniqueid)
Get the Stasis Message Bus API topic for MWI messages on a unique ID.
Definition: mwi.c:100
static snd_pcm_format_t format
Definition: chan_alsa.c:102
struct stasis_message_type * ast_mwi_vm_app_type(void)
Get the Stasis Message Bus API message type for voicemail application specific messages.

◆ play_record_review()

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

References ast_channel_language(), ast_channel_setoption(), AST_DIGIT_ANY, ast_log, AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), AST_RECORD_IF_EXISTS_OVERWRITE, ast_stream_and_wait(), ast_streamfile(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_waitstream(), LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, NULL, and vm_delete().

Referenced by leave_voicemail(), and minivm_accmess_exec().

1647 {
1648  int cmd = 0;
1649  int max_attempts = 3;
1650  int attempts = 0;
1651  int recorded = 0;
1652  int message_exists = 0;
1653  signed char zero_gain = 0;
1654  char *acceptdtmf = "#";
1655  char *canceldtmf = "";
1656 
1657  /* Note that urgent and private are for flagging messages as such in the future */
1658 
1659  /* barf if no pointer passed to store duration in */
1660  if (duration == NULL) {
1661  ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n");
1662  return -1;
1663  }
1664 
1665  cmd = '3'; /* Want to start by recording */
1666 
1667  while ((cmd >= 0) && (cmd != 't')) {
1668  switch (cmd) {
1669  case '1':
1670  ast_verb(3, "Saving message as is\n");
1671  ast_stream_and_wait(chan, "vm-msgsaved", "");
1672  cmd = 't';
1673  break;
1674  case '2':
1675  /* Review */
1676  ast_verb(3, "Reviewing the message\n");
1677  ast_streamfile(chan, recordfile, ast_channel_language(chan));
1678  cmd = ast_waitstream(chan, AST_DIGIT_ANY);
1679  break;
1680  case '3':
1681  message_exists = 0;
1682  /* Record */
1683  if (recorded == 1)
1684  ast_verb(3, "Re-recording the message\n");
1685  else
1686  ast_verb(3, "Recording the message\n");
1687  if (recorded && outsidecaller)
1688  cmd = ast_play_and_wait(chan, "beep");
1689  recorded = 1;
1690  /* 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 */
1691  if (record_gain)
1692  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
1693  if (ast_test_flag(vmu, MVM_OPERATOR))
1694  canceldtmf = "0";
1695  cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, 0, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf, 0, AST_RECORD_IF_EXISTS_OVERWRITE);
1696  if (record_gain)
1697  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
1698  if (cmd == -1) /* User has hung up, no options to give */
1699  return cmd;
1700  if (cmd == '0')
1701  break;
1702  else if (cmd == '*')
1703  break;
1704  else {
1705  /* If all is well, a message exists */
1706  message_exists = 1;
1707  cmd = 0;
1708  }
1709  break;
1710  case '4':
1711  case '5':
1712  case '6':
1713  case '7':
1714  case '8':
1715  case '9':
1716  case '*':
1717  case '#':
1718  cmd = ast_play_and_wait(chan, "vm-sorry");
1719  break;
1720  case '0':
1721  if(!ast_test_flag(vmu, MVM_OPERATOR)) {
1722  cmd = ast_play_and_wait(chan, "vm-sorry");
1723  break;
1724  }
1725  if (message_exists || recorded) {
1726  cmd = ast_play_and_wait(chan, "vm-saveoper");
1727  if (!cmd)
1728  cmd = ast_waitfordigit(chan, 3000);
1729  if (cmd == '1') {
1730  ast_play_and_wait(chan, "vm-msgsaved");
1731  cmd = '0';
1732  } else {
1733  ast_play_and_wait(chan, "vm-deleted");
1734  vm_delete(recordfile);
1735  cmd = '0';
1736  }
1737  }
1738  return cmd;
1739  default:
1740  /* If the caller is an ouside caller, and the review option is enabled,
1741  allow them to review the message, but let the owner of the box review
1742  their OGM's */
1743  if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW))
1744  return cmd;
1745  if (message_exists) {
1746  cmd = ast_play_and_wait(chan, "vm-review");
1747  } else {
1748  cmd = ast_play_and_wait(chan, "vm-torerecord");
1749  if (!cmd)
1750  cmd = ast_waitfordigit(chan, 600);
1751  }
1752 
1753  if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) {
1754  cmd = ast_play_and_wait(chan, "vm-reachoper");
1755  if (!cmd)
1756  cmd = ast_waitfordigit(chan, 600);
1757  }
1758  if (!cmd)
1759  cmd = ast_waitfordigit(chan, 6000);
1760  if (!cmd) {
1761  attempts++;
1762  }
1763  if (attempts > max_attempts) {
1764  cmd = 't';
1765  }
1766  }
1767  }
1768  if (outsidecaller)
1769  ast_play_and_wait(chan, "vm-goodbye");
1770  if (cmd == 't')
1771  cmd = 0;
1772  return cmd;
1773 }
static int vm_delete(char *file)
Definition: app_minivm.c:1630
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:1250
#define MVM_REVIEW
Definition: app_minivm.c:525
#define AST_DIGIT_ANY
Definition: file.h:48
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
static int global_silencethreshold
Definition: app_minivm.c:698
#define NULL
Definition: resample.c:96
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:7522
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
#define MVM_OPERATOR
Definition: app_minivm.c:526
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: main/app.c:1470
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 beep, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf, int skip_confirmation_sound, enum ast_record_if_exists if_exists)
Record a file based on input from a channel This function will play "auth-thankyou" upon successful r...
Definition: main/app.c:1992
static int global_maxsilence
Definition: app_minivm.c:696
#define AST_OPTION_RXGAIN
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:1814
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1776
const char * ast_channel_language(const struct ast_channel *chan)

◆ populate_defaults()

static void populate_defaults ( struct minivm_account vmu)
static

Definition at line 1031 of file app_minivm.c.

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

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

1032 {
1034  ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt));
1035  vmu->volgain = global_volgain;
1036 }
char attachfmt[80]
Definition: app_minivm.c:615
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
double volgain
Definition: app_minivm.c:620
static char default_vmformat[80]
Definition: app_minivm.c:702
#define AST_FLAGS_ALL
Definition: utils.h:196
static double global_volgain
Definition: app_minivm.c:707
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static struct ast_flags globalflags
Definition: app_minivm.c:704

◆ prep_email_sub_vars()

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 1002 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().

1003 {
1004  char callerid[256];
1005  struct ast_variable *var;
1006 
1007  if (!channel) {
1008  ast_log(LOG_ERROR, "No allocated channel, giving up...\n");
1009  return;
1010  }
1011 
1012  for (var = vmu->chanvars ; var ; var = var->next) {
1013  pbx_builtin_setvar_helper(channel, var->name, var->value);
1014  }
1015 
1016  /* Prepare variables for substition in email body and subject */
1017  pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname);
1018  pbx_builtin_setvar_helper(channel, "MVM_DUR", dur);
1019  pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain);
1020  pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username);
1021  pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller"));
1022  pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller"));
1023  pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller"));
1024  pbx_builtin_setvar_helper(channel, "MVM_DATE", date);
1025  if (!ast_strlen_zero(counter))
1026  pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter);
1027 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1073
#define LOG_ERROR
Definition: logger.h:285
struct ast_variable * chanvars
Definition: app_minivm.c:619
char fullname[120]
Definition: app_minivm.c:605
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...

◆ queue_mwi_event()

static void queue_mwi_event ( const char *  channel_id,
const char *  mbx,
const char *  ctx,
int  urgent,
int  new,
int  old 
)
static

Definition at line 2084 of file app_minivm.c.

References ast_publish_mwi_state_channel, ast_strdupa, ast_strlen_zero, context, and mailbox.

Referenced by minivm_mwi_exec().

2085 {
2086  char *mailbox, *context;
2087 
2088  mailbox = ast_strdupa(mbx);
2089  context = ast_strdupa(ctx);
2090  if (ast_strlen_zero(context)) {
2091  context = "default";
2092  }
2093 
2094  ast_publish_mwi_state_channel(mailbox, context, new + urgent, old, channel_id);
2095 }
#define ast_strlen_zero(foo)
Definition: strings.h:52
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
Definition: chan_mgcp.c:204
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_publish_mwi_state_channel(mailbox, context, new_msgs, old_msgs, channel_id)
Publish a MWI state update associated with some channel.
Definition: mwi.h:397
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ reload()

static int reload ( void  )
static

Reload mini voicemail module.

Definition at line 3545 of file app_minivm.c.

References load_config().

Referenced by handle_minivm_reload(), and unload_module().

3546 {
3547  return(load_config(1));
3548 }
static int load_config(int reload)
Load minivoicemail configuration.
Definition: app_minivm.c:2864

◆ run_externnotify()

static void run_externnotify ( struct ast_channel chan,
struct minivm_account vmu 
)
static

Run external notification for voicemail message.

Definition at line 1776 of file app_minivm.c.

References ast_channel_caller(), ast_debug, AST_MAX_CONTEXT, ast_safe_execvp(), ast_strlen_zero, minivm_account::domain, minivm_account::externnotify, global_externnotify, ast_party_caller::id, ast_party_id::name, NULL, ast_party_id::number, S_COR, 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().

1777 {
1778  char fquser[AST_MAX_CONTEXT * 2];
1779  char *argv[5] = { NULL };
1780  struct ast_party_caller *caller;
1781  char *cid;
1782  int idx;
1783 
1785  return;
1786  }
1787 
1788  snprintf(fquser, sizeof(fquser), "%s@%s", vmu->username, vmu->domain);
1789 
1790  caller = ast_channel_caller(chan);
1791  idx = 0;
1792  argv[idx++] = ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify;
1793  argv[idx++] = fquser;
1794  cid = S_COR(caller->id.name.valid, caller->id.name.str, NULL);
1795  if (cid) {
1796  argv[idx++] = cid;
1797  }
1798  cid = S_COR(caller->id.number.valid, caller->id.number.str, NULL);
1799  if (cid) {
1800  argv[idx++] = cid;
1801  }
1802  argv[idx] = NULL;
1803 
1804  ast_debug(1, "Executing: %s %s %s %s\n",
1805  argv[0], argv[1], argv[2] ?: "", argv[3] ?: "");
1806  ast_safe_execvp(1, argv[0], argv);
1807 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
char * str
Subscriber name (Malloced)
Definition: channel.h:265
#define NULL
Definition: resample.c:96
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
Caller Party information.
Definition: channel.h:419
#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:85
#define AST_MAX_CONTEXT
Definition: channel.h:136
static char global_externnotify[160]
Definition: app_minivm.c:700
char externnotify[160]
Definition: app_minivm.c:610
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:280
int ast_safe_execvp(int dualfork, const char *file, char *const argv[])
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1180
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343

◆ sendmail()

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 1234 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_strftime(), ast_strlen_zero, ast_tvnow(), base_encode(), check_mime(), DEBUG_ATLEAST, minivm_account::domain, minivm_account::email, errno, minivm_account::fullname, host, minivm_account::list, LOG_ERROR, LOG_WARNING, MAXHOSTNAMELEN, mkdtemp(), MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE, minivm_zone::name, NULL, out, minivm_account::pager, PATH_MAX, prep_email_sub_vars(), RAII_VAR, minivm_account::serveremail, minivm_zone::timezone, tmp(), minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.

Referenced by notify_new_message().

1235 {
1236  RAII_VAR(struct ast_str *, str1, ast_str_create(16), ast_free);
1237  RAII_VAR(struct ast_str *, str2, ast_str_create(16), ast_free);
1238  FILE *p = NULL;
1239  int pfd;
1240  char email[256] = "";
1241  char who[256] = "";
1242  char date[256];
1243  char bound[256];
1244  char fname[PATH_MAX];
1245  char dur[PATH_MAX];
1246  char tmp[80] = "/tmp/astmail-XXXXXX";
1247  char mail_cmd_buffer[PATH_MAX];
1248  char sox_gain_tmpdir[PATH_MAX] = ""; /* Only used with volgain */
1249  char *file_to_delete = NULL, *dir_to_delete = NULL;
1250  struct timeval now;
1251  struct ast_tm tm;
1252  struct minivm_zone *the_zone = NULL;
1253  struct ast_channel *chan = NULL;
1254  char *fromaddress;
1255  char *fromemail;
1256  int res = -1;
1257 
1258  if (!str1 || !str2) {
1259  return -1;
1260  }
1261 
1262  if (type == MVM_MESSAGE_EMAIL) {
1263  if (vmu && !ast_strlen_zero(vmu->email)) {
1264  ast_copy_string(email, vmu->email, sizeof(email));
1265  } else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain))
1266  snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain);
1267  } else if (type == MVM_MESSAGE_PAGE) {
1268  ast_copy_string(email, vmu->pager, sizeof(email));
1269  }
1270 
1271  if (ast_strlen_zero(email)) {
1272  ast_log(LOG_WARNING, "No address to send message to.\n");
1273  return -1;
1274  }
1275 
1276  ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name);
1277 
1278  if (!strcmp(format, "wav49"))
1279  format = "WAV";
1280 
1281  /* If we have a gain option, process it now with sox */
1282  if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) {
1283  char sox_gain_cmd[PATH_MAX];
1284 
1285  ast_copy_string(sox_gain_tmpdir, "/tmp/minivm-gain-XXXXXX", sizeof(sox_gain_tmpdir));
1286  ast_debug(3, "sox_gain_tmpdir: %s\n", sox_gain_tmpdir);
1287  if (!mkdtemp(sox_gain_tmpdir)) {
1288  ast_log(LOG_WARNING, "Failed to create temporary directory for volgain: %d\n", errno);
1289  return -1;
1290  }
1291  snprintf(fname, sizeof(fname), "%s/output.%s", sox_gain_tmpdir, format);
1292  snprintf(sox_gain_cmd, sizeof(sox_gain_cmd), "sox -v %.4f %s.%s %s", vmu->volgain, filename, format, fname);
1293  ast_safe_system(sox_gain_cmd);
1294  ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username);
1295 
1296  /* Mark some things for deletion */
1297  file_to_delete = fname;
1298  dir_to_delete = sox_gain_tmpdir;
1299  } else {
1300  snprintf(fname, sizeof(fname), "%s.%s", filename, format);
1301  }
1302 
1303  if (template->attachment)
1304  ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", fname, format, attach_user_voicemail);
1305 
1306  /* Make a temporary file instead of piping directly to sendmail, in case the mail
1307  command hangs */
1308  pfd = mkstemp(tmp);
1309  if (pfd > -1) {
1310  p = fdopen(pfd, "w");
1311  if (!p) {
1312  close(pfd);
1313  pfd = -1;
1314  }
1315  ast_debug(1, "Opening temp file for e-mail: %s\n", tmp);
1316  }
1317  if (!p) {
1318  ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp);
1319  goto out;
1320  }
1321  /* Allocate channel used for chanvar substitution */
1322  chan = ast_dummy_channel_alloc();
1323  if (!chan) {
1324  goto out;
1325  }
1326 
1327  snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
1328 
1329  /* Does this user have a timezone specified? */
1330  if (!ast_strlen_zero(vmu->zonetag)) {
1331  /* Find the zone in the list */
1332  struct minivm_zone *z;
1335  if (strcmp(z->name, vmu->zonetag))
1336  continue;
1337  the_zone = z;
1338  }
1340  }
1341 
1342  now = ast_tvnow();
1343  ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL);
1344  ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm);
1345 
1346  /* Start printing the email to the temporary file */
1347  fprintf(p, "Date: %s\n", date);
1348 
1349  /* Set date format for voicemail mail */
1350  ast_strftime(date, sizeof(date), template->dateformat, &tm);
1351 
1352  /* Populate channel with channel variables for substitution */
1353  prep_email_sub_vars(chan, vmu, cidnum, cidname, dur, date, counter);
1354 
1355  /* Find email address to use */
1356  /* If there's a server e-mail address in the account, use that, otherwise template */
1357  fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail;
1358 
1359  /* Find name to user for server e-mail */
1360  fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress;
1361 
1362  /* If needed, add hostname as domain */
1363  if (ast_strlen_zero(fromemail))
1364  fromemail = "asterisk";
1365 
1366  if (strchr(fromemail, '@'))
1367  ast_copy_string(who, fromemail, sizeof(who));
1368  else {
1369  char host[MAXHOSTNAMELEN];
1370  gethostname(host, sizeof(host)-1);
1371  snprintf(who, sizeof(who), "%s@%s", fromemail, host);
1372  }
1373 
1374  if (ast_strlen_zero(fromaddress)) {
1375  fprintf(p, "From: Asterisk PBX <%s>\n", who);
1376  } else {
1377  ast_debug(4, "Fromaddress template: %s\n", fromaddress);
1378  ast_str_substitute_variables(&str1, 0, chan, fromaddress);
1379  if (check_mime(ast_str_buffer(str1))) {
1380  int first_line = 1;
1381  char *ptr;
1382  ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3);
1383  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
1384  *ptr = '\0';
1385  fprintf(p, "%s %s\n", first_line ? "From:" : "", ast_str_buffer(str2));
1386  first_line = 0;
1387  /* Substring is smaller, so this will never grow */
1388  ast_str_set(&str2, 0, "%s", ptr + 1);
1389  }
1390  fprintf(p, "%s %s <%s>\n", first_line ? "From:" : "", ast_str_buffer(str2), who);
1391  } else {
1392  fprintf(p, "From: %s <%s>\n", ast_str_quote(&str2, 0, ast_str_buffer(str1)), who);
1393  }
1394  }
1395 
1396  fprintf(p, "Message-ID: <Asterisk-%u-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who);
1397 
1398  if (ast_strlen_zero(vmu->email)) {
1399  snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain);
1400  } else {
1401  ast_copy_string(email, vmu->email, sizeof(email));
1402  }
1403 
1404  if (check_mime(vmu->fullname)) {
1405  int first_line = 1;
1406  char *ptr;
1407  ast_str_encode_mime(&str2, 0, template->charset, vmu->fullname, strlen("To: "), strlen(email) + 3);
1408  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
1409  *ptr = '\0';
1410  fprintf(p, "%s %s\n", first_line ? "To:" : "", ast_str_buffer(str2));
1411  first_line = 0;
1412  /* Substring is smaller, so this will never grow */
1413  ast_str_set(&str2, 0, "%s", ptr + 1);
1414  }
1415  fprintf(p, "%s %s <%s>\n", first_line ? "To:" : "", ast_str_buffer(str2), email);
1416  } else {
1417  fprintf(p, "To: %s <%s>\n", ast_str_quote(&str2, 0, vmu->fullname), email);
1418  }
1419 
1420  if (!ast_strlen_zero(template->subject)) {
1421  ast_str_substitute_variables(&str1, 0, chan, template->subject);
1422  if (check_mime(ast_str_buffer(str1))) {
1423  int first_line = 1;
1424  char *ptr;
1425  ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("Subject: "), 0);
1426  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
1427  *ptr = '\0';
1428  fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2));
1429  first_line = 0;
1430  /* Substring is smaller, so this will never grow */
1431  ast_str_set(&str2, 0, "%s", ptr + 1);
1432  }
1433  fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2));
1434  } else {
1435  fprintf(p, "Subject: %s\n", ast_str_buffer(str1));
1436  }
1437  } else {
1438  fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain);
1439  ast_debug(1, "Using default subject for this email \n");
1440  }
1441 
1442  if (DEBUG_ATLEAST(3))
1443  fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain);
1444  fprintf(p, "MIME-Version: 1.0\n");
1445 
1446  /* Something unique. */
1447  snprintf(bound, sizeof(bound), "voicemail_%s%d%u", vmu->username, (int)getpid(), (unsigned int)ast_random());
1448 
1449  fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound);
1450 
1451  fprintf(p, "--%s\n", bound);
1452  fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", template->charset);
1453  if (!ast_strlen_zero(template->body)) {
1454  ast_str_substitute_variables(&str1, 0, chan, template->body);
1455  ast_debug(3, "Message now: %s\n-----\n", ast_str_buffer(str1));
1456  fprintf(p, "%s\n", ast_str_buffer(str1));
1457  } else {
1458  fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n"
1459  "in mailbox %s from %s, on %s so you might\n"
1460  "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname,
1461  dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
1462  ast_debug(3, "Using default message body (no template)\n-----\n");
1463  }
1464  /* Eww. We want formats to tell us their own MIME type */
1465  if (template->attachment) {
1466  char *ctype = "audio/x-";
1467  ast_debug(3, "Attaching file to message: %s\n", fname);
1468  if (!strcasecmp(format, "ogg"))
1469  ctype = "application/";
1470 
1471  fprintf(p, "--%s\n", bound);
1472  fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format);
1473  fprintf(p, "Content-Transfer-Encoding: base64\n");
1474  fprintf(p, "Content-Description: Voicemail sound attachment.\n");
1475  fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format);
1476 
1477  base_encode(fname, p);
1478  fprintf(p, "\n\n--%s--\n.\n", bound);
1479  }
1480  fclose(p);
1481 
1482  chan = ast_channel_unref(chan);
1483 
1484  if (file_to_delete && dir_to_delete) {
1485  /* We can't delete these files ourselves because the mail command will execute in
1486  the background and we'll end up deleting them out from under it. */
1487  res = snprintf(mail_cmd_buffer, sizeof(mail_cmd_buffer),
1488  "( %s < %s ; rm -f %s %s ; rmdir %s ) &",
1489  global_mailcmd, tmp, tmp, file_to_delete, dir_to_delete);
1490  } else {
1491  res = snprintf(mail_cmd_buffer, sizeof(mail_cmd_buffer),
1492  "( %s < %s ; rm -f %s ) &",
1493  global_mailcmd, tmp, tmp);
1494  }
1495 
1496  if (res < sizeof(mail_cmd_buffer)) {
1497  file_to_delete = dir_to_delete = NULL;
1498  } else {
1499  ast_log(LOG_ERROR, "Could not send message, command line too long\n");
1500  res = -1;
1501  goto out;
1502  }
1503 
1504  ast_safe_system(mail_cmd_buffer);
1505  ast_debug(1, "Sent message to %s with command '%s'%s\n", vmu->email, global_mailcmd, template->attachment ? " - (media attachment)" : "");
1506  ast_debug(3, "Actual command used: %s\n", mail_cmd_buffer);
1507 
1508  res = 0;
1509 
1510 out:
1511  if (file_to_delete) {
1512  unlink(file_to_delete);
1513  }
1514 
1515  if (dir_to_delete) {
1516  rmdir(dir_to_delete);
1517  }
1518 
1519  return res;
1520 }
static const char type[]
Definition: chan_ooh323.c:109
Main Channel structure associated with a channel.
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char name[80]
Definition: app_minivm.c:666
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define LOG_WARNING
Definition: logger.h:274
#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:714
static int tmp()
Definition: bt_open.c:389
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:1739
static char email[80]
Definition: pbx_dundi.c:206
char username[AST_MAX_CONTEXT]
Definition: app_minivm.c:601
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define MAXHOSTNAMELEN
Definition: network.h:69
static char global_mailcmd[160]
Definition: app_minivm.c:699
static int base_encode(char *filename, FILE *so)
Definition: app_minivm.c:905
#define NULL
Definition: resample.c:96
char domain[AST_MAX_CONTEXT]
Definition: app_minivm.c:602
char subject[100]
Definition: app_minivm.c:638
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:1065
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static char host[256]
Definition: muted.c:77
char email[80]
Definition: app_minivm.c:606
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
struct minivm_zone::@56 list
long int ast_random(void)
Definition: main/utils.c:2064
char zonetag[80]
Definition: app_minivm.c:612
char timezone[80]
Definition: app_minivm.c:667
static const char * ast_str_quote(struct ast_str **buf, ssize_t maxlen, const char *from)
Definition: app_minivm.c:1214
double volgain
Definition: app_minivm.c:620
#define LOG_ERROR
Definition: logger.h:285
static int check_mime(const char *str)
Definition: app_minivm.c:1144
char name[80]
Definition: app_minivm.c:634
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
int ast_safe_system(const char *s)
Safely spawn an OS shell command while closing file descriptors.
Definition: extconf.c:829
char * mkdtemp(char *template_s)
int errno
Voicemail time zones.
Definition: app_minivm.c:665
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
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:2524
The list of e-mail time zones.
Definition: app_minivm.c:673
char charset[32]
Definition: app_minivm.c:639
char fullname[120]
Definition: app_minivm.c:605
FILE * out
Definition: utils/frame.c:33
char pager[80]
Definition: app_minivm.c:607
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define PATH_MAX
Definition: asterisk.h:40
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:1173
char fromaddress[100]
Definition: app_minivm.c:636
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
static snd_pcm_format_t format
Definition: chan_alsa.c:102
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:1002
char dateformat[80]
Definition: app_minivm.c:641
char serveremail[80]
Definition: app_minivm.c:609
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ timezone_add()

static int timezone_add ( const char *  zonename,
const char *  config 
)
static

Add time zone to memory list.

Definition at line 2707 of file app_minivm.c.

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

Referenced by load_config().

2708 {
2709  struct minivm_zone *newzone;
2710  char *msg_format, *timezone_str;
2711 
2712  newzone = ast_calloc(1, sizeof(*newzone));
2713  if (newzone == NULL)
2714  return 0;
2715 
2716  msg_format = ast_strdupa(config);
2717 
2718  timezone_str = strsep(&msg_format, "|");
2719  if (!msg_format) {
2720  ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename);
2721  ast_free(newzone);
2722  return 0;
2723  }
2724 
2725  ast_copy_string(newzone->name, zonename, sizeof(newzone->name));
2726  ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone));
2727  ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format));
2728 
2732 
2734 
2735  return 0;
2736 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char name[80]
Definition: app_minivm.c:666
char * config
Definition: conf2ael.c:66
#define LOG_WARNING
Definition: logger.h:274
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define NULL
Definition: resample.c:96
static struct minivm_stats global_stats
Statistics for voicemail.
Definition: app_minivm.c:687
#define ast_log
Definition: astobj2.c:42
struct minivm_zone::@56 list
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char timezone[80]
Definition: app_minivm.c:667
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
char msg_format[BUFSIZ]
Definition: app_minivm.c:668
Voicemail time zones.
Definition: app_minivm.c:665
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
The list of e-mail time zones.
Definition: app_minivm.c:673
char * strsep(char **str, const char *delims)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ timezone_destroy_list()

static void timezone_destroy_list ( void  )
static

Clear list of timezones.

Definition at line 2695 of file app_minivm.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and minivm_account::list.

Referenced by load_config(), and unload_module().

2696 {
2697  struct minivm_zone *this;
2698 
2700  while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list)))
2701  free_zone(this);
2702 
2704 }
#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:2689
struct minivm_zone::@56 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
Voicemail time zones.
Definition: app_minivm.c:665
The list of e-mail time zones.
Definition: app_minivm.c:673

◆ unload_module()

static int unload_module ( void  )
static

Unload mini voicemail module.

Definition at line 3571 of file app_minivm.c.

References app_minivm_accmess, app_minivm_delete, app_minivm_greet, app_minivm_mwi, app_minivm_notify, app_minivm_record, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_SUPPORT_EXTENDED, ast_unregister_application(), ASTERISK_GPL_KEY, load_module(), message_destroy_list(), reload(), timezone_destroy_list(), and vmaccounts_destroy_list().

3572 {
3573  int res;
3574 
3581 
3585 
3586  message_destroy_list(); /* Destroy list of voicemail message templates */
3587  timezone_destroy_list(); /* Destroy list of timezones */
3588  vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */
3589 
3590  return res;
3591 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_custom_function minivm_counter_function
Definition: app_minivm.c:3505
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static char * app_minivm_notify
Definition: app_minivm.c:563
static void vmaccounts_destroy_list(void)
Definition: app_minivm.c:1055
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static void timezone_destroy_list(void)
Clear list of timezones.
Definition: app_minivm.c:2695
static char * app_minivm_record
Definition: app_minivm.c:561
static struct ast_cli_entry cli_minivm[]
CLI commands for Mini-voicemail.
Definition: app_minivm.c:3496
static char * app_minivm_mwi
Definition: app_minivm.c:566
static char * app_minivm_accmess
Definition: app_minivm.c:565
static char * app_minivm_greet
Definition: app_minivm.c:562
static void message_destroy_list(void)
Definition: app_minivm.c:838
static char * app_minivm_delete
Definition: app_minivm.c:564
static struct ast_custom_function minivm_account_function
Definition: app_minivm.c:3511

◆ vm_delete()

static int vm_delete ( char *  file)
static

Definition at line 1630 of file app_minivm.c.

References ast_debug, ast_filedelete(), and NULL.

Referenced by minivm_delete_exec(), and play_record_review().

1631 {
1632  int res;
1633 
1634  ast_debug(1, "Deleting voicemail file %s\n", file);
1635 
1636  res = unlink(file); /* Remove the meta data file */
1637  res |= ast_filedelete(file, NULL); /* remove the media file */
1638  return res;
1639 }
#define NULL
Definition: resample.c:96
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:1098
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452

◆ vm_lock_path()

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

References ast_lock_path(), and AST_LOCK_TIMEOUT.

Referenced by access_counter_file().

3303 {
3304  switch (ast_lock_path(path)) {
3305  case AST_LOCK_TIMEOUT:
3306  return -1;
3307  default:
3308  return 0;
3309  }
3310 }
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Definition: main/app.c:2457

◆ vmaccounts_destroy_list()

static void vmaccounts_destroy_list ( void  )
static

Definition at line 1055 of file app_minivm.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and minivm_account::list.

Referenced by load_config(), and unload_module().

1056 {
1057  struct minivm_account *this;
1059  while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list)))
1060  ast_free(this);
1062 }
#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_account::@54 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_free(a)
Definition: astmm.h:182

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, }
static

Definition at line 3599 of file app_minivm.c.

◆ app_minivm_accmess

char* app_minivm_accmess = "MinivmAccMess"
static

Definition at line 565 of file app_minivm.c.

Referenced by load_module(), and unload_module().

◆ app_minivm_delete

char* app_minivm_delete = "MinivmDelete"
static

Definition at line 564 of file app_minivm.c.

Referenced by load_module(), and unload_module().

◆ app_minivm_greet

char* app_minivm_greet = "MinivmGreet"
static

Definition at line 562 of file app_minivm.c.

Referenced by load_module(), and unload_module().

◆ app_minivm_mwi

char* app_minivm_mwi = "MinivmMWI"
static

Definition at line 566 of file app_minivm.c.

Referenced by load_module(), and unload_module().

◆ app_minivm_notify

char* app_minivm_notify = "MinivmNotify"
static

Definition at line 563 of file app_minivm.c.

Referenced by load_module(), and unload_module().

◆ app_minivm_record

char* app_minivm_record = "MinivmRecord"
static

Definition at line 561 of file app_minivm.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 3599 of file app_minivm.c.

◆ cli_minivm

struct ast_cli_entry cli_minivm[]
static

CLI commands for Mini-voicemail.

Definition at line 3496 of file app_minivm.c.

◆ default_vmformat

char default_vmformat[80]
static

Definition at line 702 of file app_minivm.c.

◆ global_externnotify

char global_externnotify[160]
static

External notification application

Definition at line 700 of file app_minivm.c.

Referenced by run_externnotify().

◆ global_logfile

char global_logfile[PATH_MAX]
static

Global log file for messages

Definition at line 701 of file app_minivm.c.

◆ global_mailcmd

char global_mailcmd[160]
static

Configurable mail cmd

Definition at line 699 of file app_minivm.c.

◆ global_maxgreet

int global_maxgreet
static

Maximum length of prompts

Definition at line 697 of file app_minivm.c.

◆ global_maxsilence

int global_maxsilence
static

Maximum silence during recording

Examples:
/usr/src/asterisk-18.5.0/main/app.c.

Definition at line 696 of file app_minivm.c.

◆ global_saydurationminfo

int global_saydurationminfo
static

Definition at line 705 of file app_minivm.c.

◆ global_silencethreshold

int global_silencethreshold = 128
static

Definition at line 698 of file app_minivm.c.

◆ global_stats

struct minivm_stats global_stats
static

Statistics for voicemail.

Definition at line 687 of file app_minivm.c.

Referenced by create_vmaccount(), handle_minivm_show_stats(), leave_voicemail(), load_config(), message_template_build(), and timezone_add().

◆ global_vmmaxmessage

int global_vmmaxmessage
static

Maximum duration of message

Definition at line 695 of file app_minivm.c.

◆ global_vmminmessage

int global_vmminmessage
static

Minimum duration of messages

Definition at line 694 of file app_minivm.c.

◆ global_volgain

double global_volgain
static

Volume gain for voicmemail via e-mail

Definition at line 707 of file app_minivm.c.

Referenced by populate_defaults().

◆ globalflags

struct ast_flags globalflags = {0}
static

Global voicemail flags

Definition at line 704 of file app_minivm.c.

◆ message_templates

struct message_templates message_templates = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ minivm_accmess_options

const struct ast_app_option minivm_accmess_options[128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING }, }
static

Definition at line 596 of file app_minivm.c.

Referenced by minivm_accmess_exec().

◆ minivm_account_function

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

Definition at line 3511 of file app_minivm.c.

◆ minivm_accounts

struct minivm_accounts minivm_accounts = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ minivm_app_options

const struct ast_app_option minivm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, }
static

Definition at line 589 of file app_minivm.c.

Referenced by minivm_greet_exec(), and minivm_record_exec().

◆ minivm_counter_function

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:3372
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:3425

Definition at line 3505 of file app_minivm.c.

◆ minivm_zones

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

◆ minivmlock

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

Lock to protect voicemail system

Definition at line 689 of file app_minivm.c.

Referenced by load_config().

◆ minivmlogfile

FILE* minivmlogfile
static

The minivm log file

Definition at line 692 of file app_minivm.c.

◆ minivmloglock

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

Lock to protect voicemail system log file

Definition at line 690 of file app_minivm.c.

Referenced by leave_voicemail().

◆ MVM_SPOOL_DIR

char MVM_SPOOL_DIR[PATH_MAX]
static