Wed Jan 8 2020 09:49:56

Asterisk developer's documentation


app_voicemail_odbcstorage.c File Reference

Comedian Mail - Voicemail System. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include "asterisk/logger.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/adsi.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/stringfields.h"
#include "asterisk/smdi.h"
#include "asterisk/astobj2.h"
#include "asterisk/event.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"

Go to the source code of this file.

Data Structures

struct  ast_vm_user
 
struct  baseio
 
struct  inprocess
 
struct  leave_vm_options
 Options for leaving voicemail with the voicemail() application. More...
 
struct  mwi_sub
 An MWI subscription. More...
 
struct  mwi_sub_task
 
struct  mwi_subs
 
struct  users
 list of users found in the config file More...
 
struct  vm_state
 
struct  vm_zone
 
struct  zones
 

Macros

#define ASTERISK_USERNAME   "asterisk"
 
#define BASELINELEN   72
 
#define BASEMAXINLINE   256
 
#define CHUNKSIZE   65536
 
#define COMMAND_TIMEOUT   5000
 
#define COPY(a, b, c, d, e, f, g, h)   (copy_plain_file(g,h));
 
#define DATA_EXPORT_VM_USERS(USER)
 
#define DATA_EXPORT_VM_ZONES(ZONE)
 
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY   "#"
 
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY   "0"
 
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY   "2"
 
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY   "*"
 
#define DEFAULT_LISTEN_CONTROL_STOP_KEY   "13456789"
 
#define DEFAULT_POLL_FREQ   30
 
#define DELETE(a, b, c, d)   (vm_delete(c))
 
#define DISPOSE(a, b)
 
#define ENDL   "\n"
 
#define ERROR_LOCK_PATH   -100
 
#define EXISTS(a, b, c, d)   (ast_fileexists(c,NULL,d) > 0)
 
#define HVSU_OUTPUT_FORMAT   "%-10s %-5s %-25s %-10s %6s\n"
 
#define HVSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"
 
#define INTRO   "vm-intro"
 
#define MAX_DATETIME_FORMAT   512
 
#define MAX_NUM_CID_CONTEXTS   10
 
#define MAXMSG   100
 
#define MAXMSGLIMIT   9999
 
#define MINPASSWORD   0
 
#define OPERATOR_EXIT   300
 
#define PWDCHANGE_EXTERNAL   (1 << 2)
 
#define PWDCHANGE_INTERNAL   (1 << 1)
 
#define RENAME(a, b, c, d, e, f, g, h)   (rename_file(g,h));
 
#define RETRIEVE(a, b, c, d)
 
#define SENDMAIL   "/usr/sbin/sendmail -t"
 
#define SMDI_MWI_WAIT_TIMEOUT   1000 /* 1 second */
 
#define STORE(a, b, c, d, e, f, g, h, i, j)
 
#define tdesc   "Comedian Mail (Voicemail System)"
 
#define VALID_DTMF   "1234567890*#" /* Yes ABCD are valid dtmf but what phones have those? */
 
#define VM_ALLOCED   (1 << 13)
 
#define VM_ATTACH   (1 << 11)
 
#define VM_DELETE   (1 << 12)
 
#define VM_DIRECFORWARD   (1 << 10)
 
#define VM_ENVELOPE   (1 << 4)
 
#define VM_FORCEGREET   (1 << 8)
 
#define VM_FORCENAME   (1 << 7)
 
#define VM_FWDURGAUTO   (1 << 18)
 
#define VM_MESSAGEWRAP   (1 << 17)
 
#define VM_MOVEHEARD   (1 << 16)
 
#define VM_OPERATOR   (1 << 1)
 
#define VM_PBXSKIP   (1 << 9)
 
#define VM_REVIEW   (1 << 0)
 
#define VM_SAYCID   (1 << 2)
 
#define VM_SAYDURATION   (1 << 5)
 
#define VM_SEARCH   (1 << 14)
 
#define VM_SKIPAFTERCMD   (1 << 6)
 
#define VM_SVMAIL   (1 << 3)
 
#define VM_TEMPGREETWARN   (1 << 15)
 
#define VMSTATE_MAX_MSG_ARRAY   256
 
#define VOICEMAIL_CONFIG   "voicemail.conf"
 
#define VOICEMAIL_DIR_MODE   0777
 
#define VOICEMAIL_FILE_MODE   0666
 

Enumerations

enum  vm_box {
  NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER,
  FRIENDS_FOLDER, GREETINGS_FOLDER, NEW_FOLDER, OLD_FOLDER,
  WORK_FOLDER, FAMILY_FOLDER, FRIENDS_FOLDER, GREETINGS_FOLDER,
  NEW_FOLDER, OLD_FOLDER, WORK_FOLDER, FAMILY_FOLDER,
  FRIENDS_FOLDER, GREETINGS_FOLDER
}
 
enum  vm_option_args {
  OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3,
  OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3,
  OPT_ARG_RECORDGAIN = 0, OPT_ARG_PLAYFOLDER = 1, OPT_ARG_DTMFEXIT = 2, OPT_ARG_ARRAY_SIZE = 3
}
 
enum  vm_option_flags {
  OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3),
  OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8),
  OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2),
  OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6), OPT_DTMFEXIT = (1 << 7),
  OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9), OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1),
  OPT_UNAVAIL_GREETING = (1 << 2), OPT_RECORDGAIN = (1 << 3), OPT_PREPEND_MAILBOX = (1 << 4), OPT_AUTOPLAY = (1 << 6),
  OPT_DTMFEXIT = (1 << 7), OPT_MESSAGE_Urgent = (1 << 8), OPT_MESSAGE_PRIORITY = (1 << 9)
}
 
enum  vm_passwordlocation {
  OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0,
  OPT_PWLOC_SPOOLDIR = 1, OPT_PWLOC_USERSCONF = 2, OPT_PWLOC_VOICEMAILCONF = 0, OPT_PWLOC_SPOOLDIR = 1,
  OPT_PWLOC_USERSCONF = 2
}
 

Functions

static int __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static int acf_mailbox_exists (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len)
 
static int actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg)
 
static int add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum)
 
static void adsi_begin (struct ast_channel *chan, int *useadsi)
 
static void adsi_delete (struct ast_channel *chan, struct vm_state *vms)
 
static void adsi_folders (struct ast_channel *chan, int start, char *label)
 
static void adsi_goodbye (struct ast_channel *chan)
 
static int adsi_load_vmail (struct ast_channel *chan, int *useadsi)
 
static void adsi_login (struct ast_channel *chan)
 
static int adsi_logo (unsigned char *buf)
 
static void adsi_message (struct ast_channel *chan, struct vm_state *vms)
 
static void adsi_password (struct ast_channel *chan)
 
static void adsi_status (struct ast_channel *chan, struct vm_state *vms)
 
static void adsi_status2 (struct ast_channel *chan, struct vm_state *vms)
 
static int advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
 The advanced options within a message. More...
 
static int append_mailbox (const char *context, const char *box, const char *data)
 
static void apply_option (struct ast_vm_user *vmu, const char *var, const char *value)
 Sets a a specific property value. More...
 
static void apply_options (struct ast_vm_user *vmu, const char *options)
 Destructively Parse options and apply. More...
 
static void apply_options_full (struct ast_vm_user *retval, struct ast_variable *var)
 Loads the options specific to a voicemail user. More...
 
 AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS)
 
 AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES)
 
static const char * ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble)
 Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. More...
 
static const char * ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from)
 Wraps a character sequence in double quotes, escaping occurences of quotes within the string. More...
 
 AST_TEST_DEFINE (test_voicemail_vmuser)
 
static int base_encode (char *filename, FILE *so)
 Performs a base 64 encode algorithm on the contents of a File. More...
 
static int change_password_realtime (struct ast_vm_user *vmu, const char *password)
 Performs a change of the voicemail passowrd in the realtime engine. More...
 
static int check_mime (const char *str)
 Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. More...
 
static int check_password (struct ast_vm_user *vmu, char *password)
 Check that password meets minimum required length. More...
 
static int close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu)
 
static char * complete_voicemail_show_users (const char *line, const char *word, int pos, int state)
 
static int copy (char *infile, char *outfile)
 Utility function to copy a file. More...
 
static int copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag)
 Copies a message from one mailbox to another. More...
 
static void copy_plain_file (char *frompath, char *topath)
 Copies a voicemail information (envelope) file. More...
 
static int count_messages (struct ast_vm_user *vmu, char *dir)
 Find all .txt files - even if they are not in sequence from 0000. More...
 
static int create_dirpath (char *dest, int len, const char *context, const char *ext, const char *folder)
 basically mkdir -p $dest/$context/$ext/$folder More...
 
static int dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
 
static struct ast_vm_userfind_or_create (const char *context, const char *box)
 
static struct ast_vm_userfind_user (struct ast_vm_user *ivm, const char *context, const char *mailbox)
 Finds a voicemail user from the users file or the realtime engine. More...
 
static struct ast_vm_userfind_user_realtime (struct ast_vm_user *ivm, const char *context, const char *mailbox)
 Finds a voicemail user from the realtime engine. More...
 
static int forward_message (struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent)
 Sends a voicemail message to a mailbox recipient. More...
 
static void free_user (struct ast_vm_user *vmu)
 
static void free_vm_users (void)
 Free the users structure. More...
 
static void free_vm_zones (void)
 Free the zones structure. More...
 
static void free_zone (struct vm_zone *z)
 
static int get_date (char *s, int len)
 Gets the current date and time, as formatted string. More...
 
static int get_folder (struct ast_channel *chan, int start)
 get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized More...
 
static int get_folder2 (struct ast_channel *chan, char *fn, int start)
 plays a prompt and waits for a keypress. More...
 
static int get_folder_by_name (const char *name)
 
static int handle_subscribe (void *datap)
 
static int handle_unsubscribe (void *datap)
 
static char * handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Reload voicemail configuration from the CLI. More...
 
static char * handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show a list of voicemail users in the CLI. More...
 
static char * handle_voicemail_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 has_voicemail (const char *mailbox, const char *folder)
 Determines if the given folder has messages. More...
 
static int inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs)
 
static int inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
 
static int inbuf (struct baseio *bio, FILE *fi)
 utility used by inchar(), for base_encode() More...
 
static int inchar (struct baseio *bio, FILE *fi)
 utility used by base_encode() More...
 
static int inprocess_cmp_fn (void *obj, void *arg, int flags)
 
static int inprocess_count (const char *context, const char *mailbox, int delta)
 
static int inprocess_hash_fn (const void *obj, const int flags)
 
static int invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
 
static int is_valid_dtmf (const char *key)
 Determines if a DTMF key entered is valid. More...
 
static int last_message_index (struct ast_vm_user *vmu, char *dir)
 Determines the highest message number in use for a given user and mailbox folder. More...
 
static int leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options)
 Prompts the user and records a voicemail to a mailbox. More...
 
static int load_config (int reload)
 
static int load_module (void)
 
static int make_dir (char *dest, int len, const char *context, const char *ext, const char *folder)
 Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. More...
 
static void make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag)
 Creates the email file to be sent to indicate a new voicemail exists for a user. More...
 
static int make_file (char *dest, const int len, const char *dir, const int num)
 Creates a file system path expression for a folder within the voicemail data folder and the appropriate context. More...
 
static int manager_list_voicemail_users (struct mansession *s, const struct message *m)
 Manager list voicemail users command. More...
 
static void * mb_poll_thread (void *data)
 
static const char * mbox (struct ast_vm_user *vmu, int id)
 
static int messagecount (const char *context, const char *mailbox, const char *folder)
 
static void mwi_sub_destroy (struct mwi_sub *mwi_sub)
 
static void mwi_sub_event_cb (const struct ast_event *event, void *userdata)
 
static void mwi_unsub_event_cb (const struct ast_event *event, void *userdata)
 
static int notify_new_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag)
 Sends email notification that a user has a new voicemail waiting for them. More...
 
static int ochar (struct baseio *bio, int c, FILE *so)
 utility used by base_encode() More...
 
static int open_mailbox (struct vm_state *vms, struct ast_vm_user *vmu, int box)
 
static int play_message (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
 
static int play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
 
static int play_message_category (struct ast_channel *chan, const char *category)
 
static int play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
 
static int play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
 
static int play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag)
 
static void poll_subscribed_mailbox (struct mwi_sub *mwi_sub)
 
static void poll_subscribed_mailboxes (void)
 
static void populate_defaults (struct ast_vm_user *vmu)
 Sets default voicemail system options to a voicemail user. More...
 
static void prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag)
 
static void queue_mwi_event (const char *box, int urgent, int new, int old)
 
static void read_password_from_file (const char *secretfn, char *password, int passwordlen)
 
static int reload (void)
 
static void rename_file (char *sfn, char *dfn)
 Renames a message in a mailbox folder. More...
 
static int resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount)
 
static int reset_user_pw (const char *context, const char *mailbox, const char *newpass)
 Resets a user password to a specified password. More...
 
static void run_externnotify (char *context, char *extension, const char *flag)
 
static int save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
 
static int say_and_wait (struct ast_channel *chan, int num, const char *language)
 
static int sayname (struct ast_channel *chan, const char *mailbox, const char *context)
 
static int sendmail (char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag)
 
static int sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag)
 
static char * show_users_realtime (int fd, const char *context)
 
static void start_poll_thread (void)
 
static void stop_poll_thread (void)
 
static char * strip_control_and_high (const char *input, char *buf, size_t buflen)
 Strips control and non 7-bit clean characters from input string. More...
 
static const char * substitute_escapes (const char *value)
 
static int unload_module (void)
 
static int valid_config (const struct ast_config *cfg)
 Check if configuration file is valid. More...
 
static int vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg)
 
static int vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent)
 
static int vm_box_exists (struct ast_channel *chan, const char *data)
 
static int vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
 Top level method to invoke the language variant vm_browse_messages_XX function. More...
 
static int vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
 Default English syntax for 'You have N messages' greeting. More...
 
static int vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
 
static int vm_browse_messages_latin (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
 Common LATIN languages syntax for 'You have N messages' greeting. More...
 
static int vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
 Vietnamese syntax for 'You have N messages' greeting. More...
 
static int vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
 Chinese (Taiwan)syntax for 'You have N messages' greeting. More...
 
static void vm_change_password (struct ast_vm_user *vmu, const char *newpassword)
 The handler for the change password option. More...
 
static void vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword)
 
static char * vm_check_password_shell (char *command, char *buf, size_t len)
 
static int vm_delete (char *file)
 Removes the voicemail sound and information file. More...
 
static int vm_exec (struct ast_channel *chan, const char *data)
 
static int vm_execmain (struct ast_channel *chan, const char *data)
 
static int vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag)
 presents the option to prepend to an existing message when forwarding it. More...
 
static int vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
 
static int vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
 
static int vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
 
static int vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
 
static int vm_intro_cs (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_de (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_en (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_es (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_fr (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_gr (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_he (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_it (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
 
static int vm_intro_nl (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_no (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_pl (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_pt (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_se (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_vi (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_intro_zh (struct ast_channel *chan, struct vm_state *vms)
 
static int vm_lock_path (const char *path)
 Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. More...
 
static FILE * vm_mkftemp (char *template)
 
static int vm_newuser (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
 
static int vm_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
 
static int vm_play_folder_name (struct ast_channel *chan, char *mbox)
 
static int vm_play_folder_name_gr (struct ast_channel *chan, char *box)
 
static int vm_play_folder_name_pl (struct ast_channel *chan, char *box)
 
static int vm_play_folder_name_ua (struct ast_channel *chan, char *box)
 
static int vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
 The handler for 'record a temporary greeting'. More...
 
static int vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root)
 
static int vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user)
 
static int vmauthenticate (struct ast_channel *chan, const char *data)
 
static int vmsayname_exec (struct ast_channel *chan, const char *data)
 
static struct ast_tmvmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm)
 fill in *tm for current time according to the proper timezone, if any. More...
 
static int wait_file (struct ast_channel *chan, struct vm_state *vms, char *file)
 
static int wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file)
 
static int write_password_to_file (const char *secretfn, const char *password)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", }
 
static char * addesc = "Comedian Mail"
 
static unsigned char adsifdn [4] = "\x00\x00\x00\x0F"
 
static unsigned char adsisec [4] = "\x9B\xDB\xF7\xAC"
 
static int adsiver = 1
 
static char * app = "VoiceMail"
 
static char * app2 = "VoiceMailMain"
 
static char * app3 = "MailboxExists"
 
static char * app4 = "VMAuthenticate"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static char callcontext [AST_MAX_CONTEXT] = ""
 
static char charset [32] = "ISO-8859-1"
 
static char cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64]
 
static struct ast_cli_entry cli_voicemail []
 
static char dialcontext [AST_MAX_CONTEXT] = ""
 
static char * emailbody = NULL
 
static char emaildateformat [32] = "%A, %B %d, %Y at %r"
 
static char * emailsubject = NULL
 
static char exitcontext [AST_MAX_CONTEXT] = ""
 
static char ext_pass_check_cmd [128]
 
static char ext_pass_cmd [128]
 
static char externnotify [160]
 
static char fromstring [100]
 
static struct ast_flags globalflags = {0}
 
struct ao2_containerinprocess_container
 
static char listen_control_forward_key [12]
 
static char listen_control_pause_key [12]
 
static char listen_control_restart_key [12]
 
static char listen_control_reverse_key [12]
 
static char listen_control_stop_key [12]
 
static char locale [20]
 
static struct ast_custom_function mailbox_exists_acf
 
static const char *const mailbox_folders []
 
static char mailcmd [160]
 
static int maxdeletedmsg
 
static int maxgreet
 
static int maxlogins
 
static int maxmsg
 
static int maxsilence
 
static int minpassword
 
static struct ast_event_submwi_sub_sub
 
static struct mwi_subs mwi_subs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct ast_taskprocessormwi_subscription_tps
 
static struct ast_event_submwi_unsub_sub
 
static int my_umask
 
static char * pagerbody = NULL
 
static char pagerdateformat [32] = "%A, %B %d, %Y at %r"
 
static char pagerfromstring [100]
 
static char * pagersubject = NULL
 
static int passwordlocation
 
static ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER
 
static unsigned int poll_freq
 
static ast_mutex_t poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static unsigned int poll_mailboxes
 
static pthread_t poll_thread = AST_PTHREADT_NULL
 
static unsigned char poll_thread_run
 
static int pwdchange = PWDCHANGE_INTERNAL
 
static int saydurationminfo
 
static char * sayname_app = "VMSayName"
 
static char serveremail [80]
 
static int silencethreshold = 128
 
static int skipms
 
static struct ast_smdi_interfacesmdi_iface = NULL
 
static struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 
static char userscontext [AST_MAX_EXTENSION] = "default"
 
static struct ast_app_option vm_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 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY } }
 
static struct ast_data_entry vm_data_providers []
 
static char vm_invalid_password [80] = "vm-invalid-password"
 
static char vm_mismatch [80] = "vm-mismatch"
 
static char vm_newpassword [80] = "vm-newpassword"
 
static char vm_passchanged [80] = "vm-passchanged"
 
static char vm_password [80] = "vm-password"
 
static char vm_pls_try_again [80] = "vm-pls-try-again"
 
static char vm_prepend_timeout [80] = "vm-then-pound"
 
static char vm_reenterpassword [80] = "vm-reenterpassword"
 
static char VM_SPOOL_DIR [PATH_MAX]
 
static struct ast_data_handler vm_users_data_provider
 
static char vmfmts [80]
 
static int vmmaxsecs
 
static int vmminsecs
 
static double volgain
 
static struct zones zones = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 
static char zonetag [80]
 

Detailed Description

Comedian Mail - Voicemail System.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
ExtRef:

unixODBC (http://www.unixodbc.org/)

A source distribution of University of Washington's IMAP c-client (http://www.washington.edu/imap/)

See also
Note
For information about voicemail IMAP storage, https://wiki.asterisk.org/wiki/display/AST/IMAP+Voicemail+Storage
This module requires res_adsi to load. This needs to be optional during compilation.
This file is now almost impossible to work with, due to all #ifdefs. Feels like the database code before realtime. Someone - please come up with a plan to clean this up.

Definition in file app_voicemail_odbcstorage.c.

Macro Definition Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 411 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define BASELINELEN   72

Definition at line 434 of file app_voicemail_odbcstorage.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 435 of file app_voicemail_odbcstorage.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 408 of file app_voicemail_odbcstorage.c.

#define COMMAND_TIMEOUT   5000

Definition at line 404 of file app_voicemail_odbcstorage.c.

#define COPY (   a,
  b,
  c,
  d,
  e,
  f,
  g,
 
)    (copy_plain_file(g,h));

Definition at line 722 of file app_voicemail_odbcstorage.c.

Referenced by copy_message(), and save_to_folder().

#define DATA_EXPORT_VM_USERS (   USER)

Definition at line 11277 of file app_voicemail_odbcstorage.c.

#define DATA_EXPORT_VM_ZONES (   ZONE)
Value:
ZONE(vm_zone, timezone, AST_DATA_STRING) \
ZONE(vm_zone, msg_format, AST_DATA_STRING)
static const char name[]

Definition at line 11304 of file app_voicemail_odbcstorage.c.

#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY   "#"

Definition at line 416 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY   "0"

Definition at line 418 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_RESTART_KEY   "2"

Definition at line 419 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY   "*"

Definition at line 417 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_STOP_KEY   "13456789"

Definition at line 420 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define DEFAULT_POLL_FREQ   30

By default, poll every 30 seconds

Definition at line 792 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define DELETE (   a,
  b,
  c,
 
)    (vm_delete(c))
#define ENDL   "\n"
#define ERROR_LOCK_PATH   -100
#define EXISTS (   a,
  b,
  c,
 
)    (ast_fileexists(c,NULL,d) > 0)
#define HVSU_OUTPUT_FORMAT   "%-10s %-5s %-25s %-10s %6s\n"
#define HVSZ_OUTPUT_FORMAT   "%-15s %-20s %-45s\n"
#define INTRO   "vm-intro"
#define MAX_DATETIME_FORMAT   512

Definition at line 442 of file app_voicemail_odbcstorage.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 443 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 429 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), and apply_option().

#define MAXMSGLIMIT   9999
#define MINPASSWORD   0

Default minimum mailbox password length

Definition at line 432 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define OPERATOR_EXIT   300

Definition at line 465 of file app_voicemail_odbcstorage.c.

Referenced by leave_voicemail(), vm_exec(), and vm_execmain().

#define PWDCHANGE_EXTERNAL   (1 << 2)

Definition at line 735 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), vm_newuser(), and vm_options().

#define PWDCHANGE_INTERNAL   (1 << 1)

Definition at line 734 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), vm_newuser(), and vm_options().

#define RENAME (   a,
  b,
  c,
  d,
  e,
  f,
  g,
 
)    (rename_file(g,h));
#define SENDMAIL   "/usr/sbin/sendmail -t"

Definition at line 425 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000 /* 1 second */

Definition at line 402 of file app_voicemail_odbcstorage.c.

Referenced by run_externnotify().

#define STORE (   a,
  b,
  c,
  d,
  e,
  f,
  g,
  h,
  i,
 
)
#define tdesc   "Comedian Mail (Voicemail System)"

Definition at line 744 of file app_voicemail_odbcstorage.c.

#define VALID_DTMF   "1234567890*#" /* Yes ABCD are valid dtmf but what phones have those? */

Definition at line 421 of file app_voicemail_odbcstorage.c.

Referenced by is_valid_dtmf().

#define VM_ALLOCED   (1 << 13)

Structure was malloc'ed, instead of placed in a return (usually static) buffer

Definition at line 458 of file app_voicemail_odbcstorage.c.

Referenced by AST_TEST_DEFINE(), find_user(), find_user_realtime(), free_user(), and free_vm_users().

#define VM_ATTACH   (1 << 11)

Attach message to voicemail notifications?

Definition at line 456 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), forward_message(), manager_list_voicemail_users(), notify_new_message(), and sendmail().

#define VM_DELETE   (1 << 12)

Delete message after sending notification

Definition at line 457 of file app_voicemail_odbcstorage.c.

Referenced by apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and notify_new_message().

#define VM_DIRECFORWARD   (1 << 10)

Permit caller to use the Directory app for selecting to which mailbox to forward a VM

Definition at line 455 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), and forward_message().

#define VM_ENVELOPE   (1 << 4)

Play the envelope information (who-from, time received, etc.)

Definition at line 449 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().

#define VM_FORCEGREET   (1 << 8)

Have new users record their greetings

Definition at line 453 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().

#define VM_FORCENAME   (1 << 7)

Have new users record their name

Definition at line 452 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().

#define VM_FWDURGAUTO   (1 << 18)

Autoset of Urgent flag on forwarded Urgent messages set globally

Definition at line 463 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), and forward_message().

#define VM_MESSAGEWRAP   (1 << 17)

Wrap around from the last message to the first, and vice-versa

Definition at line 462 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_instructions_en().

#define VM_MOVEHEARD   (1 << 16)

Move a "heard" message to Old after listening to it

Definition at line 461 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and close_mailbox().

#define VM_OPERATOR   (1 << 1)

Allow 0 to be pressed to go to 'o' extension

Definition at line 446 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), leave_voicemail(), manager_list_voicemail_users(), and play_record_review().

#define VM_PBXSKIP   (1 << 9)

Skip the [PBX] preamble in the Subject line of emails

Definition at line 454 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), and make_email_file().

#define VM_REVIEW   (1 << 0)

After recording, permit the caller to review the recording before saving

Definition at line 445 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_record_review().

#define VM_SAYCID   (1 << 2)

Repeat the CallerID info during envelope playback

Definition at line 447 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().

#define VM_SAYDURATION   (1 << 5)

Play the length of the message during envelope playback

Definition at line 450 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and play_message().

#define VM_SEARCH   (1 << 14)

Search all contexts for a matching mailbox

Definition at line 459 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), find_or_create(), find_user(), and find_user_realtime().

#define VM_SKIPAFTERCMD   (1 << 6)

After deletion, assume caller wants to go to the next message

Definition at line 451 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().

#define VM_SVMAIL   (1 << 3)

Allow the user to compose a new VM from within VoicemailMain

Definition at line 448 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().

#define VM_TEMPGREETWARN   (1 << 15)

Remind user tempgreeting is set

Definition at line 460 of file app_voicemail_odbcstorage.c.

Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_intro().

#define VMSTATE_MAX_MSG_ARRAY   256

Definition at line 658 of file app_voicemail_odbcstorage.c.

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 410 of file app_voicemail_odbcstorage.c.

Referenced by load_config(), and vm_change_password().

#define VOICEMAIL_DIR_MODE   0777

Definition at line 406 of file app_voicemail_odbcstorage.c.

Referenced by create_dirpath(), and leave_voicemail().

#define VOICEMAIL_FILE_MODE   0666

Enumeration Type Documentation

enum vm_box
Enumerator
NEW_FOLDER 
OLD_FOLDER 
WORK_FOLDER 
FAMILY_FOLDER 
FRIENDS_FOLDER 
GREETINGS_FOLDER 
NEW_FOLDER 
OLD_FOLDER 
WORK_FOLDER 
FAMILY_FOLDER 
FRIENDS_FOLDER 
GREETINGS_FOLDER 
NEW_FOLDER 
OLD_FOLDER 
WORK_FOLDER 
FAMILY_FOLDER 
FRIENDS_FOLDER 
GREETINGS_FOLDER 

Definition at line 468 of file app_voicemail_odbcstorage.c.

Enumerator
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_DTMFEXIT 
OPT_ARG_ARRAY_SIZE 
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_DTMFEXIT 
OPT_ARG_ARRAY_SIZE 
OPT_ARG_RECORDGAIN 
OPT_ARG_PLAYFOLDER 
OPT_ARG_DTMFEXIT 
OPT_ARG_ARRAY_SIZE 

Definition at line 489 of file app_voicemail_odbcstorage.c.

489  {
490  OPT_ARG_RECORDGAIN = 0,
491  OPT_ARG_PLAYFOLDER = 1,
492  OPT_ARG_DTMFEXIT = 2,
493  /* This *must* be the last value in this enum! */
494  OPT_ARG_ARRAY_SIZE = 3,
495 };
Enumerator
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_AUTOPLAY 
OPT_DTMFEXIT 
OPT_MESSAGE_Urgent 
OPT_MESSAGE_PRIORITY 
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_AUTOPLAY 
OPT_DTMFEXIT 
OPT_MESSAGE_Urgent 
OPT_MESSAGE_PRIORITY 
OPT_SILENT 
OPT_BUSY_GREETING 
OPT_UNAVAIL_GREETING 
OPT_RECORDGAIN 
OPT_PREPEND_MAILBOX 
OPT_AUTOPLAY 
OPT_DTMFEXIT 
OPT_MESSAGE_Urgent 
OPT_MESSAGE_PRIORITY 

Definition at line 477 of file app_voicemail_odbcstorage.c.

477  {
478  OPT_SILENT = (1 << 0),
479  OPT_BUSY_GREETING = (1 << 1),
480  OPT_UNAVAIL_GREETING = (1 << 2),
481  OPT_RECORDGAIN = (1 << 3),
482  OPT_PREPEND_MAILBOX = (1 << 4),
483  OPT_AUTOPLAY = (1 << 6),
484  OPT_DTMFEXIT = (1 << 7),
485  OPT_MESSAGE_Urgent = (1 << 8),
486  OPT_MESSAGE_PRIORITY = (1 << 9)
487 };
Enumerator
OPT_PWLOC_VOICEMAILCONF 
OPT_PWLOC_SPOOLDIR 
OPT_PWLOC_USERSCONF 
OPT_PWLOC_VOICEMAILCONF 
OPT_PWLOC_SPOOLDIR 
OPT_PWLOC_USERSCONF 
OPT_PWLOC_VOICEMAILCONF 
OPT_PWLOC_SPOOLDIR 
OPT_PWLOC_USERSCONF 

Definition at line 497 of file app_voicemail_odbcstorage.c.

Function Documentation

static int __has_voicemail ( const char *  context,
const char *  mailbox,
const char *  folder,
int  shortcircuit 
)
static

Definition at line 5403 of file app_voicemail_odbcstorage.c.

References ast_strlen_zero().

Referenced by has_voicemail(), inboxcount2(), and messagecount().

5404 {
5405  DIR *dir;
5406  struct dirent *de;
5407  char fn[256];
5408  int ret = 0;
5409 
5410  /* If no mailbox, return immediately */
5411  if (ast_strlen_zero(mailbox))
5412  return 0;
5413 
5414  if (ast_strlen_zero(folder))
5415  folder = "INBOX";
5416  if (ast_strlen_zero(context))
5417  context = "default";
5418 
5419  snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
5420 
5421  if (!(dir = opendir(fn)))
5422  return 0;
5423 
5424  while ((de = readdir(dir))) {
5425  if (!strncasecmp(de->d_name, "msg", 3)) {
5426  if (shortcircuit) {
5427  ret = 1;
5428  break;
5429  } else if (!strncasecmp(de->d_name + 8, "txt", 3)) {
5430  ret++;
5431  }
5432  }
5433  }
5434 
5435  closedir(dir);
5436 
5437  return ret;
5438 }
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char VM_SPOOL_DIR[PATH_MAX]
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static void __reg_module ( void  )
static

Definition at line 13624 of file app_voicemail_odbcstorage.c.

static void __unreg_module ( void  )
static

Definition at line 13624 of file app_voicemail_odbcstorage.c.

static int acf_mailbox_exists ( struct ast_channel chan,
const char *  cmd,
char *  args,
char *  buf,
size_t  len 
)
static

Definition at line 10980 of file app_voicemail_odbcstorage.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), find_user(), LOG_ERROR, and mbox().

10981 {
10982  struct ast_vm_user svm;
10984  AST_APP_ARG(mbox);
10986  );
10987 
10988  AST_NONSTANDARD_APP_ARGS(arg, args, '@');
10989 
10990  if (ast_strlen_zero(arg.mbox)) {
10991  ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n");
10992  return -1;
10993  }
10994 
10995  ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len);
10996  return 0;
10997 }
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define LOG_ERROR
Definition: logger.h:155
static struct @350 args
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char * mbox(struct ast_vm_user *vmu, int id)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
static int actual_load_config ( int  reload,
struct ast_config cfg,
struct ast_config ucfg 
)
static

Definition at line 11814 of file app_voicemail_odbcstorage.c.

References append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_option(), ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_false(), ast_format_str_reduce(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_DEBUG, AST_LOG_ERROR, AST_LOG_WARNING, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, ast_vm_user::context, DEFAULT_LISTEN_CONTROL_FORWARD_KEY, DEFAULT_LISTEN_CONTROL_PAUSE_KEY, DEFAULT_LISTEN_CONTROL_RESTART_KEY, DEFAULT_LISTEN_CONTROL_REVERSE_KEY, DEFAULT_LISTEN_CONTROL_STOP_KEY, DEFAULT_POLL_FREQ, find_or_create(), free_vm_users(), free_vm_zones(), is_valid_dtmf(), ast_variable::lineno, LOG_ERROR, ast_vm_user::mailbox, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, vm_zone::msg_format, ast_variable::name, vm_zone::name, ast_variable::next, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), SENDMAIL, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, vm_zone::timezone, ast_variable::value, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_PBXSKIP, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, and VM_TEMPGREETWARN.

Referenced by load_config().

11815 {
11816  struct ast_vm_user *current;
11817  char *cat;
11818  struct ast_variable *var;
11819  const char *val;
11820  char *q, *stringp, *tmp;
11821  int x;
11822  unsigned int tmpadsi[4];
11823  char secretfn[PATH_MAX] = "";
11824 
11825 #ifdef IMAP_STORAGE
11826  ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder));
11827 #endif
11828  /* set audio control prompts */
11834 
11835  /* Free all the users structure */
11836  free_vm_users();
11837 
11838  /* Free all the zones structure */
11839  free_vm_zones();
11840 
11841  AST_LIST_LOCK(&users);
11842 
11843  memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
11844  memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd));
11845 
11846  if (cfg) {
11847  /* General settings */
11848 
11849  if (!(val = ast_variable_retrieve(cfg, "general", "userscontext")))
11850  val = "default";
11851  ast_copy_string(userscontext, val, sizeof(userscontext));
11852  /* Attach voice message to mail message ? */
11853  if (!(val = ast_variable_retrieve(cfg, "general", "attach")))
11854  val = "yes";
11856 
11857  if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts")))
11858  val = "no";
11860 
11861  volgain = 0.0;
11862  if ((val = ast_variable_retrieve(cfg, "general", "volgain")))
11863  sscanf(val, "%30lf", &volgain);
11864 
11865 #ifdef ODBC_STORAGE
11866  strcpy(odbc_database, "asterisk");
11867  if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) {
11868  ast_copy_string(odbc_database, val, sizeof(odbc_database));
11869  }
11870  strcpy(odbc_table, "voicemessages");
11871  if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) {
11872  ast_copy_string(odbc_table, val, sizeof(odbc_table));
11873  }
11874 #endif
11875  /* Mail command */
11876  strcpy(mailcmd, SENDMAIL);
11877  if ((val = ast_variable_retrieve(cfg, "general", "mailcmd")))
11878  ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */
11879 
11880  maxsilence = 0;
11881  if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) {
11882  maxsilence = atoi(val);
11883  if (maxsilence > 0)
11884  maxsilence *= 1000;
11885  }
11886 
11887  if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) {
11888  maxmsg = MAXMSG;
11889  } else {
11890  maxmsg = atoi(val);
11891  if (maxmsg < 0) {
11892  ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG);
11893  maxmsg = MAXMSG;
11894  } else if (maxmsg > MAXMSGLIMIT) {
11895  ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val);
11896  maxmsg = MAXMSGLIMIT;
11897  }
11898  }
11899 
11900  if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) {
11901  maxdeletedmsg = 0;
11902  } else {
11903  if (sscanf(val, "%30d", &x) == 1)
11904  maxdeletedmsg = x;
11905  else if (ast_true(val))
11907  else
11908  maxdeletedmsg = 0;
11909 
11910  if (maxdeletedmsg < 0) {
11911  ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG);
11913  } else if (maxdeletedmsg > MAXMSGLIMIT) {
11914  ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val);
11916  }
11917  }
11918 
11919  /* Load date format config for voicemail mail */
11920  if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) {
11922  }
11923 
11924  /* Load date format config for voicemail pager mail */
11925  if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) {
11927  }
11928 
11929  /* External password changing command */
11930  if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) {
11931  ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd));
11933  } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) {
11934  ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd));
11936  }
11937 
11938  /* External password validation command */
11939  if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) {
11941  ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd);
11942  }
11943 
11944 #ifdef IMAP_STORAGE
11945  /* IMAP server address */
11946  if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) {
11947  ast_copy_string(imapserver, val, sizeof(imapserver));
11948  } else {
11949  ast_copy_string(imapserver, "localhost", sizeof(imapserver));
11950  }
11951  /* IMAP server port */
11952  if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) {
11953  ast_copy_string(imapport, val, sizeof(imapport));
11954  } else {
11955  ast_copy_string(imapport, "143", sizeof(imapport));
11956  }
11957  /* IMAP server flags */
11958  if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) {
11959  ast_copy_string(imapflags, val, sizeof(imapflags));
11960  }
11961  /* IMAP server master username */
11962  if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) {
11963  ast_copy_string(authuser, val, sizeof(authuser));
11964  }
11965  /* IMAP server master password */
11966  if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) {
11967  ast_copy_string(authpassword, val, sizeof(authpassword));
11968  }
11969  /* Expunge on exit */
11970  if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) {
11971  if (ast_false(val))
11972  expungeonhangup = 0;
11973  else
11974  expungeonhangup = 1;
11975  } else {
11976  expungeonhangup = 1;
11977  }
11978  /* IMAP voicemail folder */
11979  if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) {
11980  ast_copy_string(imapfolder, val, sizeof(imapfolder));
11981  } else {
11982  ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder));
11983  }
11984  if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) {
11985  ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder));
11986  }
11987  if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) {
11988  imapgreetings = ast_true(val);
11989  } else {
11990  imapgreetings = 0;
11991  }
11992  if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) {
11993  ast_copy_string(greetingfolder, val, sizeof(greetingfolder));
11994  } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) {
11995  /* Also support greetingsfolder as documented in voicemail.conf.sample */
11996  ast_copy_string(greetingfolder, val, sizeof(greetingfolder));
11997  } else {
11998  ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder));
11999  }
12000 
12001  /* There is some very unorthodox casting done here. This is due
12002  * to the way c-client handles the argument passed in. It expects a
12003  * void pointer and casts the pointer directly to a long without
12004  * first dereferencing it. */
12005  if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) {
12006  mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val)));
12007  } else {
12008  mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L);
12009  }
12010 
12011  if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) {
12012  mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val)));
12013  } else {
12014  mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L);
12015  }
12016 
12017  if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) {
12018  mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val)));
12019  } else {
12020  mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L);
12021  }
12022 
12023  if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) {
12024  mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val)));
12025  } else {
12026  mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L);
12027  }
12028 
12029  /* Increment configuration version */
12030  imapversion++;
12031 #endif
12032  /* External voicemail notify application */
12033  if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) {
12034  ast_copy_string(externnotify, val, sizeof(externnotify));
12035  ast_debug(1, "found externnotify: %s\n", externnotify);
12036  } else {
12037  externnotify[0] = '\0';
12038  }
12039 
12040  /* SMDI voicemail notification */
12041  if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) {
12042  ast_debug(1, "Enabled SMDI voicemail notification\n");
12043  if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) {
12045  } else {
12046  ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n");
12047  smdi_iface = ast_smdi_interface_find("/dev/ttyS0");
12048  }
12049  if (!smdi_iface) {
12050  ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n");
12051  }
12052  }
12053 
12054  /* Silence treshold */
12056  if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold")))
12057  silencethreshold = atoi(val);
12058 
12059  if (!(val = ast_variable_retrieve(cfg, "general", "serveremail")))
12060  val = ASTERISK_USERNAME;
12061  ast_copy_string(serveremail, val, sizeof(serveremail));
12062 
12063  vmmaxsecs = 0;
12064  if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) {
12065  if (sscanf(val, "%30d", &x) == 1) {
12066  vmmaxsecs = x;
12067  } else {
12068  ast_log(AST_LOG_WARNING, "Invalid max message time length\n");
12069  }
12070  } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) {
12071  static int maxmessage_deprecate = 0;
12072  if (maxmessage_deprecate == 0) {
12073  maxmessage_deprecate = 1;
12074  ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n");
12075  }
12076  if (sscanf(val, "%30d", &x) == 1) {
12077  vmmaxsecs = x;
12078  } else {
12079  ast_log(AST_LOG_WARNING, "Invalid max message time length\n");
12080  }
12081  }
12082 
12083  vmminsecs = 0;
12084  if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) {
12085  if (sscanf(val, "%30d", &x) == 1) {
12086  vmminsecs = x;
12087  if (maxsilence / 1000 >= vmminsecs) {
12088  ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n");
12089  }
12090  } else {
12091  ast_log(AST_LOG_WARNING, "Invalid min message time length\n");
12092  }
12093  } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) {
12094  static int maxmessage_deprecate = 0;
12095  if (maxmessage_deprecate == 0) {
12096  maxmessage_deprecate = 1;
12097  ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n");
12098  }
12099  if (sscanf(val, "%30d", &x) == 1) {
12100  vmminsecs = x;
12101  if (maxsilence / 1000 >= vmminsecs) {
12102  ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n");
12103  }
12104  } else {
12105  ast_log(AST_LOG_WARNING, "Invalid min message time length\n");
12106  }
12107  }
12108 
12109  val = ast_variable_retrieve(cfg, "general", "format");
12110  if (!val) {
12111  val = "wav";
12112  } else {
12113  tmp = ast_strdupa(val);
12114  val = ast_format_str_reduce(tmp);
12115  if (!val) {
12116  ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n");
12117  val = "wav";
12118  }
12119  }
12120  ast_copy_string(vmfmts, val, sizeof(vmfmts));
12121 
12122  skipms = 3000;
12123  if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) {
12124  if (sscanf(val, "%30d", &x) == 1) {
12125  maxgreet = x;
12126  } else {
12127  ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n");
12128  }
12129  }
12130 
12131  if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) {
12132  if (sscanf(val, "%30d", &x) == 1) {
12133  skipms = x;
12134  } else {
12135  ast_log(AST_LOG_WARNING, "Invalid skipms value\n");
12136  }
12137  }
12138 
12139  maxlogins = 3;
12140  if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) {
12141  if (sscanf(val, "%30d", &x) == 1) {
12142  maxlogins = x;
12143  } else {
12144  ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n");
12145  }
12146  }
12147 
12149  if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) {
12150  if (sscanf(val, "%30d", &x) == 1) {
12151  minpassword = x;
12152  } else {
12153  ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword);
12154  }
12155  }
12156 
12157  /* Force new user to record name ? */
12158  if (!(val = ast_variable_retrieve(cfg, "general", "forcename")))
12159  val = "no";
12161 
12162  /* Force new user to record greetings ? */
12163  if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings")))
12164  val = "no";
12166 
12167  if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) {
12168  ast_debug(1, "VM_CID Internal context string: %s\n", val);
12169  stringp = ast_strdupa(val);
12170  for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){
12171  if (!ast_strlen_zero(stringp)) {
12172  q = strsep(&stringp, ",");
12173  while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */
12174  q++;
12176  ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]);
12177  } else {
12178  cidinternalcontexts[x][0] = '\0';
12179  }
12180  }
12181  }
12182  if (!(val = ast_variable_retrieve(cfg, "general", "review"))){
12183  ast_debug(1, "VM Review Option disabled globally\n");
12184  val = "no";
12185  }
12187 
12188  /* Temporary greeting reminder */
12189  if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) {
12190  ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n");
12191  val = "no";
12192  } else {
12193  ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n");
12194  }
12196  if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){
12197  ast_debug(1, "VM next message wrap disabled globally\n");
12198  val = "no";
12199  }
12201 
12202  if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){
12203  ast_debug(1, "VM Operator break disabled globally\n");
12204  val = "no";
12205  }
12207 
12208  if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) {
12209  ast_debug(1, "VM CID Info before msg disabled globally\n");
12210  val = "no";
12211  }
12213 
12214  if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){
12215  ast_debug(1, "Send Voicemail msg disabled globally\n");
12216  val = "no";
12217  }
12219 
12220  if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) {
12221  ast_debug(1, "ENVELOPE before msg enabled globally\n");
12222  val = "yes";
12223  }
12225 
12226  if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) {
12227  ast_debug(1, "Move Heard enabled globally\n");
12228  val = "yes";
12229  }
12231 
12232  if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) {
12233  ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n");
12234  val = "no";
12235  }
12237 
12238  if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) {
12239  ast_debug(1, "Duration info before msg enabled globally\n");
12240  val = "yes";
12241  }
12243 
12244  saydurationminfo = 2;
12245  if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) {
12246  if (sscanf(val, "%30d", &x) == 1) {
12247  saydurationminfo = x;
12248  } else {
12249  ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n");
12250  }
12251  }
12252 
12253  if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) {
12254  ast_debug(1, "We are not going to skip to the next msg after save/delete\n");
12255  val = "no";
12256  }
12258 
12259  if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) {
12260  ast_copy_string(dialcontext, val, sizeof(dialcontext));
12261  ast_debug(1, "found dialout context: %s\n", dialcontext);
12262  } else {
12263  dialcontext[0] = '\0';
12264  }
12265 
12266  if ((val = ast_variable_retrieve(cfg, "general", "callback"))) {
12267  ast_copy_string(callcontext, val, sizeof(callcontext));
12268  ast_debug(1, "found callback context: %s\n", callcontext);
12269  } else {
12270  callcontext[0] = '\0';
12271  }
12272 
12273  if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) {
12274  ast_copy_string(exitcontext, val, sizeof(exitcontext));
12275  ast_debug(1, "found operator context: %s\n", exitcontext);
12276  } else {
12277  exitcontext[0] = '\0';
12278  }
12279 
12280  /* load password sounds configuration */
12281  if ((val = ast_variable_retrieve(cfg, "general", "vm-password")))
12282  ast_copy_string(vm_password, val, sizeof(vm_password));
12283  if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword")))
12285  if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password")))
12287  if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged")))
12289  if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword")))
12291  if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch")))
12292  ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch));
12293  if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) {
12295  }
12296  if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) {
12298  }
12299  /* load configurable audio prompts */
12300  if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val))
12302  if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val))
12304  if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val))
12306  if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val))
12308  if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val))
12310 
12311  if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory")))
12312  val = "no";
12314 
12315  if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) {
12316  val = "voicemail.conf";
12317  }
12318  if (!(strcmp(val, "spooldir"))) {
12320  } else {
12322  }
12323 
12325  if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) {
12326  if (sscanf(val, "%30u", &poll_freq) != 1) {
12328  ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val);
12329  }
12330  }
12331 
12332  poll_mailboxes = 0;
12333  if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes")))
12334  poll_mailboxes = ast_true(val);
12335 
12336  memset(fromstring, 0, sizeof(fromstring));
12337  memset(pagerfromstring, 0, sizeof(pagerfromstring));
12338  strcpy(charset, "ISO-8859-1");
12339  if (emailbody) {
12341  emailbody = NULL;
12342  }
12343  if (emailsubject) {
12345  emailsubject = NULL;
12346  }
12347  if (pagerbody) {
12349  pagerbody = NULL;
12350  }
12351  if (pagersubject) {
12353  pagersubject = NULL;
12354  }
12355  if ((val = ast_variable_retrieve(cfg, "general", "pbxskip")))
12357  if ((val = ast_variable_retrieve(cfg, "general", "fromstring")))
12358  ast_copy_string(fromstring, val, sizeof(fromstring));
12359  if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring")))
12361  if ((val = ast_variable_retrieve(cfg, "general", "charset")))
12362  ast_copy_string(charset, val, sizeof(charset));
12363  if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) {
12364  sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
12365  for (x = 0; x < 4; x++) {
12366  memcpy(&adsifdn[x], &tmpadsi[x], 1);
12367  }
12368  }
12369  if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) {
12370  sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]);
12371  for (x = 0; x < 4; x++) {
12372  memcpy(&adsisec[x], &tmpadsi[x], 1);
12373  }
12374  }
12375  if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) {
12376  if (atoi(val)) {
12377  adsiver = atoi(val);
12378  }
12379  }
12380  if ((val = ast_variable_retrieve(cfg, "general", "tz"))) {
12381  ast_copy_string(zonetag, val, sizeof(zonetag));
12382  }
12383  if ((val = ast_variable_retrieve(cfg, "general", "locale"))) {
12384  ast_copy_string(locale, val, sizeof(locale));
12385  }
12386  if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) {
12388  }
12389  if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) {
12391  }
12392  if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) {
12394  }
12395  if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) {
12397  }
12398 
12399  /* load mailboxes from users.conf */
12400  if (ucfg) {
12401  for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) {
12402  if (!strcasecmp(cat, "general")) {
12403  continue;
12404  }
12405  if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail")))
12406  continue;
12407  if ((current = find_or_create(userscontext, cat))) {
12408  populate_defaults(current);
12409  apply_options_full(current, ast_variable_browse(ucfg, cat));
12410  ast_copy_string(current->context, userscontext, sizeof(current->context));
12411  if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) {
12413  }
12414 
12415  switch (current->passwordlocation) {
12416  case OPT_PWLOC_SPOOLDIR:
12417  snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox);
12418  read_password_from_file(secretfn, current->password, sizeof(current->password));
12419  }
12420  }
12421  }
12422  }
12423 
12424  /* load mailboxes from voicemail.conf */
12425  cat = ast_category_browse(cfg, NULL);
12426  while (cat) {
12427  if (strcasecmp(cat, "general")) {
12428  var = ast_variable_browse(cfg, cat);
12429  if (strcasecmp(cat, "zonemessages")) {
12430  /* Process mailboxes in this context */
12431  while (var) {
12432  append_mailbox(cat, var->name, var->value);
12433  var = var->next;
12434  }
12435  } else {
12436  /* Timezones in this context */
12437  while (var) {
12438  struct vm_zone *z;
12439  if ((z = ast_malloc(sizeof(*z)))) {
12440  char *msg_format, *tzone;
12441  msg_format = ast_strdupa(var->value);
12442  tzone = strsep(&msg_format, "|,");
12443  if (msg_format) {
12444  ast_copy_string(z->name, var->name, sizeof(z->name));
12445  ast_copy_string(z->timezone, tzone, sizeof(z->timezone));
12446  ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
12447  AST_LIST_LOCK(&zones);
12450  } else {
12451  ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
12452  ast_free(z);
12453  }
12454  } else {
12456  return -1;
12457  }
12458  var = var->next;
12459  }
12460  }
12461  }
12462  cat = ast_category_browse(cfg, cat);
12463  }
12464 
12466 
12470  stop_poll_thread();;
12471 
12472  return 0;
12473  } else {
12475  ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n");
12476  return 0;
12477  }
12478 }
#define VM_OPERATOR
static char listen_control_restart_key[12]
static double volgain
static struct ast_flags globalflags
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static int vmmaxsecs
static char listen_control_forward_key[12]
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY
static char vm_passchanged[80]
#define PWDCHANGE_EXTERNAL
char * strsep(char **str, const char *delims)
#define VM_PBXSKIP
static char userscontext[AST_MAX_EXTENSION]
char msg_format[512]
static char zonetag[80]
static unsigned int poll_mailboxes
#define MINPASSWORD
#define ast_strdup(a)
Definition: astmm.h:109
Definition: ast_expr2.c:325
char name[80]
static unsigned char adsifdn[4]
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define VM_FORCEGREET
static char pagerdateformat[32]
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static char vm_password[80]
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
char timezone[80]
#define ASTERISK_USERNAME
static char externnotify[160]
int lineno
Definition: config.h:87
struct ast_smdi_interface * ast_smdi_interface_find(const char *iface_name)
Find an SMDI interface with the specified name.
Definition: res_smdi.c:627
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static struct ast_vm_user * find_or_create(const char *context, const char *box)
#define AST_LOG_WARNING
Definition: logger.h:149
#define var
Definition: ast_expr2f.c:606
#define VM_DIRECFORWARD
#define DEFAULT_LISTEN_CONTROL_STOP_KEY
static unsigned int poll_freq
static char charset[32]
static char listen_control_pause_key[12]
static void start_poll_thread(void)
static char locale[20]
const char * ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
Retrieve a configuration variable within the configuration set.
Definition: config.c:614
static int skipms
list of users found in the config file
#define SENDMAIL
static char vm_reenterpassword[80]
static int maxlogins
static void free_vm_zones(void)
Free the zones structure.
#define VM_ENVELOPE
#define VM_SAYDURATION
#define VM_FWDURGAUTO
static unsigned char adsisec[4]
#define PWDCHANGE_INTERNAL
static struct ast_smdi_interface * smdi_iface
#define MAX_NUM_CID_CONTEXTS
#define VM_ATTACH
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define VM_SKIPAFTERCMD
const char * value
Definition: config.h:79
#define AST_LOG_ERROR
Definition: logger.h:160
static char * emailbody
static char * pagersubject
static int saydurationminfo
static char exitcontext[AST_MAX_CONTEXT]
#define AST_PTHREADT_NULL
Definition: lock.h:65
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char ext_pass_cmd[128]
char mailbox[AST_MAX_EXTENSION]
int passwordlocation
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY
char context[AST_MAX_CONTEXT]
const char * name
Definition: config.h:77
char * ast_format_str_reduce(char *fmts)
Definition: file.c:1382
#define VM_SAYCID
#define VM_TEMPGREETWARN
static int vmminsecs
static void stop_poll_thread(void)
static char * pagerbody
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
#define LOG_ERROR
Definition: logger.h:155
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
static int append_mailbox(const char *context, const char *box, const char *data)
static char fromstring[100]
static char emaildateformat[32]
static int pwdchange
static const char * substitute_escapes(const char *value)
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define VM_SVMAIL
static char vm_pls_try_again[80]
#define DEFAULT_POLL_FREQ
#define VM_MESSAGEWRAP
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
static char ext_pass_check_cmd[128]
#define ast_free(a)
Definition: astmm.h:97
static char * emailsubject
static char dialcontext[AST_MAX_CONTEXT]
static pthread_t poll_thread
static char vm_mismatch[80]
#define VM_REVIEW
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY
static int silencethreshold
static int maxsilence
#define MAXMSGLIMIT
static char serveremail[80]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char vmfmts[80]
#define VM_SEARCH
static int maxmsg
#define AST_LOG_DEBUG
Definition: logger.h:127
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
static char vm_prepend_timeout[80]
static int maxdeletedmsg
static char vm_newpassword[80]
static char pagerfromstring[100]
#define MAXMSG
struct ast_variable * next
Definition: config.h:82
static char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64]
static void read_password_from_file(const char *secretfn, char *password, int passwordlen)
static char listen_control_stop_key[12]
static int adsiver
static void free_vm_users(void)
Free the users structure.
static int passwordlocation
static char vm_invalid_password[80]
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Definition: dsp.c:1880
#define ast_malloc(a)
Definition: astmm.h:91
#define VM_MOVEHEARD
static char callcontext[AST_MAX_CONTEXT]
#define VM_FORCENAME
static char listen_control_reverse_key[12]
static int is_valid_dtmf(const char *key)
Determines if a DTMF key entered is valid.
static int maxgreet
char password[80]
static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *var)
Loads the options specific to a voicemail user.
static char mailcmd[160]
struct vm_zone::@66 list
static int minpassword
static int add_email_attachment ( FILE *  p,
struct ast_vm_user vmu,
char *  format,
char *  attach,
char *  greeting_attachment,
char *  mailbox,
char *  bound,
char *  filename,
int  last,
int  msgnum 
)
static

Definition at line 4817 of file app_voicemail_odbcstorage.c.

References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.

Referenced by make_email_file().

4818 {
4819  char tmpdir[256], newtmp[256];
4820  char fname[256];
4821  char tmpcmd[256];
4822  int tmpfd = -1;
4823  int soxstatus = 0;
4824 
4825  /* Eww. We want formats to tell us their own MIME type */
4826  char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
4827 
4828  if (vmu->volgain < -.001 || vmu->volgain > .001) {
4829  create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
4830  snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
4831  tmpfd = mkstemp(newtmp);
4832  chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
4833  ast_debug(3, "newtmp: %s\n", newtmp);
4834  if (tmpfd > -1) {
4835  snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
4836  if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
4837  attach = newtmp;
4838  ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
4839  } else {
4840  ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
4841  soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
4842  ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
4843  }
4844  }
4845  }
4846  fprintf(p, "--%s" ENDL, bound);
4847  if (msgnum > -1)
4848  fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename);
4849  else
4850  fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format);
4851  fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
4852  fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
4853  if (msgnum > -1)
4854  fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename);
4855  else
4856  fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format);
4857  snprintf(fname, sizeof(fname), "%s.%s", attach, format);
4858  base_encode(fname, p);
4859  if (last)
4860  fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound);
4861  if (tmpfd > -1) {
4862  if (soxstatus == 0) {
4863  unlink(fname);
4864  }
4865  close(tmpfd);
4866  unlink(newtmp);
4867  }
4868  return 0;
4869 }
double volgain
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
#define LOG_WARNING
Definition: logger.h:144
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct sla_ringing_trunk * last
Definition: app_meetme.c:965
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
static int my_umask
static int base_encode(char *filename, FILE *so)
Performs a base 64 encode algorithm on the contents of a File.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define VOICEMAIL_FILE_MODE
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
#define ENDL
static void adsi_begin ( struct ast_channel chan,
int *  useadsi 
)
static

Definition at line 6426 of file app_voicemail_odbcstorage.c.

References adsi_load_vmail(), ast_adsi_available(), ast_adsi_load_session(), ast_log(), and AST_LOG_WARNING.

Referenced by vm_authenticate(), and vm_execmain().

6427 {
6428  int x;
6429  if (!ast_adsi_available(chan))
6430  return;
6431  x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
6432  if (x < 0)
6433  return;
6434  if (!x) {
6435  if (adsi_load_vmail(chan, useadsi)) {
6436  ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n");
6437  return;
6438  }
6439  } else
6440  *useadsi = 1;
6441 }
static unsigned char adsifdn[4]
#define AST_LOG_WARNING
Definition: logger.h:149
int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data)
Check if scripts for a given app are already loaded. Version may be -1, if any version is okay...
Definition: adsi.c:76
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
static int adsi_load_vmail(struct ast_channel *chan, int *useadsi)
static int adsiver
static void adsi_delete ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 6621 of file app_voicemail_odbcstorage.c.

References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_set_keys(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_mutex_lock, ast_mutex_unlock, vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.

Referenced by vm_execmain().

6622 {
6623  int bytes = 0;
6624  unsigned char buf[256];
6625  unsigned char keys[8];
6626 
6627  int x;
6628 
6629  if (!ast_adsi_available(chan))
6630  return;
6631 
6632  /* New meaning for keys */
6633  for (x = 0; x < 5; x++)
6634  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
6635 
6636  keys[6] = 0x0;
6637  keys[7] = 0x0;
6638 
6639  if (!vms->curmsg) {
6640  /* No prev key, provide "Folder" instead */
6641  keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6642  }
6643  if (vms->curmsg >= vms->lastmsg) {
6644  /* If last message ... */
6645  if (vms->curmsg) {
6646  /* but not only message, provide "Folder" instead */
6647  keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6648  } else {
6649  /* Otherwise if only message, leave blank */
6650  keys[3] = 1;
6651  }
6652  }
6653 
6654  /* If deleted, show "undeleted" */
6655 #ifdef IMAP_STORAGE
6656  ast_mutex_lock(&vms->lock);
6657 #endif
6658  if (vms->deleted[vms->curmsg]) {
6659  keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
6660  }
6661 #ifdef IMAP_STORAGE
6662  ast_mutex_unlock(&vms->lock);
6663 #endif
6664 
6665  /* Except "Exit" */
6666  keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
6667  bytes += ast_adsi_set_keys(buf + bytes, keys);
6668  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6669 
6670  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6671 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
#define ADSI_KEY_SKT
Definition: adsi.h:117
int * deleted
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
#define ADSI_KEY_APPS
Definition: adsi.h:109
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void adsi_folders ( struct ast_channel chan,
int  start,
char *  label 
)
static

Definition at line 6491 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), and ast_adsi_voice_mode().

Referenced by vm_execmain().

6492 {
6493  unsigned char buf[256];
6494  int bytes = 0;
6495  unsigned char keys[8];
6496  int x, y;
6497 
6498  if (!ast_adsi_available(chan))
6499  return;
6500 
6501  for (x = 0; x < 5; x++) {
6502  y = ADSI_KEY_APPS + 12 + start + x;
6503  if (y > ADSI_KEY_APPS + 12 + 4)
6504  y = 0;
6505  keys[x] = ADSI_KEY_SKT | y;
6506  }
6507  keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
6508  keys[6] = 0;
6509  keys[7] = 0;
6510 
6511  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
6512  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
6513  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6514  bytes += ast_adsi_set_keys(buf + bytes, keys);
6515  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6516 
6517  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6518 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
#define ADSI_COMM_PAGE
Definition: adsi.h:107
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
#define ADSI_KEY_SKT
Definition: adsi.h:117
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
#define ADSI_JUST_CENT
Definition: adsi.h:114
#define ADSI_KEY_APPS
Definition: adsi.h:109
static void adsi_goodbye ( struct ast_channel chan)
static

Definition at line 6776 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), and ast_adsi_voice_mode().

Referenced by vm_execmain().

6777 {
6778  unsigned char buf[256];
6779  int bytes = 0;
6780 
6781  if (!ast_adsi_available(chan))
6782  return;
6783  bytes += adsi_logo(buf + bytes);
6784  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
6785  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
6786  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6787  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6788 
6789  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6790 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define ADSI_JUST_LEFT
Definition: adsi.h:112
static int adsi_logo(unsigned char *buf)
#define ADSI_COMM_PAGE
Definition: adsi.h:107
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
#define ADSI_JUST_CENT
Definition: adsi.h:114
static int adsi_load_vmail ( struct ast_channel chan,
int *  useadsi 
)
static

Definition at line 6297 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, ast_adsi_begin_download(), ast_adsi_data_mode(), ast_adsi_display(), ast_adsi_download_disconnect(), ast_adsi_end_download(), ast_adsi_load_session(), ast_adsi_load_soft_key(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, and mbox().

Referenced by adsi_begin().

6298 {
6299  unsigned char buf[256];
6300  int bytes = 0;
6301  int x;
6302  char num[5];
6303 
6304  *useadsi = 0;
6305  bytes += ast_adsi_data_mode(buf + bytes);
6306  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6307 
6308  bytes = 0;
6309  bytes += adsi_logo(buf);
6310  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
6311 #ifdef DISPLAY
6312  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", "");
6313 #endif
6314  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6315  bytes += ast_adsi_data_mode(buf + bytes);
6316  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6317 
6319  bytes = 0;
6320  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
6321  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
6322  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6323  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6324  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6325  return 0;
6326  }
6327 
6328 #ifdef DISPLAY
6329  /* Add a dot */
6330  bytes = 0;
6331  bytes += ast_adsi_logo(buf);
6332  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
6333  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", "");
6334  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6335  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6336 #endif
6337  bytes = 0;
6338  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
6339  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
6340  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
6341  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
6342  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
6343  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
6344  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6345 
6346 #ifdef DISPLAY
6347  /* Add another dot */
6348  bytes = 0;
6349  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", "");
6350  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6351 
6352  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6353  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6354 #endif
6355 
6356  bytes = 0;
6357  /* These buttons we load but don't use yet */
6358  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
6359  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
6360  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
6361  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
6362  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
6363  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
6364  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6365 
6366 #ifdef DISPLAY
6367  /* Add another dot */
6368  bytes = 0;
6369  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", "");
6370  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6371  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6372 #endif
6373 
6374  bytes = 0;
6375  for (x = 0; x < 5; x++) {
6376  snprintf(num, sizeof(num), "%d", x);
6377  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1);
6378  }
6379  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
6380  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6381 
6382 #ifdef DISPLAY
6383  /* Add another dot */
6384  bytes = 0;
6385  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", "");
6386  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6387  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6388 #endif
6389 
6390  if (ast_adsi_end_download(chan)) {
6391  bytes = 0;
6392  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
6393  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
6394  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6395  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6396  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6397  return 0;
6398  }
6399  bytes = 0;
6400  bytes += ast_adsi_download_disconnect(buf + bytes);
6401  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6402  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6403 
6404  ast_debug(1, "Done downloading scripts...\n");
6405 
6406 #ifdef DISPLAY
6407  /* Add last dot */
6408  bytes = 0;
6409  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", "");
6410  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6411 #endif
6412  ast_debug(1, "Restarting session...\n");
6413 
6414  bytes = 0;
6415  /* Load the session now */
6416  if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
6417  *useadsi = 1;
6418  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
6419  } else
6420  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
6421 
6422  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6423  return 0;
6424 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
int ast_adsi_begin_download(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version)
Definition: adsi.c:32
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_data_mode(unsigned char *buf)
Puts CPE in data mode.
Definition: adsi.c:219
static unsigned char adsifdn[4]
int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data)
Check if scripts for a given app are already loaded. Version may be -1, if any version is okay...
Definition: adsi.c:76
int ast_adsi_download_disconnect(unsigned char *buf)
Disconnects (and hopefully saves) a downloaded script.
Definition: adsi.c:208
#define ADSI_JUST_LEFT
Definition: adsi.h:112
static int adsi_logo(unsigned char *buf)
#define ADSI_COMM_PAGE
Definition: adsi.h:107
static unsigned char adsisec[4]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
static char * addesc
static const char * mbox(struct ast_vm_user *vmu, int id)
int ast_adsi_end_download(struct ast_channel *chan)
Definition: adsi.c:43
int ast_adsi_load_soft_key(unsigned char *buf, int key, const char *llabel, const char *slabel, char *ret, int data)
Creates &quot;load soft key&quot; parameters.
Definition: adsi.c:296
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
static int adsiver
#define ADSI_JUST_CENT
Definition: adsi.h:114
#define ADSI_KEY_APPS
Definition: adsi.h:109
static void adsi_login ( struct ast_channel chan)
static

Definition at line 6443 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_input_control(), ast_adsi_input_format(), ast_adsi_load_soft_key(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), and ast_adsi_voice_mode().

Referenced by vm_authenticate().

6444 {
6445  unsigned char buf[256];
6446  int bytes = 0;
6447  unsigned char keys[8];
6448  int x;
6449  if (!ast_adsi_available(chan))
6450  return;
6451 
6452  for (x = 0; x < 8; x++)
6453  keys[x] = 0;
6454  /* Set one key for next */
6455  keys[3] = ADSI_KEY_APPS + 3;
6456 
6457  bytes += adsi_logo(buf + bytes);
6458  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
6459  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
6460  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6461  bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
6462  bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
6463  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
6464  bytes += ast_adsi_set_keys(buf + bytes, keys);
6465  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6466  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6467 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
#define ADSI_JUST_LEFT
Definition: adsi.h:112
static int adsi_logo(unsigned char *buf)
#define ADSI_COMM_PAGE
Definition: adsi.h:107
#define ADSI_DIR_FROM_LEFT
Definition: adsi.h:120
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_input_format(unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
Set input format.
Definition: adsi.c:329
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
int ast_adsi_load_soft_key(unsigned char *buf, int key, const char *llabel, const char *slabel, char *ret, int data)
Creates &quot;load soft key&quot; parameters.
Definition: adsi.c:296
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
int ast_adsi_input_control(unsigned char *buf, int page, int line, int display, int format, int just)
Set input information.
Definition: adsi.c:318
#define ADSI_JUST_CENT
Definition: adsi.h:114
#define ADSI_KEY_APPS
Definition: adsi.h:109
static int adsi_logo ( unsigned char *  buf)
static

Definition at line 6289 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().

Referenced by adsi_goodbye(), adsi_load_vmail(), adsi_login(), vm_newuser(), vm_options(), and vm_tempgreeting().

6290 {
6291  int bytes = 0;
6292  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
6293  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
6294  return bytes;
6295 }
#define ADSI_COMM_PAGE
Definition: adsi.h:107
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
#define ADSI_JUST_CENT
Definition: adsi.h:114
static void adsi_message ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 6520 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_callerid_parse(), ast_copy_string(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), buf1, buf2, vm_state::curbox, vm_state::curmsg, vm_state::deleted, f, vm_state::fn, vm_state::lastmsg, name, and strsep().

Referenced by play_message(), and vm_execmain().

6521 {
6522  int bytes = 0;
6523  unsigned char buf[256];
6524  char buf1[256], buf2[256];
6525  char fn2[PATH_MAX];
6526 
6527  char cid[256] = "";
6528  char *val;
6529  char *name, *num;
6530  char datetime[21] = "";
6531  FILE *f;
6532 
6533  unsigned char keys[8];
6534 
6535  int x;
6536 
6537  if (!ast_adsi_available(chan))
6538  return;
6539 
6540  /* Retrieve important info */
6541  snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
6542  f = fopen(fn2, "r");
6543  if (f) {
6544  while (!feof(f)) {
6545  if (!fgets((char *) buf, sizeof(buf), f)) {
6546  continue;
6547  }
6548  if (!feof(f)) {
6549  char *stringp = NULL;
6550  stringp = (char *) buf;
6551  strsep(&stringp, "=");
6552  val = strsep(&stringp, "=");
6553  if (!ast_strlen_zero(val)) {
6554  if (!strcmp((char *) buf, "callerid"))
6555  ast_copy_string(cid, val, sizeof(cid));
6556  if (!strcmp((char *) buf, "origdate"))
6557  ast_copy_string(datetime, val, sizeof(datetime));
6558  }
6559  }
6560  }
6561  fclose(f);
6562  }
6563  /* New meaning for keys */
6564  for (x = 0; x < 5; x++)
6565  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
6566  keys[6] = 0x0;
6567  keys[7] = 0x0;
6568 
6569  if (!vms->curmsg) {
6570  /* No prev key, provide "Folder" instead */
6571  keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6572  }
6573  if (vms->curmsg >= vms->lastmsg) {
6574  /* If last message ... */
6575  if (vms->curmsg) {
6576  /* but not only message, provide "Folder" instead */
6577  keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6578  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6579 
6580  } else {
6581  /* Otherwise if only message, leave blank */
6582  keys[3] = 1;
6583  }
6584  }
6585 
6586  if (!ast_strlen_zero(cid)) {
6587  ast_callerid_parse(cid, &name, &num);
6588  if (!name)
6589  name = num;
6590  } else
6591  name = "Unknown Caller";
6592 
6593  /* If deleted, show "undeleted" */
6594 #ifdef IMAP_STORAGE
6595  ast_mutex_lock(&vms->lock);
6596 #endif
6597  if (vms->deleted[vms->curmsg]) {
6598  keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
6599  }
6600 #ifdef IMAP_STORAGE
6601  ast_mutex_unlock(&vms->lock);
6602 #endif
6603 
6604  /* Except "Exit" */
6605  keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
6606  snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
6607  strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
6608  snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
6609 
6610  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
6611  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
6612  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
6613  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
6614  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6615  bytes += ast_adsi_set_keys(buf + bytes, keys);
6616  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6617 
6618  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6619 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
char * strsep(char **str, const char *delims)
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
Definition: ast_expr2.c:325
char fn[PATH_MAX]
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
static struct ast_threadstorage buf2
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ADSI_COMM_PAGE
Definition: adsi.h:107
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
#define ADSI_KEY_SKT
Definition: adsi.h:117
static struct ast_threadstorage buf1
static const char name[]
int * deleted
static struct ast_format f[]
Definition: format_g726.c:181
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char curbox[80]
#define ADSI_KEY_APPS
Definition: adsi.h:109
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
static void adsi_password ( struct ast_channel chan)
static

Definition at line 6469 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_input_control(), ast_adsi_input_format(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), and ast_adsi_voice_mode().

Referenced by vm_authenticate().

6470 {
6471  unsigned char buf[256];
6472  int bytes = 0;
6473  unsigned char keys[8];
6474  int x;
6475  if (!ast_adsi_available(chan))
6476  return;
6477 
6478  for (x = 0; x < 8; x++)
6479  keys[x] = 0;
6480  /* Set one key for next */
6481  keys[3] = ADSI_KEY_APPS + 3;
6482 
6483  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6484  bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
6485  bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
6486  bytes += ast_adsi_set_keys(buf + bytes, keys);
6487  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6488  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6489 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ADSI_COMM_PAGE
Definition: adsi.h:107
#define ADSI_DIR_FROM_LEFT
Definition: adsi.h:120
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_input_format(unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
Set input format.
Definition: adsi.c:329
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
int ast_adsi_input_control(unsigned char *buf, int page, int line, int display, int format, int just)
Set input information.
Definition: adsi.c:318
#define ADSI_KEY_APPS
Definition: adsi.h:109
static void adsi_status ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 6673 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), buf1, buf2, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_execmain().

6674 {
6675  unsigned char buf[256] = "";
6676  char buf1[256] = "", buf2[256] = "";
6677  int bytes = 0;
6678  unsigned char keys[8];
6679  int x;
6680 
6681  char *newm = (vms->newmessages == 1) ? "message" : "messages";
6682  char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
6683  if (!ast_adsi_available(chan))
6684  return;
6685  if (vms->newmessages) {
6686  snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
6687  if (vms->oldmessages) {
6688  strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
6689  snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
6690  } else {
6691  snprintf(buf2, sizeof(buf2), "%s.", newm);
6692  }
6693  } else if (vms->oldmessages) {
6694  snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
6695  snprintf(buf2, sizeof(buf2), "%s.", oldm);
6696  } else {
6697  strcpy(buf1, "You have no messages.");
6698  buf2[0] = ' ';
6699  buf2[1] = '\0';
6700  }
6701  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
6702  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
6703  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6704 
6705  for (x = 0; x < 6; x++)
6706  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
6707  keys[6] = 0;
6708  keys[7] = 0;
6709 
6710  /* Don't let them listen if there are none */
6711  if (vms->lastmsg < 0)
6712  keys[0] = 1;
6713  bytes += ast_adsi_set_keys(buf + bytes, keys);
6714 
6715  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6716 
6717  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6718 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
int oldmessages
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
static struct ast_threadstorage buf2
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ADSI_COMM_PAGE
Definition: adsi.h:107
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
#define ADSI_KEY_SKT
Definition: adsi.h:117
static struct ast_threadstorage buf1
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
int newmessages
#define ADSI_KEY_APPS
Definition: adsi.h:109
static void adsi_status2 ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 6720 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), buf1, buf2, vm_state::curbox, and vm_state::lastmsg.

Referenced by vm_execmain().

6721 {
6722  unsigned char buf[256] = "";
6723  char buf1[256] = "", buf2[256] = "";
6724  int bytes = 0;
6725  unsigned char keys[8];
6726  int x;
6727 
6728  char *mess = (vms->lastmsg == 0) ? "message" : "messages";
6729 
6730  if (!ast_adsi_available(chan))
6731  return;
6732 
6733  /* Original command keys */
6734  for (x = 0; x < 6; x++)
6735  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
6736 
6737  keys[6] = 0;
6738  keys[7] = 0;
6739 
6740  if ((vms->lastmsg + 1) < 1)
6741  keys[0] = 0;
6742 
6743  snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
6744  strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
6745 
6746  if (vms->lastmsg + 1)
6747  snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
6748  else
6749  strcpy(buf2, "no messages.");
6750  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
6751  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
6752  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
6753  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6754  bytes += ast_adsi_set_keys(buf + bytes, keys);
6755 
6756  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6757 
6758  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6759 
6760 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys)
Set which soft keys should be displayed.
Definition: adsi.c:307
static struct ast_threadstorage buf2
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ADSI_COMM_PAGE
Definition: adsi.h:107
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
#define ADSI_KEY_SKT
Definition: adsi.h:117
static struct ast_threadstorage buf1
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
char curbox[80]
#define ADSI_KEY_APPS
Definition: adsi.h:109
static int advanced_options ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
int  msg,
int  option,
signed char  record_gain 
)
static

The advanced options within a message.

Parameters
chan
vmu
vms
msg
option
record_gainProvides handling for the play message envelope, call the person back, or reply to message.
Returns
zero on success, -1 on error.

Definition at line 13186 of file app_voicemail_odbcstorage.c.

References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, context, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), name, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, valid_config(), and wait_file().

Referenced by vm_execmain().

13187 {
13188  int res = 0;
13189  char filename[PATH_MAX];
13190  struct ast_config *msg_cfg = NULL;
13191  const char *origtime, *context;
13192  char *name, *num;
13193  int retries = 0;
13194  char *cid;
13195  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, };
13196 
13197  vms->starting = 0;
13198 
13199  make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
13200 
13201  /* Retrieve info from VM attribute file */
13202  snprintf(filename, sizeof(filename), "%s.txt", vms->fn);
13203  RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
13204  msg_cfg = ast_config_load(filename, config_flags);
13205  DISPOSE(vms->curdir, vms->curmsg);
13206  if (!valid_config(msg_cfg)) {
13207  ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
13208  return 0;
13209  }
13210 
13211  if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
13212  ast_config_destroy(msg_cfg);
13213  return 0;
13214  }
13215 
13216  cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
13217 
13218  context = ast_variable_retrieve(msg_cfg, "message", "context");
13219  if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
13220  context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
13221  switch (option) {
13222  case 3: /* Play message envelope */
13223  if (!res)
13224  res = play_message_datetime(chan, vmu, origtime, filename);
13225  if (!res)
13226  res = play_message_callerid(chan, vms, cid, context, 0);
13227 
13228  res = 't';
13229  break;
13230 
13231  case 2: /* Call back */
13232 
13233  if (ast_strlen_zero(cid))
13234  break;
13235 
13236  ast_callerid_parse(cid, &name, &num);
13237  while ((res > -1) && (res != 't')) {
13238  switch (res) {
13239  case '1':
13240  if (num) {
13241  /* Dial the CID number */
13242  res = dialout(chan, vmu, num, vmu->callback);
13243  if (res) {
13244  ast_config_destroy(msg_cfg);
13245  return 9;
13246  }
13247  } else {
13248  res = '2';
13249  }
13250  break;
13251 
13252  case '2':
13253  /* Want to enter a different number, can only do this if there's a dialout context for this user */
13254  if (!ast_strlen_zero(vmu->dialout)) {
13255  res = dialout(chan, vmu, NULL, vmu->dialout);
13256  if (res) {
13257  ast_config_destroy(msg_cfg);
13258  return 9;
13259  }
13260  } else {
13261  ast_verb(3, "Caller can not specify callback number - no dialout context available\n");
13262  res = ast_play_and_wait(chan, "vm-sorry");
13263  }
13264  ast_config_destroy(msg_cfg);
13265  return res;
13266  case '*':
13267  res = 't';
13268  break;
13269  case '3':
13270  case '4':
13271  case '5':
13272  case '6':
13273  case '7':
13274  case '8':
13275  case '9':
13276  case '0':
13277 
13278  res = ast_play_and_wait(chan, "vm-sorry");
13279  retries++;
13280  break;
13281  default:
13282  if (num) {
13283  ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num);
13284  res = ast_play_and_wait(chan, "vm-num-i-have");
13285  if (!res)
13286  res = play_message_callerid(chan, vms, num, vmu->context, 1);
13287  if (!res)
13288  res = ast_play_and_wait(chan, "vm-tocallnum");
13289  /* Only prompt for a caller-specified number if there is a dialout context specified */
13290  if (!ast_strlen_zero(vmu->dialout)) {
13291  if (!res)
13292  res = ast_play_and_wait(chan, "vm-calldiffnum");
13293  }
13294  } else {
13295  res = ast_play_and_wait(chan, "vm-nonumber");
13296  if (!ast_strlen_zero(vmu->dialout)) {
13297  if (!res)
13298  res = ast_play_and_wait(chan, "vm-toenternumber");
13299  }
13300  }
13301  if (!res) {
13302  res = ast_play_and_wait(chan, "vm-star-cancel");
13303  }
13304  if (!res) {
13305  res = ast_waitfordigit(chan, 6000);
13306  }
13307  if (!res) {
13308  retries++;
13309  if (retries > 3) {
13310  res = 't';
13311  }
13312  }
13313  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
13314  break;
13315 
13316  }
13317  if (res == 't')
13318  res = 0;
13319  else if (res == '*')
13320  res = -1;
13321  }
13322  break;
13323 
13324  case 1: /* Reply */
13325  /* Send reply directly to sender */
13326  if (ast_strlen_zero(cid))
13327  break;
13328 
13329  ast_callerid_parse(cid, &name, &num);
13330  if (!num) {
13331  ast_verb(3, "No CID number available, no reply sent\n");
13332  if (!res)
13333  res = ast_play_and_wait(chan, "vm-nonumber");
13334  ast_config_destroy(msg_cfg);
13335  return res;
13336  } else {
13337  struct ast_vm_user vmu2;
13338  if (find_user(&vmu2, vmu->context, num)) {
13339  struct leave_vm_options leave_options;
13340  char mailbox[AST_MAX_EXTENSION * 2 + 2];
13341  snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
13342 
13343  ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
13344 
13345  memset(&leave_options, 0, sizeof(leave_options));
13346  leave_options.record_gain = record_gain;
13347  res = leave_voicemail(chan, mailbox, &leave_options);
13348  if (!res)
13349  res = 't';
13350  ast_config_destroy(msg_cfg);
13351  return res;
13352  } else {
13353  /* Sender has no mailbox, can't reply */
13354  ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
13355  ast_play_and_wait(chan, "vm-nobox");
13356  res = 't';
13357  ast_config_destroy(msg_cfg);
13358  return res;
13359  }
13360  }
13361  res = 0;
13362 
13363  break;
13364  }
13365 
13366  ast_config_destroy(msg_cfg);
13367 
13368 #ifndef IMAP_STORAGE
13369  if (!res) {
13370  make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
13371  vms->heard[msg] = 1;
13372  res = wait_file(chan, vms, vms->fn);
13373  }
13374 #endif
13375  return res;
13376 }
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file)
char fn[PATH_MAX]
#define AST_LOG_WARNING
Definition: logger.h:149
char curdir[PATH_MAX]
static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
Prompts the user and records a voicemail to a mailbox.
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define RETRIEVE(a, b, c, d)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char mailbox[AST_MAX_EXTENSION]
#define AST_MAX_EXTENSION
Definition: channel.h:135
char context[AST_MAX_CONTEXT]
int * heard
static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
Structure used to handle boolean flags.
Definition: utils.h:200
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:635
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
signed char record_gain
Definition: app_minivm.c:637
#define DISPOSE(a, b)
char dialout[80]
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
char callback[80]
static int play_message_callerid(struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
static int append_mailbox ( const char *  context,
const char *  box,
const char *  data 
)
static

Definition at line 10707 of file app_voicemail_odbcstorage.c.

References apply_options(), ast_alloca, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), LOG_WARNING, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), queue_mwi_event(), read_password_from_file(), and strsep().

Referenced by actual_load_config().

10708 {
10709  /* Assumes lock is already held */
10710  char *tmp;
10711  char *stringp;
10712  char *s;
10713  struct ast_vm_user *vmu;
10714  char *mailbox_full;
10715  int new = 0, old = 0, urgent = 0;
10716  char secretfn[PATH_MAX] = "";
10717 
10718  tmp = ast_strdupa(data);
10719 
10720  if (!(vmu = find_or_create(context, box)))
10721  return -1;
10722 
10723  populate_defaults(vmu);
10724 
10725  stringp = tmp;
10726  if ((s = strsep(&stringp, ","))) {
10727  if (!ast_strlen_zero(s) && s[0] == '*') {
10728  ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password"
10729  "\n\tmust be reset in voicemail.conf.\n", box);
10730  }
10731  /* assign password regardless of validity to prevent NULL password from being assigned */
10732  ast_copy_string(vmu->password, s, sizeof(vmu->password));
10733  }
10734  if (stringp && (s = strsep(&stringp, ","))) {
10735  ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
10736  }
10737  if (stringp && (s = strsep(&stringp, ","))) {
10738  ast_copy_string(vmu->email, s, sizeof(vmu->email));
10739  }
10740  if (stringp && (s = strsep(&stringp, ","))) {
10741  ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
10742  }
10743  if (stringp && (s = strsep(&stringp, ","))) {
10744  apply_options(vmu, s);
10745  }
10746 
10747  switch (vmu->passwordlocation) {
10748  case OPT_PWLOC_SPOOLDIR:
10749  snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
10750  read_password_from_file(secretfn, vmu->password, sizeof(vmu->password));
10751  }
10752 
10753  mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1);
10754  strcpy(mailbox_full, box);
10755  strcat(mailbox_full, "@");
10756  strcat(mailbox_full, context);
10757 
10758  inboxcount2(mailbox_full, &urgent, &new, &old);
10759  queue_mwi_event(mailbox_full, urgent, new, old);
10760 
10761  return 0;
10762 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
char fullname[80]
char * strsep(char **str, const char *delims)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define LOG_WARNING
Definition: logger.h:144
static struct ast_vm_user * find_or_create(const char *context, const char *box)
static void queue_mwi_event(const char *box, int urgent, int new, int old)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
static void apply_options(struct ast_vm_user *vmu, const char *options)
Destructively Parse options and apply.
int passwordlocation
char context[AST_MAX_CONTEXT]
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
char pager[80]
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static void read_password_from_file(const char *secretfn, char *password, int passwordlen)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char email[80]
char password[80]
static void apply_option ( struct ast_vm_user vmu,
const char *  var,
const char *  value 
)
static

Sets a a specific property value.

Parameters
vmuThe voicemail user object to work with.
varThe name of the property to be set.
valueThe value to be set to the property.

The property name must be one of the understood properties. See the source for details.

Definition at line 1037 of file app_voicemail_odbcstorage.c.

References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_strdup, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::locale, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::serveremail, substitute_escapes(), VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, vmmaxsecs, vmminsecs, ast_vm_user::volgain, and ast_vm_user::zonetag.

Referenced by apply_options(), and apply_options_full().

1038 {
1039  int x;
1040  if (!strcasecmp(var, "attach")) {
1042  } else if (!strcasecmp(var, "attachfmt")) {
1043  ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
1044  } else if (!strcasecmp(var, "serveremail")) {
1045  ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
1046  } else if (!strcasecmp(var, "emailbody")) {
1048  } else if (!strcasecmp(var, "emailsubject")) {
1050  } else if (!strcasecmp(var, "language")) {
1051  ast_copy_string(vmu->language, value, sizeof(vmu->language));
1052  } else if (!strcasecmp(var, "tz")) {
1053  ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
1054  } else if (!strcasecmp(var, "locale")) {
1055  ast_copy_string(vmu->locale, value, sizeof(vmu->locale));
1056 #ifdef IMAP_STORAGE
1057  } else if (!strcasecmp(var, "imapuser")) {
1058  ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
1059  vmu->imapversion = imapversion;
1060  } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
1061  ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
1062  vmu->imapversion = imapversion;
1063  } else if (!strcasecmp(var, "imapfolder")) {
1064  ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder));
1065  } else if (!strcasecmp(var, "imapvmshareid")) {
1066  ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
1067  vmu->imapversion = imapversion;
1068 #endif
1069  } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
1071  } else if (!strcasecmp(var, "saycid")){
1073  } else if (!strcasecmp(var, "sendvoicemail")){
1075  } else if (!strcasecmp(var, "review")){
1077  } else if (!strcasecmp(var, "tempgreetwarn")){
1079  } else if (!strcasecmp(var, "messagewrap")){
1081  } else if (!strcasecmp(var, "operator")) {
1083  } else if (!strcasecmp(var, "envelope")){
1085  } else if (!strcasecmp(var, "moveheard")){
1087  } else if (!strcasecmp(var, "sayduration")){
1089  } else if (!strcasecmp(var, "saydurationm")){
1090  if (sscanf(value, "%30d", &x) == 1) {
1091  vmu->saydurationm = x;
1092  } else {
1093  ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n");
1094  }
1095  } else if (!strcasecmp(var, "forcename")){
1097  } else if (!strcasecmp(var, "forcegreetings")){
1099  } else if (!strcasecmp(var, "callback")) {
1100  ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
1101  } else if (!strcasecmp(var, "dialout")) {
1102  ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
1103  } else if (!strcasecmp(var, "exitcontext")) {
1104  ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
1105  } else if (!strcasecmp(var, "minsecs")) {
1106  if (sscanf(value, "%30d", &x) == 1 && x >= 0) {
1107  vmu->minsecs = x;
1108  } else {
1109  ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs);
1110  vmu->minsecs = vmminsecs;
1111  }
1112  } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) {
1113  vmu->maxsecs = atoi(value);
1114  if (vmu->maxsecs <= 0) {
1115  ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs);
1116  vmu->maxsecs = vmmaxsecs;
1117  } else {
1118  vmu->maxsecs = atoi(value);
1119  }
1120  if (!strcasecmp(var, "maxmessage"))
1121  ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n");
1122  } else if (!strcasecmp(var, "maxmsg")) {
1123  vmu->maxmsg = atoi(value);
1124  /* Accept maxmsg=0 (Greetings only voicemail) */
1125  if (vmu->maxmsg < 0) {
1126  ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG);
1127  vmu->maxmsg = MAXMSG;
1128  } else if (vmu->maxmsg > MAXMSGLIMIT) {
1129  ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
1130  vmu->maxmsg = MAXMSGLIMIT;
1131  }
1132  } else if (!strcasecmp(var, "nextaftercmd")) {
1134  } else if (!strcasecmp(var, "backupdeleted")) {
1135  if (sscanf(value, "%30d", &x) == 1)
1136  vmu->maxdeletedmsg = x;
1137  else if (ast_true(value))
1138  vmu->maxdeletedmsg = MAXMSG;
1139  else
1140  vmu->maxdeletedmsg = 0;
1141 
1142  if (vmu->maxdeletedmsg < 0) {
1143  ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG);
1144  vmu->maxdeletedmsg = MAXMSG;
1145  } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) {
1146  ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value);
1147  vmu->maxdeletedmsg = MAXMSGLIMIT;
1148  }
1149  } else if (!strcasecmp(var, "volgain")) {
1150  sscanf(value, "%30lf", &vmu->volgain);
1151  } else if (!strcasecmp(var, "passwordlocation")) {
1152  if (!strcasecmp(value, "spooldir")) {
1154  } else {
1156  }
1157  } else if (!strcasecmp(var, "options")) {
1158  apply_options(vmu, value);
1159  }
1160 }
double volgain
#define VM_OPERATOR
static int vmmaxsecs
#define ast_strdup(a)
Definition: astmm.h:109
char attachfmt[20]
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define VM_FORCEGREET
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
#define var
Definition: ast_expr2f.c:606
int value
Definition: syslog.c:39
char locale[20]
char * emailsubject
#define VM_ENVELOPE
#define VM_SAYDURATION
#define VM_ATTACH
#define VM_SKIPAFTERCMD
static void apply_options(struct ast_vm_user *vmu, const char *options)
Destructively Parse options and apply.
int passwordlocation
#define VM_SAYCID
#define VM_TEMPGREETWARN
char zonetag[80]
static int vmminsecs
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
char * emailbody
static const char * substitute_escapes(const char *value)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char exit[80]
#define VM_SVMAIL
#define VM_MESSAGEWRAP
#define VM_REVIEW
char language[MAX_LANGUAGE]
#define MAXMSGLIMIT
#define VM_DELETE
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char dialout[80]
char callback[80]
#define MAXMSG
char serveremail[80]
#define VM_MOVEHEARD
#define VM_FORCENAME
static void apply_options ( struct ast_vm_user vmu,
const char *  options 
)
static

Destructively Parse options and apply.

Definition at line 1278 of file app_voicemail_odbcstorage.c.

References apply_option(), ast_strdupa, strsep(), value, and var.

Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().

1279 {
1280  char *stringp;
1281  char *s;
1282  char *var, *value;
1283  stringp = ast_strdupa(options);
1284  while ((s = strsep(&stringp, "|"))) {
1285  value = s;
1286  if ((var = strsep(&value, "=")) && value) {
1287  apply_option(vmu, var, value);
1288  }
1289  }
1290 }
char * strsep(char **str, const char *delims)
#define var
Definition: ast_expr2f.c:606
static void apply_option(struct ast_vm_user *vmu, const char *var, const char *value)
Sets a a specific property value.
int value
Definition: syslog.c:39
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static void apply_options_full ( struct ast_vm_user retval,
struct ast_variable var 
)
static

Loads the options specific to a voicemail user.

This is called when a vm_user structure is being set up, such as from load_options.

Definition at line 1297 of file app_voicemail_odbcstorage.c.

References apply_option(), ast_copy_string(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::fullname, LOG_WARNING, ast_vm_user::mailbox, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, substitute_escapes(), ast_vm_user::uniqueid, ast_variable::value, and var.

Referenced by actual_load_config(), and find_user_realtime().

1298 {
1299  for (; var; var = var->next) {
1300  if (!strcasecmp(var->name, "vmsecret")) {
1301  ast_copy_string(retval->password, var->value, sizeof(retval->password));
1302  } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */
1303  if (ast_strlen_zero(retval->password)) {
1304  if (!ast_strlen_zero(var->value) && var->value[0] == '*') {
1305  ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password"
1306  "\n\tmust be reset in voicemail.conf.\n", retval->mailbox);
1307  } else {
1308  ast_copy_string(retval->password, var->value, sizeof(retval->password));
1309  }
1310  }
1311  } else if (!strcasecmp(var->name, "uniqueid")) {
1312  ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid));
1313  } else if (!strcasecmp(var->name, "pager")) {
1314  ast_copy_string(retval->pager, var->value, sizeof(retval->pager));
1315  } else if (!strcasecmp(var->name, "email")) {
1316  ast_copy_string(retval->email, var->value, sizeof(retval->email));
1317  } else if (!strcasecmp(var->name, "fullname")) {
1318  ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname));
1319  } else if (!strcasecmp(var->name, "context")) {
1320  ast_copy_string(retval->context, var->value, sizeof(retval->context));
1321  } else if (!strcasecmp(var->name, "emailsubject")) {
1322  ast_free(retval->emailsubject);
1324  } else if (!strcasecmp(var->name, "emailbody")) {
1325  ast_free(retval->emailbody);
1326  retval->emailbody = ast_strdup(substitute_escapes(var->value));
1327 #ifdef IMAP_STORAGE
1328  } else if (!strcasecmp(var->name, "imapuser")) {
1329  ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser));
1330  retval->imapversion = imapversion;
1331  } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) {
1332  ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword));
1333  retval->imapversion = imapversion;
1334  } else if (!strcasecmp(var->name, "imapfolder")) {
1335  ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder));
1336  } else if (!strcasecmp(var->name, "imapvmshareid")) {
1337  ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid));
1338  retval->imapversion = imapversion;
1339 #endif
1340  } else
1341  apply_option(retval, var->name, var->value);
1342  }
1343 }
char uniqueid[80]
char fullname[80]
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
#define var
Definition: ast_expr2f.c:606
static void apply_option(struct ast_vm_user *vmu, const char *var, const char *value)
Sets a a specific property value.
char * emailsubject
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
const char * name
Definition: config.h:77
char pager[80]
char * emailbody
static const char * substitute_escapes(const char *value)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_variable * next
Definition: config.h:82
char email[80]
char password[80]
AST_DATA_STRUCTURE ( ast_vm_user  ,
DATA_EXPORT_VM_USERS   
)
AST_DATA_STRUCTURE ( vm_zone  ,
DATA_EXPORT_VM_ZONES   
)
static const char* ast_str_encode_mime ( struct ast_str **  end,
ssize_t  maxlen,
const char *  start,
size_t  preamble,
size_t  postamble 
)
static

Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.

Additionally, if the encoded string would exceed the MIME limit of 76 characters per line, then the encoding will be broken up into multiple sections, separated by a space character, in order to facilitate breaking up the associated header across multiple lines.

Parameters
endAn expandable buffer for holding the result
maxlenAlways zero, but see
See Also
ast_str
Parameters
startA string to be encoded
preambleThe length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars.
postamblethe length of any additional characters appended to the line, used to ensure proper field wrapping.
Return values
Theencoded string.

Definition at line 4492 of file app_voicemail_odbcstorage.c.

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

Referenced by make_email_file(), and sendpage().

4493 {
4494  struct ast_str *tmp = ast_str_alloca(80);
4495  int first_section = 1;
4496 
4497  ast_str_reset(*end);
4498  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
4499  for (; *start; start++) {
4500  int need_encoding = 0;
4501  if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
4502  need_encoding = 1;
4503  }
4504  if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) ||
4505  (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) ||
4506  (!first_section && need_encoding && ast_str_strlen(tmp) > 70) ||
4507  (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) {
4508  /* Start new line */
4509  ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp));
4510  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
4511  first_section = 0;
4512  }
4513  if (need_encoding && *start == ' ') {
4514  ast_str_append(&tmp, -1, "_");
4515  } else if (need_encoding) {
4516  ast_str_append(&tmp, -1, "=%hhX", *start);
4517  } else {
4518  ast_str_append(&tmp, -1, "%c", *start);
4519  }
4520  }
4521  ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : "");
4522  return ast_str_buffer(*end);
4523 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
static char charset[32]
#define ast_str_alloca(init_len)
Definition: strings.h:608
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static const char* ast_str_quote ( struct ast_str **  buf,
ssize_t  maxlen,
const char *  from 
)
static

Wraps a character sequence in double quotes, escaping occurences of quotes within the string.

Parameters
fromThe string to work with.
bufThe buffer into which to write the modified quoted string.
maxlenAlways zero, but see
See Also
ast_str
Returns
The destination string with quotes wrapped on it (the to field).

Definition at line 4420 of file app_voicemail_odbcstorage.c.

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

Referenced by make_email_file(), and sendpage().

4421 {
4422  const char *ptr;
4423 
4424  /* We're only ever passing 0 to maxlen, so short output isn't possible */
4425  ast_str_set(buf, maxlen, "\"");
4426  for (ptr = from; *ptr; ptr++) {
4427  if (*ptr == '"' || *ptr == '\\') {
4428  ast_str_append(buf, maxlen, "\\%c", *ptr);
4429  } else {
4430  ast_str_append(buf, maxlen, "%c", *ptr);
4431  }
4432  }
4433  ast_str_append(buf, maxlen, "\"");
4434 
4435  return ast_str_buffer(*buf);
4436 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
AST_TEST_DEFINE ( test_voicemail_vmuser  )

Definition at line 10764 of file app_voicemail_odbcstorage.c.

References apply_options(), ast_calloc, ast_set_flag, AST_TEST_FAIL, ast_test_flag, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, free_user(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, ast_vm_user::passwordlocation, populate_defaults(), ast_vm_user::saydurationm, ast_vm_user::serveremail, TEST_EXECUTE, TEST_INIT, VM_ALLOCED, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.

10765 {
10766  int res = 0;
10767  struct ast_vm_user *vmu;
10768  /* language parameter seems to only be used for display in manager action */
10769  static const char options_string[] = "attach=yes|attachfmt=wav49|"
10770  "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|"
10771  "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|"
10772  "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|"
10773  "forcegreetings=yes|callback=somecontext|dialout=somecontext2|"
10774  "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|"
10775  "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody="
10776  "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject="
10777  "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}";
10778 #ifdef IMAP_STORAGE
10779  static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|"
10780  "imapfolder=INBOX|imapvmshareid=6000";
10781 #endif
10782 
10783  switch (cmd) {
10784  case TEST_INIT:
10785  info->name = "vmuser";
10786  info->category = "/apps/app_voicemail/";
10787  info->summary = "Vmuser unit test";
10788  info->description =
10789  "This tests passing all supported parameters to apply_options, the voicemail user config parser";
10790  return AST_TEST_NOT_RUN;
10791  case TEST_EXECUTE:
10792  break;
10793  }
10794 
10795  if (!(vmu = ast_calloc(1, sizeof(*vmu)))) {
10796  return AST_TEST_NOT_RUN;
10797  }
10798  populate_defaults(vmu);
10799  ast_set_flag(vmu, VM_ALLOCED);
10800 
10801  apply_options(vmu, options_string);
10802 
10803  if (!ast_test_flag(vmu, VM_ATTACH)) {
10804  ast_test_status_update(test, "Parse failure for attach option\n");
10805  res = 1;
10806  }
10807  if (strcasecmp(vmu->attachfmt, "wav49")) {
10808  ast_test_status_update(test, "Parse failure for attachftm option\n");
10809  res = 1;
10810  }
10811  if (strcasecmp(vmu->serveremail, "someguy@digium.com")) {
10812  ast_test_status_update(test, "Parse failure for serveremail option\n");
10813  res = 1;
10814  }
10815  if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) {
10816  ast_test_status_update(test, "Parse failure for emailsubject option\n");
10817  res = 1;
10818  }
10819  if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) {
10820  ast_test_status_update(test, "Parse failure for emailbody option\n");
10821  res = 1;
10822  }
10823  if (strcasecmp(vmu->zonetag, "central")) {
10824  ast_test_status_update(test, "Parse failure for tz option\n");
10825  res = 1;
10826  }
10827  if (!ast_test_flag(vmu, VM_DELETE)) {
10828  ast_test_status_update(test, "Parse failure for delete option\n");
10829  res = 1;
10830  }
10831  if (!ast_test_flag(vmu, VM_SAYCID)) {
10832  ast_test_status_update(test, "Parse failure for saycid option\n");
10833  res = 1;
10834  }
10835  if (!ast_test_flag(vmu, VM_SVMAIL)) {
10836  ast_test_status_update(test, "Parse failure for sendvoicemail option\n");
10837  res = 1;
10838  }
10839  if (!ast_test_flag(vmu, VM_REVIEW)) {
10840  ast_test_status_update(test, "Parse failure for review option\n");
10841  res = 1;
10842  }
10843  if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) {
10844  ast_test_status_update(test, "Parse failure for tempgreetwarm option\n");
10845  res = 1;
10846  }
10847  if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) {
10848  ast_test_status_update(test, "Parse failure for messagewrap option\n");
10849  res = 1;
10850  }
10851  if (!ast_test_flag(vmu, VM_OPERATOR)) {
10852  ast_test_status_update(test, "Parse failure for operator option\n");
10853  res = 1;
10854  }
10855  if (!ast_test_flag(vmu, VM_ENVELOPE)) {
10856  ast_test_status_update(test, "Parse failure for envelope option\n");
10857  res = 1;
10858  }
10859  if (!ast_test_flag(vmu, VM_MOVEHEARD)) {
10860  ast_test_status_update(test, "Parse failure for moveheard option\n");
10861  res = 1;
10862  }
10863  if (!ast_test_flag(vmu, VM_SAYDURATION)) {
10864  ast_test_status_update(test, "Parse failure for sayduration option\n");
10865  res = 1;
10866  }
10867  if (vmu->saydurationm != 5) {
10868  ast_test_status_update(test, "Parse failure for saydurationm option\n");
10869  res = 1;
10870  }
10871  if (!ast_test_flag(vmu, VM_FORCENAME)) {
10872  ast_test_status_update(test, "Parse failure for forcename option\n");
10873  res = 1;
10874  }
10875  if (!ast_test_flag(vmu, VM_FORCEGREET)) {
10876  ast_test_status_update(test, "Parse failure for forcegreetings option\n");
10877  res = 1;
10878  }
10879  if (strcasecmp(vmu->callback, "somecontext")) {
10880  ast_test_status_update(test, "Parse failure for callbacks option\n");
10881  res = 1;
10882  }
10883  if (strcasecmp(vmu->dialout, "somecontext2")) {
10884  ast_test_status_update(test, "Parse failure for dialout option\n");
10885  res = 1;
10886  }
10887  if (strcasecmp(vmu->exit, "somecontext3")) {
10888  ast_test_status_update(test, "Parse failure for exitcontext option\n");
10889  res = 1;
10890  }
10891  if (vmu->minsecs != 10) {
10892  ast_test_status_update(test, "Parse failure for minsecs option\n");
10893  res = 1;
10894  }
10895  if (vmu->maxsecs != 100) {
10896  ast_test_status_update(test, "Parse failure for maxsecs option\n");
10897  res = 1;
10898  }
10899  if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) {
10900  ast_test_status_update(test, "Parse failure for nextaftercmd option\n");
10901  res = 1;
10902  }
10903  if (vmu->maxdeletedmsg != 50) {
10904  ast_test_status_update(test, "Parse failure for backupdeleted option\n");
10905  res = 1;
10906  }
10907  if (vmu->volgain != 1.3) {
10908  ast_test_status_update(test, "Parse failure for volgain option\n");
10909  res = 1;
10910  }
10911  if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) {
10912  ast_test_status_update(test, "Parse failure for passwordlocation option\n");
10913  res = 1;
10914  }
10915 #ifdef IMAP_STORAGE
10916  apply_options(vmu, option_string2);
10917 
10918  if (strcasecmp(vmu->imapuser, "imapuser")) {
10919  ast_test_status_update(test, "Parse failure for imapuser option\n");
10920  res = 1;
10921  }
10922  if (strcasecmp(vmu->imappassword, "imappasswd")) {
10923  ast_test_status_update(test, "Parse failure for imappasswd option\n");
10924  res = 1;
10925  }
10926  if (strcasecmp(vmu->imapfolder, "INBOX")) {
10927  ast_test_status_update(test, "Parse failure for imapfolder option\n");
10928  res = 1;
10929  }
10930  if (strcasecmp(vmu->imapvmshareid, "6000")) {
10931  ast_test_status_update(test, "Parse failure for imapvmshareid option\n");
10932  res = 1;
10933  }
10934 #endif
10935 
10936  free_user(vmu);
10937  return res ? AST_TEST_FAIL : AST_TEST_PASS;
10938 }
double volgain
#define VM_OPERATOR
char attachfmt[20]
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define VM_FORCEGREET
#define ast_set_flag(p, flag)
Definition: utils.h:70
char * emailsubject
#define VM_ENVELOPE
#define VM_SAYDURATION
#define VM_ATTACH
#define VM_SKIPAFTERCMD
#define VM_ALLOCED
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static void apply_options(struct ast_vm_user *vmu, const char *options)
Destructively Parse options and apply.
int passwordlocation
#define VM_SAYCID
#define VM_TEMPGREETWARN
char zonetag[80]
static void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
char * emailbody
char exit[80]
#define VM_SVMAIL
#define VM_MESSAGEWRAP
static void free_user(struct ast_vm_user *vmu)
#define VM_REVIEW
#define ast_calloc(a, b)
Definition: astmm.h:82
#define VM_DELETE
char dialout[80]
char callback[80]
char serveremail[80]
#define VM_MOVEHEARD
#define VM_FORCENAME
static int base_encode ( char *  filename,
FILE *  so 
)
static

Performs a base 64 encode algorithm on the contents of a File.

Parameters
filenameThe path to the file to be encoded. Must be readable, file is opened in read mode.
soA FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename.

TODO: shouldn't this (and the above 3 support functions) be put into some kind of external utility location, such as funcs/func_base64.c ?

Returns
zero on success, -1 on error.

Definition at line 4296 of file app_voicemail_odbcstorage.c.

References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().

Referenced by add_email_attachment().

4297 {
4298  static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
4299  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
4300  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
4301  '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
4302  int i, hiteof = 0;
4303  FILE *fi;
4304  struct baseio bio;
4305 
4306  memset(&bio, 0, sizeof(bio));
4307  bio.iocp = BASEMAXINLINE;
4308 
4309  if (!(fi = fopen(filename, "rb"))) {
4310  ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
4311  return -1;
4312  }
4313 
4314  while (!hiteof){
4315  unsigned char igroup[3], ogroup[4];
4316  int c, n;
4317 
4318  memset(igroup, 0, sizeof(igroup));
4319 
4320  for (n = 0; n < 3; n++) {
4321  if ((c = inchar(&bio, fi)) == EOF) {
4322  hiteof = 1;
4323  break;
4324  }
4325 
4326  igroup[n] = (unsigned char) c;
4327  }
4328 
4329  if (n > 0) {
4330  ogroup[0]= dtable[igroup[0] >> 2];
4331  ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
4332  ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
4333  ogroup[3]= dtable[igroup[2] & 0x3F];
4334 
4335  if (n < 3) {
4336  ogroup[3] = '=';
4337 
4338  if (n < 2)
4339  ogroup[2] = '=';
4340  }
4341 
4342  for (i = 0; i < 4; i++)
4343  ochar(&bio, ogroup[i], so);
4344  }
4345  }
4346 
4347  fclose(fi);
4348 
4349  if (fputs(ENDL, so) == EOF) {
4350  return 0;
4351  }
4352 
4353  return 1;
4354 }
static int inchar(struct baseio *bio, FILE *fi)
utility used by base_encode()
#define BASEMAXINLINE
#define AST_LOG_WARNING
Definition: logger.h:149
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static int ochar(struct baseio *bio, int c, FILE *so)
utility used by base_encode()
#define ENDL
static int change_password_realtime ( struct ast_vm_user vmu,
const char *  password 
)
static

Performs a change of the voicemail passowrd in the realtime engine.

Parameters
vmuThe voicemail user to change the password for.
passwordThe new value to be set to the password for this user.

This only works if there is a realtime engine configured. This is called from the (top level) vm_change_password.

Returns
zero on success, -1 on error.

Definition at line 1256 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), ast_realtime_require_field(), ast_test_suite_event_notify, ast_update2_realtime(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, RQ_CHAR, and SENTINEL.

Referenced by vm_change_password().

1257 {
1258  int res = -1;
1259  if (!strcmp(vmu->password, password)) {
1260  /* No change (but an update would return 0 rows updated, so we opt out here) */
1261  return 0;
1262  }
1263 
1264  if (strlen(password) > 10) {
1265  ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL);
1266  }
1267  if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) {
1268  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime");
1269  ast_copy_string(vmu->password, password, sizeof(vmu->password));
1270  res = 0;
1271  }
1272  return res;
1273 }
int ast_update2_realtime(const char *family,...) attribute_sentinel
Update realtime configuration.
Definition: config.c:2703
Definition: config.h:68
#define SENTINEL
Definition: compiler.h:75
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: config.c:2606
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char password[80]
static int check_mime ( const char *  str)
static

Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean.

Definition at line 4465 of file app_voicemail_odbcstorage.c.

References str.

Referenced by make_email_file(), and sendpage().

4466 {
4467  for (; *str; str++) {
4468  if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
4469  return 1;
4470  }
4471  }
4472  return 0;
4473 }
const char * str
Definition: app_jack.c:144
static int check_password ( struct ast_vm_user vmu,
char *  password 
)
static

Check that password meets minimum required length.

Parameters
vmuThe voicemail user to change the password for.
passwordThe password string to check
Returns
zero on ok, 1 on not ok.

Definition at line 1215 of file app_voicemail_odbcstorage.c.

References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().

Referenced by vm_newuser(), and vm_options().

1216 {
1217  /* check minimum length */
1218  if (strlen(password) < minpassword)
1219  return 1;
1220  /* check that password does not contain '*' character */
1221  if (!ast_strlen_zero(password) && password[0] == '*')
1222  return 1;
1224  char cmd[255], buf[255];
1225 
1226  ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password);
1227 
1228  snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password);
1229  if (vm_check_password_shell(cmd, buf, sizeof(buf))) {
1230  ast_debug(5, "Result: %s\n", buf);
1231  if (!strncasecmp(buf, "VALID", 5)) {
1232  ast_debug(3, "Passed password check: '%s'\n", buf);
1233  return 0;
1234  } else if (!strncasecmp(buf, "FAILURE", 7)) {
1235  ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf);
1236  return 0;
1237  } else {
1238  ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password);
1239  return 1;
1240  }
1241  }
1242  }
1243  return 0;
1244 }
#define AST_LOG_WARNING
Definition: logger.h:149
#define AST_LOG_NOTICE
Definition: logger.h:138
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char ext_pass_check_cmd[128]
static char * vm_check_password_shell(char *command, char *buf, size_t len)
#define AST_LOG_DEBUG
Definition: logger.h:127
char password[80]
static int minpassword
static int close_mailbox ( struct vm_state vms,
struct ast_vm_user vmu 
)
static

Definition at line 7985 of file app_voicemail_odbcstorage.c.

References ast_check_realtime(), ast_debug, ast_free, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_unlock_path(), ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, vm_state::dh_arraysize, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::heard, last_message_index(), vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.

Referenced by vm_execmain().

7986 {
7987  int x = 0;
7988  int last_msg_idx = 0;
7989 
7990 #ifndef IMAP_STORAGE
7991  int res = 0, nummsg;
7992  char fn2[PATH_MAX];
7993 #endif
7994 
7995  if (vms->lastmsg <= -1) {
7996  goto done;
7997  }
7998 
7999  vms->curmsg = -1;
8000 #ifndef IMAP_STORAGE
8001  /* Get the deleted messages fixed */
8002  if (vm_lock_path(vms->curdir)) {
8003  return ERROR_LOCK_PATH;
8004  }
8005 
8006  /* update count as message may have arrived while we've got mailbox open */
8007  last_msg_idx = last_message_index(vmu, vms->curdir);
8008  if (last_msg_idx != vms->lastmsg) {
8009  ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg);
8010  }
8011 
8012  /* must check up to last detected message, just in case it is erroneously greater than maxmsg */
8013  for (x = 0; x < last_msg_idx + 1; x++) {
8014  if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) {
8015  /* Save this message. It's not in INBOX or hasn't been heard */
8016  make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
8017  if (!EXISTS(vms->curdir, x, vms->fn, NULL)) {
8018  break;
8019  }
8020  vms->curmsg++;
8021  make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg);
8022  if (strcmp(vms->fn, fn2)) {
8023  RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2);
8024  }
8025  } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) {
8026  /* Move to old folder before deleting */
8027  res = save_to_folder(vmu, vms, x, 1);
8028  if (res == ERROR_LOCK_PATH) {
8029  /* If save failed do not delete the message */
8030  ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
8031  vms->deleted[x] = 0;
8032  vms->heard[x] = 0;
8033  --x;
8034  }
8035  } else if (vms->deleted[x] && vmu->maxdeletedmsg) {
8036  /* Move to deleted folder */
8037  res = save_to_folder(vmu, vms, x, 10);
8038  if (res == ERROR_LOCK_PATH) {
8039  /* If save failed do not delete the message */
8040  vms->deleted[x] = 0;
8041  vms->heard[x] = 0;
8042  --x;
8043  }
8044  } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) {
8045  /* If realtime storage enabled - we should explicitly delete this message,
8046  cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */
8047  make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
8048  if (EXISTS(vms->curdir, x, vms->fn, NULL)) {
8049  DELETE(vms->curdir, x, vms->fn, vmu);
8050  }
8051  }
8052  }
8053 
8054  /* Delete ALL remaining messages */
8055  nummsg = x - 1;
8056  for (x = vms->curmsg + 1; x <= nummsg; x++) {
8057  make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
8058  if (EXISTS(vms->curdir, x, vms->fn, NULL)) {
8059  DELETE(vms->curdir, x, vms->fn, vmu);
8060  }
8061  }
8062  ast_unlock_path(vms->curdir);
8063 #else /* defined(IMAP_STORAGE) */
8064  ast_mutex_lock(&vms->lock);
8065  if (vms->deleted) {
8066  /* Since we now expunge after each delete, deleting in reverse order
8067  * ensures that no reordering occurs between each step. */
8068  last_msg_idx = vms->dh_arraysize;
8069  for (x = last_msg_idx - 1; x >= 0; x--) {
8070  if (vms->deleted[x]) {
8071  ast_debug(3, "IMAP delete of %d\n", x);
8072  DELETE(vms->curdir, x, vms->fn, vmu);
8073  }
8074  }
8075  }
8076 #endif
8077 
8078 done:
8079  if (vms->deleted) {
8080  ast_free(vms->deleted);
8081  vms->deleted = NULL;
8082  }
8083  if (vms->heard) {
8084  ast_free(vms->heard);
8085  vms->heard = NULL;
8086  }
8087  vms->dh_arraysize = 0;
8088 #ifdef IMAP_STORAGE
8089  ast_mutex_unlock(&vms->lock);
8090 #endif
8091 
8092  return 0;
8093 }
static int last_message_index(struct ast_vm_user *vmu, char *dir)
Determines the highest message number in use for a given user and mailbox folder. ...
#define DELETE(a, b, c, d)
#define ast_test_flag(p, flag)
Definition: utils.h:63
char fn[PATH_MAX]
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
#define AST_LOG_WARNING
Definition: logger.h:149
char curdir[PATH_MAX]
#define ast_mutex_lock(a)
Definition: lock.h:155
int dh_arraysize
#define AST_LOG_NOTICE
Definition: logger.h:138
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
int * heard
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
int * deleted
#define RENAME(a, b, c, d, e, f, g, h)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
#define EXISTS(a, b, c, d)
#define ERROR_LOCK_PATH
char curbox[80]
#define VM_MOVEHEARD
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
static char* complete_voicemail_show_users ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 11084 of file app_voicemail_odbcstorage.c.

References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.

Referenced by handle_voicemail_show_users().

11085 {
11086  int which = 0;
11087  int wordlen;
11088  struct ast_vm_user *vmu;
11089  const char *context = "";
11090 
11091  /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
11092  if (pos > 4)
11093  return NULL;
11094  if (pos == 3)
11095  return (state == 0) ? ast_strdup("for") : NULL;
11096  wordlen = strlen(word);
11097  AST_LIST_TRAVERSE(&users, vmu, list) {
11098  if (!strncasecmp(word, vmu->context, wordlen)) {
11099  if (context && strcmp(context, vmu->context) && ++which > state)
11100  return ast_strdup(vmu->context);
11101  /* ignore repeated contexts ? */
11102  context = vmu->context;
11103  }
11104  }
11105  return NULL;
11106 }
#define ast_strdup(a)
Definition: astmm.h:109
list of users found in the config file
Definition: ael.tab.c:203
struct ast_vm_user::@65 list
char context[AST_MAX_CONTEXT]
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int copy ( char *  infile,
char *  outfile 
)
static

Utility function to copy a file.

Parameters
infileThe path to the file to be copied. The file must be readable, it is opened in read only mode.
outfileThe path for which to copy the file to. The directory permissions must allow the creation (or truncation) of the file, and allow for opening the file in write only mode.

When the compiler option HARDLINK_WHEN_POSSIBLE is set, the copy operation will attempt to use the hard link facility instead of copy the file (to save disk space). If the link operation fails, it falls back to the copy operation. The copy operation copies up to 4096 bytes at once.

Returns
zero on success, -1 on error.

Definition at line 4101 of file app_voicemail_odbcstorage.c.

References ast_log(), AST_LOG_WARNING, errno, len(), and VOICEMAIL_FILE_MODE.

Referenced by copy_plain_file(), and vm_forwardoptions().

4102 {
4103  int ifd;
4104  int ofd;
4105  int res;
4106  int len;
4107  char buf[4096];
4108 
4109 #ifdef HARDLINK_WHEN_POSSIBLE
4110  /* Hard link if possible; saves disk space & is faster */
4111  if (link(infile, outfile)) {
4112 #endif
4113  if ((ifd = open(infile, O_RDONLY)) < 0) {
4114  ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
4115  return -1;
4116  }
4117  if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
4118  ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
4119  close(ifd);
4120  return -1;
4121  }
4122  do {
4123  len = read(ifd, buf, sizeof(buf));
4124  if (len < 0) {
4125  ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
4126  close(ifd);
4127  close(ofd);
4128  unlink(outfile);
4129  } else if (len) {
4130  res = write(ofd, buf, len);
4131  if (errno == ENOMEM || errno == ENOSPC || res != len) {
4132  ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
4133  close(ifd);
4134  close(ofd);
4135  unlink(outfile);
4136  }
4137  }
4138  } while (len);
4139  close(ifd);
4140  close(ofd);
4141  return 0;
4142 #ifdef HARDLINK_WHEN_POSSIBLE
4143  } else {
4144  /* Hard link succeeded */
4145  return 0;
4146  }
4147 #endif
4148 }
#define AST_LOG_WARNING
Definition: logger.h:149
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define VOICEMAIL_FILE_MODE
static int copy_message ( struct ast_channel chan,
struct ast_vm_user vmu,
int  imbox,
int  msgnum,
long  duration,
struct ast_vm_user recip,
char *  fmt,
char *  dir,
const char *  flag 
)
static

Copies a message from one mailbox to another.

Parameters
chan
vmu
imbox
msgnum
duration
recip
fmt
dir
flagThis is only used by file storage based mailboxes.
Returns
zero on success, -1 on error.

Definition at line 5337 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::caller, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_party_caller::id, inprocess_count(), ast_channel::language, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), mbox(), ast_party_id::name, notify_new_message(), ast_party_id::number, S_COR, STORE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, vm_delete(), and vm_lock_path().

Referenced by forward_message(), and leave_voicemail().

5338 {
5339  char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
5340  const char *frombox = mbox(vmu, imbox);
5341  const char *userfolder;
5342  int recipmsgnum;
5343  int res = 0;
5344 
5345  ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
5346 
5347  if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */
5348  userfolder = "Urgent";
5349  } else {
5350  userfolder = "INBOX";
5351  }
5352 
5353  create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder);
5354 
5355  if (!dir)
5356  make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
5357  else
5358  ast_copy_string(fromdir, dir, sizeof(fromdir));
5359 
5360  make_file(frompath, sizeof(frompath), fromdir, msgnum);
5361  make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder);
5362 
5363  if (vm_lock_path(todir))
5364  return ERROR_LOCK_PATH;
5365 
5366  recipmsgnum = last_message_index(recip, todir) + 1;
5367  if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) {
5368  make_file(topath, sizeof(topath), todir, recipmsgnum);
5369 #ifndef ODBC_STORAGE
5370  if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
5371  COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
5372  } else {
5373 #endif
5374  /* If we are prepending a message for ODBC, then the message already
5375  * exists in the database, but we want to force copying from the
5376  * filesystem (since only the FS contains the prepend). */
5377  copy_plain_file(frompath, topath);
5378  STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL);
5379  vm_delete(topath);
5380 #ifndef ODBC_STORAGE
5381  }
5382 #endif
5383  } else {
5384  ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
5385  res = -1;
5386  }
5387  ast_unlock_path(todir);
5388  notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt,
5389  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
5390  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
5391  flag);
5392 
5393  return res;
5394 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
static int last_message_index(struct ast_vm_user *vmu, char *dir)
Determines the highest message number in use for a given user and mailbox folder. ...
static int vm_delete(char *file)
Removes the voicemail sound and information file.
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define AST_LOG_NOTICE
Definition: logger.h:138
#define AST_LOG_ERROR
Definition: logger.h:160
#define COPY(a, b, c, d, e, f, g, h)
#define STORE(a, b, c, d, e, f, g, h, i, j)
static int inprocess_count(const char *context, const char *mailbox, int delta)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
char context[AST_MAX_CONTEXT]
static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag)
Sends email notification that a user has a new voicemail waiting for them.
static void copy_plain_file(char *frompath, char *topath)
Copies a voicemail information (envelope) file.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char * mbox(struct ast_vm_user *vmu, int id)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
#define EXISTS(a, b, c, d)
#define ERROR_LOCK_PATH
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int maxmsg
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
const ast_string_field language
Definition: channel.h:787
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void copy_plain_file ( char *  frompath,
char *  topath 
)
static

Copies a voicemail information (envelope) file.

Parameters
frompath
topath

Every voicemail has the data (.wav) file, and the information file. This function performs the file system copying of the information file for a voicemail, handling the internal fields and their values. This is used by the COPY macro when not using IMAP storage.

Definition at line 4159 of file app_voicemail_odbcstorage.c.

References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), ast_store_realtime(), ast_variables_destroy(), copy(), exten, ast_variable::name, ast_variable::next, SENTINEL, and ast_variable::value.

Referenced by copy_message().

4160 {
4161  char frompath2[PATH_MAX], topath2[PATH_MAX];
4162  struct ast_variable *tmp,*var = NULL;
4163  const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL;
4164  ast_filecopy(frompath, topath, NULL);
4165  snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
4166  snprintf(topath2, sizeof(topath2), "%s.txt", topath);
4167  if (ast_check_realtime("voicemail_data")) {
4168  var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL);
4169  /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */
4170  for (tmp = var; tmp; tmp = tmp->next) {
4171  if (!strcasecmp(tmp->name, "origmailbox")) {
4172  origmailbox = tmp->value;
4173  } else if (!strcasecmp(tmp->name, "context")) {
4174  context = tmp->value;
4175  } else if (!strcasecmp(tmp->name, "macrocontext")) {
4176  macrocontext = tmp->value;
4177  } else if (!strcasecmp(tmp->name, "exten")) {
4178  exten = tmp->value;
4179  } else if (!strcasecmp(tmp->name, "priority")) {
4180  priority = tmp->value;
4181  } else if (!strcasecmp(tmp->name, "callerchan")) {
4182  callerchan = tmp->value;
4183  } else if (!strcasecmp(tmp->name, "callerid")) {
4184  callerid = tmp->value;
4185  } else if (!strcasecmp(tmp->name, "origdate")) {
4186  origdate = tmp->value;
4187  } else if (!strcasecmp(tmp->name, "origtime")) {
4188  origtime = tmp->value;
4189  } else if (!strcasecmp(tmp->name, "category")) {
4190  category = tmp->value;
4191  } else if (!strcasecmp(tmp->name, "duration")) {
4192  duration = tmp->value;
4193  }
4194  }
4195  ast_store_realtime("voicemail_data", "filename", topath, "origmailbox", origmailbox, "context", context, "macrocontext", macrocontext, "exten", exten, "priority", priority, "callerchan", callerchan, "callerid", callerid, "origdate", origdate, "origtime", origtime, "category", category, "duration", duration, SENTINEL);
4196  }
4197  copy(frompath2, topath2);
4198  ast_variables_destroy(var);
4199 }
int ast_filecopy(const char *oldname, const char *newname, const char *fmt)
Copies a file.
Definition: file.c:941
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int ast_store_realtime(const char *family,...) attribute_sentinel
Create realtime configuration.
Definition: config.c:2726
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
#define SENTINEL
Definition: compiler.h:75
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
static int copy(char *infile, char *outfile)
Utility function to copy a file.
struct ast_variable * next
Definition: config.h:82
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
static int count_messages ( struct ast_vm_user vmu,
char *  dir 
)
static

Find all .txt files - even if they are not in sequence from 0000.

Parameters
vmu
dirThis method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP).
Returns
the count of messages, zero or more.

Definition at line 3996 of file app_voicemail_odbcstorage.c.

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

Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().

3997 {
3998 
3999  int vmcount = 0;
4000  DIR *vmdir = NULL;
4001  struct dirent *vment = NULL;
4002 
4003  if (vm_lock_path(dir))
4004  return ERROR_LOCK_PATH;
4005 
4006  if ((vmdir = opendir(dir))) {
4007  while ((vment = readdir(vmdir))) {
4008  if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) {
4009  vmcount++;
4010  }
4011  }
4012  closedir(vmdir);
4013  }
4014  ast_unlock_path(dir);
4015 
4016  return vmcount;
4017 }
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
#define ERROR_LOCK_PATH
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
static int create_dirpath ( char *  dest,
int  len,
const char *  context,
const char *  ext,
const char *  folder 
)
static

basically mkdir -p $dest/$context/$ext/$folder

Parameters
destString. base directory.
lenLength of dest.
contextString. Ignored if is null or empty string.
extString. Ignored if is null or empty string.
folderString. Ignored if is null or empty string.
Returns
-1 on failure, 0 on success.

Definition at line 1679 of file app_voicemail_odbcstorage.c.

References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.

Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), open_mailbox(), and save_to_folder().

1680 {
1681  mode_t mode = VOICEMAIL_DIR_MODE;
1682  int res;
1683 
1684  make_dir(dest, len, context, ext, folder);
1685  if ((res = ast_mkdir(dest, mode))) {
1686  ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res));
1687  return -1;
1688  }
1689  return 0;
1690 }
#define AST_LOG_WARNING
Definition: logger.h:149
#define VOICEMAIL_DIR_MODE
const char * ext
Definition: http.c:112
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
static int dialout ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  num,
char *  outgoing_context 
)
static

Definition at line 13113 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_verbose(), ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.

Referenced by advanced_options(), and vm_execmain().

13114 {
13115  int cmd = 0;
13116  char destination[80] = "";
13117  int retries = 0;
13118 
13119  if (!num) {
13120  ast_verb(3, "Destination number will be entered manually\n");
13121  while (retries < 3 && cmd != 't') {
13122  destination[1] = '\0';
13123  destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call");
13124  if (!cmd)
13125  destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
13126  if (!cmd)
13127  destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
13128  if (!cmd) {
13129  cmd = ast_waitfordigit(chan, 6000);
13130  if (cmd)
13131  destination[0] = cmd;
13132  }
13133  if (!cmd) {
13134  retries++;
13135  } else {
13136 
13137  if (cmd < 0)
13138  return 0;
13139  if (cmd == '*') {
13140  ast_verb(3, "User hit '*' to cancel outgoing call\n");
13141  return 0;
13142  }
13143  if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0)
13144  retries++;
13145  else
13146  cmd = 't';
13147  }
13148  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
13149  }
13150  if (retries >= 3) {
13151  return 0;
13152  }
13153 
13154  } else {
13155  if (option_verbose > 2)
13156  ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
13157  ast_copy_string(destination, num, sizeof(destination));
13158  }
13159 
13160  if (!ast_strlen_zero(destination)) {
13161  if (destination[strlen(destination) -1 ] == '*')
13162  return 0;
13163  if (option_verbose > 2)
13164  ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
13165  ast_copy_string(chan->exten, destination, sizeof(chan->exten));
13166  ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
13167  chan->priority = 0;
13168  return 9;
13169  }
13170  return 0;
13171 }
int priority
Definition: channel.h:841
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define VERBOSE_PREFIX_3
Definition: logger.h:43
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
int option_verbose
Definition: asterisk.c:181
#define ast_verb(level,...)
Definition: logger.h:243
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static struct ast_vm_user* find_or_create ( const char *  context,
const char *  box 
)
static

Definition at line 10667 of file app_voicemail_odbcstorage.c.

References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.

Referenced by actual_load_config(), and append_mailbox().

10668 {
10669  struct ast_vm_user *vmu;
10670 
10671  if (!ast_strlen_zero(box) && box[0] == '*') {
10672  ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character,"
10673  "\n\twhen it is the first character in a mailbox or password, is used to jump to a"
10674  "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid"
10675  "\n\tand will be ignored.\n", box, context);
10676  return NULL;
10677  }
10678 
10679  AST_LIST_TRAVERSE(&users, vmu, list) {
10680  if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) {
10681  if (strcasecmp(vmu->context, context)) {
10682  ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
10683  \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
10684  \n\tconfiguration creates an ambiguity that you likely do not want. Please\
10685  \n\tamend your voicemail.conf file to avoid this situation.\n", box);
10686  }
10687  ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box);
10688  return NULL;
10689  }
10690  if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) {
10691  ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context);
10692  return NULL;
10693  }
10694  }
10695 
10696  if (!(vmu = ast_calloc(1, sizeof(*vmu))))
10697  return NULL;
10698 
10699  ast_copy_string(vmu->context, context, sizeof(vmu->context));
10700  ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox));
10701 
10703 
10704  return vmu;
10705 }
static struct ast_flags globalflags
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
list of users found in the config file
struct ast_vm_user::@65 list
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define VM_SEARCH
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static struct ast_vm_user* find_user ( struct ast_vm_user ivm,
const char *  context,
const char *  mailbox 
)
static

Finds a voicemail user from the users file or the realtime engine.

Parameters
ivm
context
mailbox
Returns
The ast_vm_user structure for the user that was found.

Definition at line 1418 of file app_voicemail_odbcstorage.c.

References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_strdup, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, find_user_realtime(), VM_ALLOCED, and VM_SEARCH.

Referenced by acf_mailbox_exists(), advanced_options(), forward_message(), leave_voicemail(), vm_authenticate(), vm_box_exists(), and vm_execmain().

1419 {
1420  /* This function could be made to generate one from a database, too */
1421  struct ast_vm_user *vmu = NULL, *cur;
1422  AST_LIST_LOCK(&users);
1423 
1425  context = "default";
1426 
1427  AST_LIST_TRAVERSE(&users, cur, list) {
1428 #ifdef IMAP_STORAGE
1429  if (cur->imapversion != imapversion) {
1430  continue;
1431  }
1432 #endif
1433  if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
1434  break;
1435  if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
1436  break;
1437  }
1438  if (cur) {
1439  /* Make a copy, so that on a reload, we have no race */
1440  if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
1441  *vmu = *cur;
1442  if (!ivm) {
1443  vmu->emailbody = ast_strdup(cur->emailbody);
1444  vmu->emailsubject = ast_strdup(cur->emailsubject);
1445  }
1446  ast_set2_flag(vmu, !ivm, VM_ALLOCED);
1447  AST_LIST_NEXT(vmu, list) = NULL;
1448  }
1449  } else
1450  vmu = find_user_realtime(ivm, context, mailbox);
1452  return vmu;
1453 }
static struct ast_flags globalflags
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ast_vm_user * find_user_realtime(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the realtime engine.
#define ast_strdup(a)
Definition: astmm.h:109
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
list of users found in the config file
char * emailsubject
#define VM_ALLOCED
struct ast_vm_user::@65 list
char * emailbody
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define VM_SEARCH
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define ast_malloc(a)
Definition: astmm.h:91
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static struct ast_vm_user* find_user_realtime ( struct ast_vm_user ivm,
const char *  context,
const char *  mailbox 
)
static

Finds a voicemail user from the realtime engine.

Parameters
ivm
context
mailboxThis is called as a fall through case when the normal find_user() was not able to find a user. That is, the default it so look in the usual voicemail users file first.
Returns
The ast_vm_user structure for the user that was found.

Definition at line 1377 of file app_voicemail_odbcstorage.c.

References apply_options_full(), ast_calloc, ast_copy_string(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), free_user(), ast_vm_user::mailbox, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.

Referenced by find_user().

1378 {
1379  struct ast_variable *var;
1380  struct ast_vm_user *retval;
1381 
1382  if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
1383  if (ivm) {
1384  memset(retval, 0, sizeof(*retval));
1385  }
1386  populate_defaults(retval);
1387  if (!ivm) {
1388  ast_set_flag(retval, VM_ALLOCED);
1389  }
1390  if (mailbox) {
1391  ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
1392  }
1393  if (!context && ast_test_flag((&globalflags), VM_SEARCH)) {
1394  var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL);
1395  } else {
1396  var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL);
1397  }
1398  if (var) {
1399  apply_options_full(retval, var);
1400  ast_variables_destroy(var);
1401  } else {
1402  if (!ivm)
1403  free_user(retval);
1404  retval = NULL;
1405  }
1406  }
1407  return retval;
1408 }
static struct ast_flags globalflags
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
#define SENTINEL
Definition: compiler.h:75
#define VM_ALLOCED
char mailbox[AST_MAX_EXTENSION]
static void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
static void free_user(struct ast_vm_user *vmu)
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define VM_SEARCH
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *var)
Loads the options specific to a voicemail user.
static int forward_message ( struct ast_channel chan,
char *  context,
struct vm_state vms,
struct ast_vm_user sender,
char *  fmt,
int  is_new_message,
signed char  record_gain,
int  urgent 
)
static

Sends a voicemail message to a mailbox recipient.

Parameters
chan
context
vms
sender
fmt
is_new_messageUsed to indicate the mode for which this method was invoked. Will be 0 when called to forward an existing message (option 8) Will be 1 when called to leave a message (option 3->5)
record_gain
urgentReads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory.

When in the leave message mode (is_new_message == 1):

  • allow the leaving of a message for ourselves. (Will not allow us to forward a message to ourselves, when is_new_message == 0).
  • attempt to determine the context and and mailbox, and then invoke leave_message() function to record and store the message.

When in the forward message mode (is_new_message == 0):

  • retreives the current message to be forwarded
  • copies the original message to a temporary file, so updates to the envelope can be done.
  • determines the target mailbox and folders
  • copies the message into the target mailbox, using copy_message() or by generating the message into an email attachment if using imap folders.
Returns
zero on success, -1 on error.

Definition at line 7187 of file app_voicemail_odbcstorage.c.

References ast_clear_flag, ast_copy_string(), ast_fileexists(), ast_filerename(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_waitfordigit(), ast_channel::caller, ast_vm_user::context, ast_channel::context, copy_message(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), ast_party_caller::id, inboxcount(), inprocess_count(), ast_channel::language, leave_voicemail(), LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_party_id::name, ast_party_id::number, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), serveremail, STORE, ast_party_name::str, ast_party_number::str, strsep(), vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.

Referenced by vm_execmain().

7188 {
7189 #ifdef IMAP_STORAGE
7190  int todircount = 0;
7191  struct vm_state *dstvms;
7192 #endif
7193  char username[70]="";
7194  char fn[PATH_MAX]; /* for playback of name greeting */
7195  char ecodes[16] = "#";
7196  int res = 0, cmd = 0;
7197  struct ast_vm_user *receiver = NULL, *vmtmp;
7199  char *stringp;
7200  const char *s;
7201  int saved_messages = 0;
7202  int valid_extensions = 0;
7203  char *dir;
7204  int curmsg;
7205  char urgent_str[7] = "";
7206  int prompt_played = 0;
7207 #ifndef IMAP_STORAGE
7208  char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX];
7209 #endif
7211  ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str));
7212  }
7213 
7214  if (vms == NULL) return -1;
7215  dir = vms->curdir;
7216  curmsg = vms->curmsg;
7217 
7218  ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu");
7219  while (!res && !valid_extensions) {
7220  int use_directory = 0;
7222  int done = 0;
7223  int retries = 0;
7224  cmd = 0;
7225  while ((cmd >= 0) && !done ){
7226  if (cmd)
7227  retries = 0;
7228  switch (cmd) {
7229  case '1':
7230  use_directory = 0;
7231  done = 1;
7232  break;
7233  case '2':
7234  use_directory = 1;
7235  done = 1;
7236  break;
7237  case '*':
7238  cmd = 't';
7239  done = 1;
7240  break;
7241  default:
7242  /* Press 1 to enter an extension press 2 to use the directory */
7243  cmd = ast_play_and_wait(chan, "vm-forward");
7244  if (!cmd) {
7245  cmd = ast_waitfordigit(chan, 3000);
7246  }
7247  if (!cmd) {
7248  retries++;
7249  }
7250  if (retries > 3) {
7251  cmd = 't';
7252  done = 1;
7253  }
7254  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
7255  }
7256  }
7257  if (cmd < 0 || cmd == 't')
7258  break;
7259  }
7260 
7261  if (use_directory) {
7262  /* use app_directory */
7263 
7264  char old_context[sizeof(chan->context)];
7265  char old_exten[sizeof(chan->exten)];
7266  int old_priority;
7267  struct ast_app* directory_app;
7268 
7269  directory_app = pbx_findapp("Directory");
7270  if (directory_app) {
7271  char vmcontext[256];
7272  /* make backup copies */
7273  memcpy(old_context, chan->context, sizeof(chan->context));
7274  memcpy(old_exten, chan->exten, sizeof(chan->exten));
7275  old_priority = chan->priority;
7276 
7277  /* call the the Directory, changes the channel */
7278  snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default");
7279  res = pbx_exec(chan, directory_app, vmcontext);
7280 
7281  ast_copy_string(username, chan->exten, sizeof(username));
7282 
7283  /* restore the old context, exten, and priority */
7284  memcpy(chan->context, old_context, sizeof(chan->context));
7285  memcpy(chan->exten, old_exten, sizeof(chan->exten));
7286  chan->priority = old_priority;
7287  } else {
7288  ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
7290  }
7291  } else {
7292  /* Ask for an extension */
7293  res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
7294  prompt_played++;
7295  if (res || prompt_played > 4)
7296  break;
7297  if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
7298  break;
7299  }
7300 
7301  /* start all over if no username */
7302  if (ast_strlen_zero(username))
7303  continue;
7304  stringp = username;
7305  s = strsep(&stringp, "*");
7306  /* start optimistic */
7307  valid_extensions = 1;
7308  while (s) {
7309  if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
7310  int oldmsgs;
7311  int newmsgs;
7312  int capacity;
7313  if (inboxcount(s, &newmsgs, &oldmsgs)) {
7314  ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s);
7315  /* Shouldn't happen, but allow trying another extension if it does */
7316  res = ast_play_and_wait(chan, "pbx-invalid");
7317  valid_extensions = 0;
7318  break;
7319  }
7320  capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1);
7321  if ((newmsgs + oldmsgs) >= capacity) {
7322  ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity);
7323  res = ast_play_and_wait(chan, "vm-mailboxfull");
7324  valid_extensions = 0;
7325  while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
7326  inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
7327  free_user(vmtmp);
7328  }
7329  inprocess_count(receiver->mailbox, receiver->context, -1);
7330  break;
7331  }
7332  AST_LIST_INSERT_HEAD(&extensions, receiver, list);
7333  } else {
7334  /* XXX Optimization for the future. When we encounter a single bad extension,
7335  * bailing out on all of the extensions may not be the way to go. We should
7336  * probably just bail on that single extension, then allow the user to enter
7337  * several more. XXX
7338  */
7339  while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) {
7340  free_user(receiver);
7341  }
7342  ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
7343  /* "I am sorry, that's not a valid extension. Please try again." */
7344  res = ast_play_and_wait(chan, "pbx-invalid");
7345  valid_extensions = 0;
7346  break;
7347  }
7348 
7349  /* play name if available, else play extension number */
7350  snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s);
7351  RETRIEVE(fn, -1, s, receiver->context);
7352  if (ast_fileexists(fn, NULL, NULL) > 0) {
7353  res = ast_stream_and_wait(chan, fn, ecodes);
7354  if (res) {
7355  DISPOSE(fn, -1);
7356  return res;
7357  }
7358  } else {
7359  res = ast_say_digit_str(chan, s, ecodes, chan->language);
7360  }
7361  DISPOSE(fn, -1);
7362 
7363  s = strsep(&stringp, "*");
7364  }
7365  /* break from the loop of reading the extensions */
7366  if (valid_extensions)
7367  break;
7368  }
7369  /* check if we're clear to proceed */
7370  if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
7371  return res;
7372  if (is_new_message == 1) {
7373  struct leave_vm_options leave_options;
7374  char mailbox[AST_MAX_EXTENSION * 2 + 2];
7375  snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
7376 
7377  /* Send VoiceMail */
7378  memset(&leave_options, 0, sizeof(leave_options));
7379  leave_options.record_gain = record_gain;
7380  cmd = leave_voicemail(chan, mailbox, &leave_options);
7381  } else {
7382  /* Forward VoiceMail */
7383  long duration = 0;
7384  struct vm_state vmstmp;
7385  int copy_msg_result = 0;
7386  memcpy(&vmstmp, vms, sizeof(vmstmp));
7387 
7388  RETRIEVE(dir, curmsg, sender->mailbox, sender->context);
7389 
7390  cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str);
7391  if (!cmd) {
7392  AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
7393 #ifdef IMAP_STORAGE
7394  int attach_user_voicemail;
7395  char *myserveremail = serveremail;
7396 
7397  /* get destination mailbox */
7398  dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
7399  if (!dstvms) {
7400  dstvms = create_vm_state_from_user(vmtmp);
7401  }
7402  if (dstvms) {
7403  init_mailstream(dstvms, 0);
7404  if (!dstvms->mailstream) {
7405  ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox);
7406  } else {
7407  copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str);
7408  run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str);
7409  }
7410  } else {
7411  ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox);
7412  }
7413  if (!ast_strlen_zero(vmtmp->serveremail))
7414  myserveremail = vmtmp->serveremail;
7415  attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
7416  /* NULL category for IMAP storage */
7417  sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox,
7418  dstvms->curbox,
7419  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
7420  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
7421  vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan,
7422  NULL, urgent_str);
7423 #else
7424  copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str);
7425 #endif
7426  saved_messages++;
7428  inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
7429  free_user(vmtmp);
7430  if (res)
7431  break;
7432  }
7434  if (saved_messages > 0 && !copy_msg_result) {
7435  /* give confirmation that the message was saved */
7436  /* commented out since we can't forward batches yet
7437  if (saved_messages == 1)
7438  res = ast_play_and_wait(chan, "vm-message");
7439  else
7440  res = ast_play_and_wait(chan, "vm-messages");
7441  if (!res)
7442  res = ast_play_and_wait(chan, "vm-saved"); */
7443 #ifdef IMAP_STORAGE
7444  /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */
7445  if (ast_strlen_zero(vmstmp.introfn))
7446 #endif
7447  res = ast_play_and_wait(chan, "vm-msgsaved");
7448  }
7449 #ifndef IMAP_STORAGE
7450  else {
7451  /* with IMAP, mailbox full warning played by imap_check_limits */
7452  res = ast_play_and_wait(chan, "vm-mailboxfull");
7453  }
7454  /* Restore original message without prepended message if backup exists */
7455  make_file(msgfile, sizeof(msgfile), dir, curmsg);
7456  strcpy(textfile, msgfile);
7457  strcpy(backup, msgfile);
7458  strcpy(backup_textfile, msgfile);
7459  strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
7460  strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
7461  strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
7462  if (ast_fileexists(backup, NULL, NULL) > 0) {
7463  ast_filerename(backup, msgfile, NULL);
7464  rename(backup_textfile, textfile);
7465  }
7466 #endif
7467  }
7468  DISPOSE(dir, curmsg);
7469 #ifndef IMAP_STORAGE
7470  if (cmd) { /* assuming hangup, cleanup backup file */
7471  make_file(msgfile, sizeof(msgfile), dir, curmsg);
7472  strcpy(textfile, msgfile);
7473  strcpy(backup_textfile, msgfile);
7474  strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
7475  strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
7476  rename(backup_textfile, textfile);
7477  }
7478 #endif
7479  }
7480 
7481  /* If anything failed above, we still have this list to free */
7482  while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
7483  inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
7484  free_user(vmtmp);
7485  }
7486  return res ? res : cmd;
7487 }
static struct ast_flags globalflags
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char * strsep(char **str, const char *delims)
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx.c:1537
int priority
Definition: channel.h:841
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx.c:1497
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char fn[PATH_MAX]
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define AST_LOG_WARNING
Definition: logger.h:149
char curdir[PATH_MAX]
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8415
#define VM_DIRECFORWARD
char * str
Subscriber name (Malloced)
Definition: channel.h:214
static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
Prompts the user and records a voicemail to a mailbox.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag)
Copies a message from one mailbox to another.
#define VM_FWDURGAUTO
#define RETRIEVE(a, b, c, d)
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define VM_ATTACH
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define AST_LOG_ERROR
Definition: logger.h:160
#define STORE(a, b, c, d, e, f, g, h, i, j)
static int inprocess_count(const char *context, const char *mailbox, int delta)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char username[80]
#define AST_MAX_EXTENSION
Definition: channel.h:135
static void run_externnotify(char *context, char *extension, const char *flag)
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
char context[AST_MAX_CONTEXT]
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static int vm_forwardoptions(struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag)
presents the option to prepend to an existing message when forwarding it.
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
#define AST_LIST_HEAD_NOLOCK_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
Definition: linkedlists.h:345
#define LOG_ERROR
Definition: logger.h:155
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
static void free_user(struct ast_vm_user *vmu)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
#define ast_clear_flag(p, flag)
Definition: utils.h:77
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:635
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
signed char record_gain
Definition: app_minivm.c:637
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
#define DISPOSE(a, b)
static char serveremail[80]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char vmfmts[80]
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
ast_app: A registered application
Definition: pbx.c:971
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
char curbox[80]
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag)
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static void free_user ( struct ast_vm_user vmu)
static

Definition at line 1734 of file app_voicemail_odbcstorage.c.

References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.

Referenced by AST_TEST_DEFINE(), find_user_realtime(), forward_message(), free_vm_users(), leave_voicemail(), and vm_execmain().

1735 {
1736  if (ast_test_flag(vmu, VM_ALLOCED)) {
1737 
1738  ast_free(vmu->emailbody);
1739  vmu->emailbody = NULL;
1740 
1741  ast_free(vmu->emailsubject);
1742  vmu->emailsubject = NULL;
1743 
1744  ast_free(vmu);
1745  }
1746 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * emailsubject
#define VM_ALLOCED
char * emailbody
#define ast_free(a)
Definition: astmm.h:97
static void free_vm_users ( void  )
static

Free the users structure.

Definition at line 11696 of file app_voicemail_odbcstorage.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), and VM_ALLOCED.

Referenced by actual_load_config(), and unload_module().

11697 {
11698  struct ast_vm_user *current;
11699  AST_LIST_LOCK(&users);
11700  while ((current = AST_LIST_REMOVE_HEAD(&users, list))) {
11701  ast_set_flag(current, VM_ALLOCED);
11702  free_user(current);
11703  }
11705 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
list of users found in the config file
#define VM_ALLOCED
struct ast_vm_user::@65 list
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static void free_user(struct ast_vm_user *vmu)
static void free_vm_zones ( void  )
static

Free the zones structure.

Definition at line 11708 of file app_voicemail_odbcstorage.c.

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

Referenced by actual_load_config(), and unload_module().

11709 {
11710  struct vm_zone *zcur;
11711  AST_LIST_LOCK(&zones);
11712  while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list)))
11713  free_zone(zcur);
11715 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static void free_zone(struct vm_zone *z)
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct vm_zone::@66 list
static void free_zone ( struct vm_zone z)
static

Definition at line 5105 of file app_voicemail_odbcstorage.c.

References ast_free.

Referenced by free_vm_zones().

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

Gets the current date and time, as formatted string.

Parameters
sThe buffer to hold the output formatted date.
lenthe length of the buffer. Used to prevent buffer overflow in ast_strftime.

The date format string used is "%a %b %e %r UTC %Y".

Returns
zero on success, -1 on error.

Definition at line 5061 of file app_voicemail_odbcstorage.c.

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

Referenced by leave_voicemail().

5062 {
5063  struct ast_tm tm;
5064  struct timeval t = ast_tvnow();
5065 
5066  ast_localtime(&t, &tm, "UTC");
5067 
5068  return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm);
5069 }
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
static int get_folder ( struct ast_channel chan,
int  start 
)
static

get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized

Definition at line 6796 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_fileexists(), ast_play_and_wait(), ast_say_number(), ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().

Referenced by get_folder2().

6797 {
6798  int x;
6799  int d;
6800  char fn[PATH_MAX];
6801  d = ast_play_and_wait(chan, "vm-press"); /* "Press" */
6802  if (d)
6803  return d;
6804  for (x = start; x < 5; x++) { /* For all folders */
6805  if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL)))
6806  return d;
6807  d = ast_play_and_wait(chan, "vm-for"); /* "for" */
6808  if (d)
6809  return d;
6810  snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */
6811 
6812  /* The inbox folder can have its name changed under certain conditions
6813  * so this checks if the sound file exists for the inbox folder name and
6814  * if it doesn't, plays the default name instead. */
6815  if (x == 0) {
6816  if (ast_fileexists(fn, NULL, NULL)) {
6817  d = vm_play_folder_name(chan, fn);
6818  } else {
6819  ast_verb(1, "failed to find %s\n", fn);
6820  d = vm_play_folder_name(chan, "vm-INBOX");
6821  }
6822  } else {
6823  ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn);
6824  d = vm_play_folder_name(chan, fn);
6825  }
6826 
6827  if (d)
6828  return d;
6829  d = ast_waitfordigit(chan, 500);
6830  if (d)
6831  return d;
6832  }
6833 
6834  d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
6835  if (d)
6836  return d;
6837  d = ast_waitfordigit(chan, 4000);
6838  return d;
6839 }
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_verb(level,...)
Definition: logger.h:243
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static const char * mbox(struct ast_vm_user *vmu, int id)
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
const ast_string_field language
Definition: channel.h:787
static int get_folder2 ( struct ast_channel chan,
char *  fn,
int  start 
)
static

plays a prompt and waits for a keypress.

Parameters
chan
fnthe name of the voice prompt file to be played. For example, 'vm-changeto', 'vm-savefolder'
startDoes not appear to be used at this time.

This is used by the main menu option to move a message to a folder or to save a message into a folder. After playing the message identified by the fn parameter value, it calls get_folder(), which plays the prompting for the number inputs that correspond to the available folders.

Returns
zero on success, or -1 on error.

Definition at line 6853 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().

Referenced by vm_execmain().

6854 {
6855  int res = 0;
6856  int loops = 0;
6857 
6858  res = ast_play_and_wait(chan, fn); /* Folder name */
6859  while (((res < '0') || (res > '9')) &&
6860  (res != '#') && (res >= 0) &&
6861  loops < 4) {
6862  res = get_folder(chan, 0);
6863  loops++;
6864  }
6865  if (loops == 4) { /* give up */
6866  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#');
6867  return '#';
6868  }
6869  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
6870  return res;
6871 }
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static int get_folder(struct ast_channel *chan, int start)
get_folder: Folder menu Plays &quot;press 1 for INBOX messages&quot; etc. Should possibly be internationalized ...
static int get_folder_by_name ( const char *  name)
static

Definition at line 1721 of file app_voicemail_odbcstorage.c.

References ARRAY_LEN.

Referenced by vm_execmain().

1722 {
1723  size_t i;
1724 
1725  for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) {
1726  if (strcasecmp(name, mailbox_folders[i]) == 0) {
1727  return i;
1728  }
1729  }
1730 
1731  return -1;
1732 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const char name[]
static const char *const mailbox_folders[]
static int handle_subscribe ( void *  datap)
static

Definition at line 11466 of file app_voicemail_odbcstorage.c.

References ast_calloc, ast_free, AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), mwi_sub_task::context, len(), mwi_sub_task::mailbox, mwi_sub, poll_subscribed_mailbox(), and mwi_sub_task::uniqueid.

Referenced by mwi_sub_event_cb().

11467 {
11468  unsigned int len;
11469  struct mwi_sub *mwi_sub;
11470  struct mwi_sub_task *p = datap;
11471 
11472  len = sizeof(*mwi_sub);
11473  if (!ast_strlen_zero(p->mailbox))
11474  len += strlen(p->mailbox);
11475 
11476  if (!ast_strlen_zero(p->context))
11477  len += strlen(p->context) + 1; /* Allow for seperator */
11478 
11479  if (!(mwi_sub = ast_calloc(1, len)))
11480  return -1;
11481 
11482  mwi_sub->uniqueid = p->uniqueid;
11483  if (!ast_strlen_zero(p->mailbox))
11484  strcpy(mwi_sub->mailbox, p->mailbox);
11485 
11486  if (!ast_strlen_zero(p->context)) {
11487  strcat(mwi_sub->mailbox, "@");
11488  strcat(mwi_sub->mailbox, p->context);
11489  }
11490 
11492  AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry);
11494  ast_free((void *) p->mailbox);
11495  ast_free((void *) p->context);
11496  ast_free(p);
11497  poll_subscribed_mailbox(mwi_sub);
11498  return 0;
11499 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
const char * context
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
An MWI subscription.
const char * mailbox
static struct ast_event_sub * mwi_sub
Definition: res_jabber.c:394
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
uint32_t uniqueid
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:97
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
static void poll_subscribed_mailbox(struct mwi_sub *mwi_sub)
static int handle_unsubscribe ( void *  datap)
static

Definition at line 11444 of file app_voicemail_odbcstorage.c.

References ast_free, AST_LIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, mwi_sub, and mwi_sub_destroy().

Referenced by mwi_unsub_event_cb().

11445 {
11446  struct mwi_sub *mwi_sub;
11447  uint32_t *uniqueid = datap;
11448 
11450  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) {
11451  if (mwi_sub->uniqueid == *uniqueid) {
11452  AST_LIST_REMOVE_CURRENT(entry);
11453  break;
11454  }
11455  }
11458 
11459  if (mwi_sub)
11460  mwi_sub_destroy(mwi_sub);
11461 
11462  ast_free(uniqueid);
11463  return 0;
11464 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
An MWI subscription.
static struct ast_event_sub * mwi_sub
Definition: res_jabber.c:394
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define ast_free(a)
Definition: astmm.h:97
static void mwi_sub_destroy(struct mwi_sub *mwi_sub)
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
static char* handle_voicemail_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Reload voicemail configuration from the CLI.

Definition at line 11221 of file app_voicemail_odbcstorage.c.

References ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, load_config(), and ast_cli_entry::usage.

11222 {
11223  switch (cmd) {
11224  case CLI_INIT:
11225  e->command = "voicemail reload";
11226  e->usage =
11227  "Usage: voicemail reload\n"
11228  " Reload voicemail configuration\n";
11229  return NULL;
11230  case CLI_GENERATE:
11231  return NULL;
11232  }
11233 
11234  if (a->argc != 2)
11235  return CLI_SHOWUSAGE;
11236 
11237  ast_cli(a->fd, "Reloading voicemail configuration...\n");
11238  load_config(1);
11239 
11240  return CLI_SUCCESS;
11241 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int load_config(int reload)
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_voicemail_show_users ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Show a list of voicemail users in the CLI.

Definition at line 11109 of file app_voicemail_odbcstorage.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_check_realtime(), ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_voicemail_show_users(), ast_vm_user::context, ast_cli_args::fd, ast_vm_user::fullname, HVSU_OUTPUT_FORMAT, inboxcount(), ast_cli_args::line, ast_vm_user::mailbox, ast_cli_args::n, ast_cli_args::pos, show_users_realtime(), ast_cli_entry::usage, ast_cli_args::word, and ast_vm_user::zonetag.

11110 {
11111  struct ast_vm_user *vmu;
11112 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n"
11113  const char *context = NULL;
11114  int users_counter = 0;
11115 
11116  switch (cmd) {
11117  case CLI_INIT:
11118  e->command = "voicemail show users";
11119  e->usage =
11120  "Usage: voicemail show users [for <context>]\n"
11121  " Lists all mailboxes currently set up\n";
11122  return NULL;
11123  case CLI_GENERATE:
11124  return complete_voicemail_show_users(a->line, a->word, a->pos, a->n);
11125  }
11126 
11127  if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
11128  return CLI_SHOWUSAGE;
11129  if (a->argc == 5) {
11130  if (strcmp(a->argv[3],"for"))
11131  return CLI_SHOWUSAGE;
11132  context = a->argv[4];
11133  }
11134 
11135  if (ast_check_realtime("voicemail")) {
11136  if (!context) {
11137  ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n");
11138  return CLI_SHOWUSAGE;
11139  }
11140  return show_users_realtime(a->fd, context);
11141  }
11142 
11143  AST_LIST_LOCK(&users);
11144  if (AST_LIST_EMPTY(&users)) {
11145  ast_cli(a->fd, "There are no voicemail users currently defined\n");
11147  return CLI_FAILURE;
11148  }
11149  if (!context) {
11150  ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg");
11151  } else {
11152  int count = 0;
11153  AST_LIST_TRAVERSE(&users, vmu, list) {
11154  if (!strcmp(context, vmu->context)) {
11155  count++;
11156  break;
11157  }
11158  }
11159  if (count) {
11160  ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg");
11161  } else {
11162  ast_cli(a->fd, "No such voicemail context \"%s\"\n", context);
11164  return CLI_FAILURE;
11165  }
11166  }
11167  AST_LIST_TRAVERSE(&users, vmu, list) {
11168  int newmsgs = 0, oldmsgs = 0;
11169  char count[12], tmp[256] = "";
11170 
11171  if (!context || !strcmp(context, vmu->context)) {
11172  snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
11173  inboxcount(tmp, &newmsgs, &oldmsgs);
11174  snprintf(count, sizeof(count), "%d", newmsgs);
11175  ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
11176  users_counter++;
11177  }
11178  }
11180  ast_cli(a->fd, "%d voicemail users configured.\n", users_counter);
11181  return CLI_SUCCESS;
11182 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char fullname[80]
const int argc
Definition: cli.h:154
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
Definition: cli.h:146
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define HVSU_OUTPUT_FORMAT
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
list of users found in the config file
const char * line
Definition: cli.h:156
struct ast_vm_user::@65 list
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const int n
Definition: cli.h:159
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
char zonetag[80]
static char * show_users_realtime(int fd, const char *context)
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
const int pos
Definition: cli.h:158
static char * complete_voicemail_show_users(const char *line, const char *word, int pos, int state)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
static char* handle_voicemail_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 11185 of file app_voicemail_odbcstorage.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, HVSZ_OUTPUT_FORMAT, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.

11186 {
11187  struct vm_zone *zone;
11188 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
11189  char *res = CLI_SUCCESS;
11190 
11191  switch (cmd) {
11192  case CLI_INIT:
11193  e->command = "voicemail show zones";
11194  e->usage =
11195  "Usage: voicemail show zones\n"
11196  " Lists zone message formats\n";
11197  return NULL;
11198  case CLI_GENERATE:
11199  return NULL;
11200  }
11201 
11202  if (a->argc != 3)
11203  return CLI_SHOWUSAGE;
11204 
11205  AST_LIST_LOCK(&zones);
11206  if (!AST_LIST_EMPTY(&zones)) {
11207  ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format");
11208  AST_LIST_TRAVERSE(&zones, zone, list) {
11209  ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format);
11210  }
11211  } else {
11212  ast_cli(a->fd, "There are no voicemail zones currently defined\n");
11213  res = CLI_FAILURE;
11214  }
11216 
11217  return res;
11218 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char msg_format[512]
char name[80]
const int argc
Definition: cli.h:154
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char timezone[80]
Definition: cli.h:146
#define HVSZ_OUTPUT_FORMAT
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
struct vm_zone::@66 list
static int has_voicemail ( const char *  mailbox,
const char *  folder 
)
static

Determines if the given folder has messages.

Parameters
mailboxThe @ delimited string for user. If no context is found, uses 'default' for the context.
folderthe folder to look in

This function is used when the mailbox is stored in a filesystem back end. This invokes the __has_voicemail(). Here we are interested in the presence of messages (> 0) only, not the actual count.

Returns
1 if the folder has one or more messages. zero otherwise.

Definition at line 5449 of file app_voicemail_odbcstorage.c.

References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), context, and strsep().

Referenced by load_module(), and vm_execmain().

5450 {
5451  char tmp[256], *tmp2 = tmp, *box, *context;
5452  ast_copy_string(tmp, mailbox, sizeof(tmp));
5453  if (ast_strlen_zero(folder)) {
5454  folder = "INBOX";
5455  }
5456  while ((box = strsep(&tmp2, ",&"))) {
5457  if ((context = strchr(box, '@')))
5458  *context++ = '\0';
5459  else
5460  context = "default";
5461  if (__has_voicemail(context, box, folder, 1))
5462  return 1;
5463  /* If we are checking INBOX, we should check Urgent as well */
5464  if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) {
5465  return 1;
5466  }
5467  }
5468  return 0;
5469 }
char * strsep(char **str, const char *delims)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int inboxcount ( const char *  mailbox,
int *  newmsgs,
int *  oldmsgs 
)
static

Definition at line 5531 of file app_voicemail_odbcstorage.c.

References inboxcount2().

Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().

5532 {
5533  int urgentmsgs = 0;
5534  int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs);
5535  if (newmsgs) {
5536  *newmsgs += urgentmsgs;
5537  }
5538  return res;
5539 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int inboxcount2 ( const char *  mailbox,
int *  urgentmsgs,
int *  newmsgs,
int *  oldmsgs 
)
static

Definition at line 5472 of file app_voicemail_odbcstorage.c.

References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), context, and strsep().

Referenced by append_mailbox(), inboxcount(), load_module(), poll_subscribed_mailbox(), run_externnotify(), and vm_users_data_provider_get_helper().

5473 {
5474  char tmp[256];
5475  char *context;
5476 
5477  /* If no mailbox, return immediately */
5478  if (ast_strlen_zero(mailbox))
5479  return 0;
5480 
5481  if (newmsgs)
5482  *newmsgs = 0;
5483  if (oldmsgs)
5484  *oldmsgs = 0;
5485  if (urgentmsgs)
5486  *urgentmsgs = 0;
5487 
5488  if (strchr(mailbox, ',')) {
5489  int tmpnew, tmpold, tmpurgent;
5490  char *mb, *cur;
5491 
5492  ast_copy_string(tmp, mailbox, sizeof(tmp));
5493  mb = tmp;
5494  while ((cur = strsep(&mb, ", "))) {
5495  if (!ast_strlen_zero(cur)) {
5496  if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
5497  return -1;
5498  else {
5499  if (newmsgs)
5500  *newmsgs += tmpnew;
5501  if (oldmsgs)
5502  *oldmsgs += tmpold;
5503  if (urgentmsgs)
5504  *urgentmsgs += tmpurgent;
5505  }
5506  }
5507  }
5508  return 0;
5509  }
5510 
5511  ast_copy_string(tmp, mailbox, sizeof(tmp));
5512 
5513  if ((context = strchr(tmp, '@')))
5514  *context++ = '\0';
5515  else
5516  context = "default";
5517 
5518  if (newmsgs)
5519  *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
5520  if (oldmsgs)
5521  *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
5522  if (urgentmsgs)
5523  *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0);
5524 
5525  return 0;
5526 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
char * strsep(char **str, const char *delims)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int inbuf ( struct baseio bio,
FILE *  fi 
)
static

utility used by inchar(), for base_encode()

Definition at line 4231 of file app_voicemail_odbcstorage.c.

References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.

Referenced by inchar().

4232 {
4233  int l;
4234 
4235  if (bio->ateof)
4236  return 0;
4237 
4238  if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) {
4239  if (ferror(fi))
4240  return -1;
4241 
4242  bio->ateof = 1;
4243  return 0;
4244  }
4245 
4246  bio->iolen = l;
4247  bio->iocp = 0;
4248 
4249  return 1;
4250 }
#define BASEMAXINLINE
unsigned char iobuf[BASEMAXINLINE]
static int inchar ( struct baseio bio,
FILE *  fi 
)
static

utility used by base_encode()

Definition at line 4255 of file app_voicemail_odbcstorage.c.

References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.

Referenced by base_encode().

4256 {
4257  if (bio->iocp>=bio->iolen) {
4258  if (!inbuf(bio, fi))
4259  return EOF;
4260  }
4261 
4262  return bio->iobuf[bio->iocp++];
4263 }
static int inbuf(struct baseio *bio, FILE *fi)
utility used by inchar(), for base_encode()
unsigned char iobuf[BASEMAXINLINE]
static int inprocess_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 916 of file app_voicemail_odbcstorage.c.

References CMP_MATCH, inprocess::context, and inprocess::mailbox.

Referenced by load_module().

917 {
918  struct inprocess *i = obj, *j = arg;
919  if (strcmp(i->mailbox, j->mailbox)) {
920  return 0;
921  }
922  return !strcmp(i->context, j->context) ? CMP_MATCH : 0;
923 }
char * context
char mailbox[0]
static int inprocess_count ( const char *  context,
const char *  mailbox,
int  delta 
)
static

Definition at line 925 of file app_voicemail_odbcstorage.c.

References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_alloca, ast_atomic_fetchadd_int(), ast_log(), inprocess::context, inprocess::count, LOG_WARNING, and inprocess::mailbox.

Referenced by copy_message(), forward_message(), and leave_voicemail().

926 {
927  struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2);
928  arg->context = arg->mailbox + strlen(mailbox) + 1;
929  strcpy(arg->mailbox, mailbox); /* SAFE */
930  strcpy(arg->context, context); /* SAFE */
932  if ((i = ao2_find(inprocess_container, arg, 0))) {
933  int ret = ast_atomic_fetchadd_int(&i->count, delta);
935  ao2_ref(i, -1);
936  return ret;
937  }
938  if (delta < 0) {
939  ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n");
940  }
941  if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) {
943  return 0;
944  }
945  i->context = i->mailbox + strlen(mailbox) + 1;
946  strcpy(i->mailbox, mailbox); /* SAFE */
947  strcpy(i->context, context); /* SAFE */
948  i->count = delta;
951  ao2_ref(i, -1);
952  return 0;
953 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define LOG_WARNING
Definition: logger.h:144
#define ao2_unlock(a)
Definition: astobj2.h:497
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
char * context
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
char mailbox[0]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
struct ao2_container * inprocess_container
static int inprocess_hash_fn ( const void *  obj,
const int  flags 
)
static

Definition at line 910 of file app_voicemail_odbcstorage.c.

References inprocess::mailbox.

Referenced by load_module().

911 {
912  const struct inprocess *i = obj;
913  return atoi(i->mailbox);
914 }
char mailbox[0]
static int invent_message ( struct ast_channel chan,
char *  context,
char *  ext,
int  busy,
char *  ecodes 
)
static

Definition at line 5071 of file app_voicemail_odbcstorage.c.

References ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, ast_channel::language, and RETRIEVE.

Referenced by leave_voicemail().

5072 {
5073  int res;
5074  char fn[PATH_MAX];
5075  char dest[PATH_MAX];
5076 
5077  snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
5078 
5079  if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) {
5080  ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn);
5081  return -1;
5082  }
5083 
5084  RETRIEVE(fn, -1, ext, context);
5085  if (ast_fileexists(fn, NULL, NULL) > 0) {
5086  res = ast_stream_and_wait(chan, fn, ecodes);
5087  if (res) {
5088  DISPOSE(fn, -1);
5089  return res;
5090  }
5091  } else {
5092  /* Dispose just in case */
5093  DISPOSE(fn, -1);
5094  res = ast_stream_and_wait(chan, "vm-theperson", ecodes);
5095  if (res)
5096  return res;
5097  res = ast_say_digit_str(chan, ext, ecodes, chan->language);
5098  if (res)
5099  return res;
5100  }
5101  res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes);
5102  return res;
5103 }
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
#define AST_LOG_WARNING
Definition: logger.h:149
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8415
const char * ext
Definition: http.c:112
#define RETRIEVE(a, b, c, d)
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
#define DISPOSE(a, b)
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
static int is_valid_dtmf ( const char *  key)
static

Determines if a DTMF key entered is valid.

Parameters
keyThe character to be compared. expects a single character. Though is capable of handling a string, this is internally copies using ast_strdupa.

Tests the character entered against the set of valid DTMF characters.

Returns
1 if the character entered is a valid DTMF digit, 0 if the character is invalid.

Definition at line 1352 of file app_voicemail_odbcstorage.c.

References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.

Referenced by actual_load_config().

1353 {
1354  int i;
1355  char *local_key = ast_strdupa(key);
1356 
1357  for (i = 0; i < strlen(key); ++i) {
1358  if (!strchr(VALID_DTMF, *local_key)) {
1359  ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key);
1360  return 0;
1361  }
1362  local_key++;
1363  }
1364  return 1;
1365 }
#define VALID_DTMF
#define AST_LOG_WARNING
Definition: logger.h:149
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int last_message_index ( struct ast_vm_user vmu,
char *  dir 
)
static

Determines the highest message number in use for a given user and mailbox folder.

Parameters
vmu
dirthe folder the mailbox folder to look for messages. Used to construct the SQL where clause.

This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). Typical use to set the msgnum would be to take the value returned from this method and add one to it.

Note
Should always be called with a lock already set on dir.
Returns
the value of zero or greaterto indicate the last message index in use, -1 to indicate none.

Definition at line 4050 of file app_voicemail_odbcstorage.c.

References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.

Referenced by close_mailbox(), copy_message(), leave_voicemail(), open_mailbox(), and save_to_folder().

4051 {
4052  int x;
4053  unsigned char map[MAXMSGLIMIT] = "";
4054  DIR *msgdir;
4055  struct dirent *msgdirent;
4056  int msgdirint;
4057  char extension[4];
4058  int stopcount = 0;
4059 
4060  /* Reading the entire directory into a file map scales better than
4061  * doing a stat repeatedly on a predicted sequence. I suspect this
4062  * is partially due to stat(2) internally doing a readdir(2) itself to
4063  * find each file. */
4064  if (!(msgdir = opendir(dir))) {
4065  return -1;
4066  }
4067 
4068  while ((msgdirent = readdir(msgdir))) {
4069  if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) {
4070  map[msgdirint] = 1;
4071  stopcount++;
4072  ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount);
4073  }
4074  }
4075  closedir(msgdir);
4076 
4077  for (x = 0; x < vmu->maxmsg; x++) {
4078  if (map[x] == 1) {
4079  stopcount--;
4080  } else if (map[x] == 0 && !stopcount) {
4081  break;
4082  }
4083  }
4084 
4085  return x - 1;
4086 }
static int * map
Definition: misdn_config.c:434
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define MAXMSGLIMIT
static int leave_voicemail ( struct ast_channel chan,
char *  ext,
struct leave_vm_options options 
)
static

Prompts the user and records a voicemail to a mailbox.

Parameters
chan
ext
optionsOPT_BUSY_GREETING, OPT_UNAVAIL_GREETING
Returns
zero on success, -1 on error.

Definition at line 5607 of file app_voicemail_odbcstorage.c.

References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verb, ast_waitstream(), ast_channel::caller, context, ast_vm_user::context, ast_channel::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, ast_vm_user::exit, leave_vm_options::exitcontext, exten, ast_channel::exten, find_user(), free_user(), ast_party_redirecting::from, get_date(), ast_party_caller::id, inboxcount(), inprocess_count(), INTRO, invent_message(), ast_channel::language, last_message_index(), LOG_DEBUG, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, ast_party_id::name, ast_channel::name, vm_state::newmessages, notify_new_message(), ast_party_id::number, OPERATOR_EXIT, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, option_debug, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, ast_channel::redirecting, RENAME, RETRIEVE, S_COR, S_OR, SENTINEL, STORE, ast_party_name::str, ast_party_number::str, strsep(), transfer, ast_party_name::valid, ast_party_number::valid, vm_lock_path(), VM_OPERATOR, VOICEMAIL_DIR_MODE, and VOICEMAIL_FILE_MODE.

Referenced by advanced_options(), forward_message(), and vm_exec().

5608 {
5609 #ifdef IMAP_STORAGE
5610  int newmsgs, oldmsgs;
5611 #else
5612  char urgdir[PATH_MAX];
5613 #endif
5614  char txtfile[PATH_MAX];
5615  char tmptxtfile[PATH_MAX];
5616  struct vm_state *vms = NULL;
5617  char callerid[256];
5618  FILE *txt;
5619  char date[256];
5620  int txtdes;
5621  int res = 0;
5622  int msgnum;
5623  int duration = 0;
5624  int sound_duration = 0;
5625  int ausemacro = 0;
5626  int ousemacro = 0;
5627  int ouseexten = 0;
5628  char tmpdur[16];
5629  char priority[16];
5630  char origtime[16];
5631  char dir[PATH_MAX];
5632  char tmpdir[PATH_MAX];
5633  char fn[PATH_MAX];
5634  char prefile[PATH_MAX] = "";
5635  char tempfile[PATH_MAX] = "";
5636  char ext_context[256] = "";
5637  char fmt[80];
5638  char *context;
5639  char ecodes[17] = "#";
5640  struct ast_str *tmp = ast_str_create(16);
5641  char *tmpptr;
5642  struct ast_vm_user *vmu;
5643  struct ast_vm_user svm;
5644  const char *category = NULL;
5645  const char *code;
5646  const char *alldtmf = "0123456789ABCD*#";
5647  char flag[80];
5648 
5649  if (!tmp) {
5650  return -1;
5651  }
5652 
5653  ast_str_set(&tmp, 0, "%s", ext);
5654  ext = ast_str_buffer(tmp);
5655  if ((context = strchr(ext, '@'))) {
5656  *context++ = '\0';
5657  tmpptr = strchr(context, '&');
5658  } else {
5659  tmpptr = strchr(ext, '&');
5660  }
5661 
5662  if (tmpptr)
5663  *tmpptr++ = '\0';
5664 
5665  ast_channel_lock(chan);
5666  if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) {
5667  category = ast_strdupa(category);
5668  }
5669  ast_channel_unlock(chan);
5670 
5671  if (ast_test_flag(options, OPT_MESSAGE_Urgent)) {
5672  ast_copy_string(flag, "Urgent", sizeof(flag));
5673  } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) {
5674  ast_copy_string(flag, "PRIORITY", sizeof(flag));
5675  } else {
5676  flag[0] = '\0';
5677  }
5678 
5679  ast_debug(3, "Before find_user\n");
5680  if (!(vmu = find_user(&svm, context, ext))) {
5681  ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext);
5682  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
5683  ast_free(tmp);
5684  return res;
5685  }
5686  /* Setup pre-file if appropriate */
5687  if (strcmp(vmu->context, "default"))
5688  snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context);
5689  else
5690  ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context));
5691 
5692  /* Set the path to the prefile. Will be one of
5693  VM_SPOOL_DIRcontext/ext/busy
5694  VM_SPOOL_DIRcontext/ext/unavail
5695  Depending on the flag set in options.
5696  */
5697  if (ast_test_flag(options, OPT_BUSY_GREETING)) {
5698  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext);
5699  } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) {
5700  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext);
5701  }
5702  /* Set the path to the tmpfile as
5703  VM_SPOOL_DIR/context/ext/temp
5704  and attempt to create the folder structure.
5705  */
5706  snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext);
5707  if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) {
5708  ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile);
5709  ast_free(tmp);
5710  return -1;
5711  }
5712  RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context);
5713  if (ast_fileexists(tempfile, NULL, NULL) > 0)
5714  ast_copy_string(prefile, tempfile, sizeof(prefile));
5715 
5716  DISPOSE(tempfile, -1);
5717  /* It's easier just to try to make it than to check for its existence */
5718 #ifndef IMAP_STORAGE
5719  create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX");
5720 #else
5721  snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR);
5722  if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) {
5723  ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno));
5724  }
5725 #endif
5726 
5727  /* Check current or macro-calling context for special extensions */
5728  if (ast_test_flag(vmu, VM_OPERATOR)) {
5729  if (!ast_strlen_zero(vmu->exit)) {
5730  if (ast_exists_extension(chan, vmu->exit, "o", 1,
5731  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5732  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
5733  ouseexten = 1;
5734  }
5735  } else if (ast_exists_extension(chan, chan->context, "o", 1,
5736  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5737  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
5738  ouseexten = 1;
5739  } else if (!ast_strlen_zero(chan->macrocontext)
5740  && ast_exists_extension(chan, chan->macrocontext, "o", 1,
5741  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5742  strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1);
5743  ousemacro = 1;
5744  }
5745  }
5746 
5747  if (!ast_strlen_zero(vmu->exit)) {
5748  if (ast_exists_extension(chan, vmu->exit, "a", 1,
5749  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5750  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
5751  }
5752  } else if (ast_exists_extension(chan, chan->context, "a", 1,
5753  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5754  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
5755  } else if (!ast_strlen_zero(chan->macrocontext)
5756  && ast_exists_extension(chan, chan->macrocontext, "a", 1,
5757  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5758  strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1);
5759  ausemacro = 1;
5760  }
5761 
5762  if (ast_test_flag(options, OPT_DTMFEXIT)) {
5763  for (code = alldtmf; *code; code++) {
5764  char e[2] = "";
5765  e[0] = *code;
5766  if (strchr(ecodes, e[0]) == NULL
5767  && ast_canmatch_extension(chan,
5768  (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context),
5769  e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
5770  strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1);
5771  }
5772  }
5773  }
5774 
5775  /* Play the beginning intro if desired */
5776  if (!ast_strlen_zero(prefile)) {
5777 #ifdef ODBC_STORAGE
5778  int success =
5779 #endif
5780  RETRIEVE(prefile, -1, ext, context);
5781  if (ast_fileexists(prefile, NULL, NULL) > 0) {
5782  if (ast_streamfile(chan, prefile, chan->language) > -1)
5783  res = ast_waitstream(chan, ecodes);
5784 #ifdef ODBC_STORAGE
5785  if (success == -1) {
5786  /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */
5787  ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n");
5788  store_file(prefile, vmu->mailbox, vmu->context, -1);
5789  }
5790 #endif
5791  } else {
5792  ast_debug(1, "%s doesn't exist, doing what we can\n", prefile);
5793  res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes);
5794  }
5795  DISPOSE(prefile, -1);
5796  if (res < 0) {
5797  ast_debug(1, "Hang up during prefile playback\n");
5798  free_user(vmu);
5799  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
5800  ast_free(tmp);
5801  return -1;
5802  }
5803  }
5804  if (res == '#') {
5805  /* On a '#' we skip the instructions */
5806  ast_set_flag(options, OPT_SILENT);
5807  res = 0;
5808  }
5809  /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */
5810  if (vmu->maxmsg == 0) {
5811  if (option_debug > 2)
5812  ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n");
5813  pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
5814  goto leave_vm_out;
5815  }
5816  if (!res && !ast_test_flag(options, OPT_SILENT)) {
5817  res = ast_stream_and_wait(chan, INTRO, ecodes);
5818  if (res == '#') {
5819  ast_set_flag(options, OPT_SILENT);
5820  res = 0;
5821  }
5822  }
5823  if (res > 0)
5824  ast_stopstream(chan);
5825  /* Check for a '*' here in case the caller wants to escape from voicemail to something
5826  other than the operator -- an automated attendant or mailbox login for example */
5827  if (res == '*') {
5828  chan->exten[0] = 'a';
5829  chan->exten[1] = '\0';
5830  if (!ast_strlen_zero(vmu->exit)) {
5831  ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
5832  } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) {
5833  ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
5834  }
5835  chan->priority = 0;
5836  free_user(vmu);
5837  pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
5838  ast_free(tmp);
5839  return 0;
5840  }
5841 
5842  /* Check for a '0' here */
5843  if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') {
5844  transfer:
5845  if (ouseexten || ousemacro) {
5846  chan->exten[0] = 'o';
5847  chan->exten[1] = '\0';
5848  if (!ast_strlen_zero(vmu->exit)) {
5849  ast_copy_string(chan->context, vmu->exit, sizeof(chan->context));
5850  } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) {
5851  ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context));
5852  }
5853  ast_play_and_wait(chan, "transfer");
5854  chan->priority = 0;
5855  free_user(vmu);
5856  pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
5857  }
5858  ast_free(tmp);
5859  return OPERATOR_EXIT;
5860  }
5861 
5862  /* Allow all other digits to exit Voicemail and return to the dialplan */
5863  if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) {
5864  if (!ast_strlen_zero(options->exitcontext)) {
5865  ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context));
5866  }
5867  free_user(vmu);
5868  ast_free(tmp);
5869  pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT");
5870  return res;
5871  }
5872 
5873  if (res < 0) {
5874  free_user(vmu);
5875  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
5876  ast_free(tmp);
5877  return -1;
5878  }
5879  /* The meat of recording the message... All the announcements and beeps have been played*/
5880  ast_copy_string(fmt, vmfmts, sizeof(fmt));
5881  if (!ast_strlen_zero(fmt)) {
5882  msgnum = 0;
5883 
5884 #ifdef IMAP_STORAGE
5885  /* Is ext a mailbox? */
5886  /* must open stream for this user to get info! */
5887  res = inboxcount(ext_context, &newmsgs, &oldmsgs);
5888  if (res < 0) {
5889  ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n");
5890  ast_free(tmp);
5891  return -1;
5892  }
5893  if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) {
5894  /* It is possible under certain circumstances that inboxcount did not
5895  * create a vm_state when it was needed. This is a catchall which will
5896  * rarely be used.
5897  */
5898  if (!(vms = create_vm_state_from_user(vmu))) {
5899  ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n");
5900  ast_free(tmp);
5901  return -1;
5902  }
5903  }
5904  vms->newmessages++;
5905 
5906  /* here is a big difference! We add one to it later */
5907  msgnum = newmsgs + oldmsgs;
5908  ast_debug(3, "Messagecount set to %d\n", msgnum);
5909  snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum);
5910  /* set variable for compatibility */
5911  pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
5912 
5913  if ((res = imap_check_limits(chan, vms, vmu, msgnum))) {
5914  goto leave_vm_out;
5915  }
5916 #else
5917  if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) {
5918  res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
5919  if (!res)
5920  res = ast_waitstream(chan, "");
5921  ast_log(AST_LOG_WARNING, "No more messages possible\n");
5922  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
5923  inprocess_count(vmu->mailbox, vmu->context, -1);
5924  goto leave_vm_out;
5925  }
5926 
5927 #endif
5928  snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir);
5929  txtdes = mkstemp(tmptxtfile);
5930  chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask);
5931  if (txtdes < 0) {
5932  res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
5933  if (!res)
5934  res = ast_waitstream(chan, "");
5935  ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno));
5936  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
5937  inprocess_count(vmu->mailbox, vmu->context, -1);
5938  goto leave_vm_out;
5939  }
5940 
5941  /* Now play the beep once we have the message number for our next message. */
5942  if (res >= 0) {
5943  /* Unless we're *really* silent, try to send the beep */
5944  res = ast_stream_and_wait(chan, "beep", "");
5945  }
5946 
5947  /* Store information in real-time storage */
5948  if (ast_check_realtime("voicemail_data")) {
5949  snprintf(priority, sizeof(priority), "%d", chan->priority);
5950  snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL));
5951  get_date(date, sizeof(date));
5952  ast_callerid_merge(callerid, sizeof(callerid),
5953  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
5954  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
5955  "Unknown");
5956  ast_store_realtime("voicemail_data",
5957  "origmailbox", ext,
5958  "context", chan->context,
5959  "macrocontext", chan->macrocontext,
5960  "exten", chan->exten,
5961  "priority", priority,
5962  "callerchan", chan->name,
5963  "callerid", callerid,
5964  "origdate", date,
5965  "origtime", origtime,
5966  "category", S_OR(category, ""),
5967  "filename", tmptxtfile,
5968  SENTINEL);
5969  }
5970 
5971  /* Store information */
5972  txt = fdopen(txtdes, "w+");
5973  if (txt) {
5974  get_date(date, sizeof(date));
5975  ast_callerid_merge(callerid, sizeof(callerid),
5976  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
5977  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
5978  "Unknown");
5979  fprintf(txt,
5980  ";\n"
5981  "; Message Information file\n"
5982  ";\n"
5983  "[message]\n"
5984  "origmailbox=%s\n"
5985  "context=%s\n"
5986  "macrocontext=%s\n"
5987  "exten=%s\n"
5988  "rdnis=%s\n"
5989  "priority=%d\n"
5990  "callerchan=%s\n"
5991  "callerid=%s\n"
5992  "origdate=%s\n"
5993  "origtime=%ld\n"
5994  "category=%s\n",
5995  ext,
5996  chan->context,
5997  chan->macrocontext,
5998  chan->exten,
6000  chan->redirecting.from.number.str, "unknown"),
6001  chan->priority,
6002  chan->name,
6003  callerid,
6004  date, (long) time(NULL),
6005  category ? category : "");
6006  } else {
6007  ast_log(AST_LOG_WARNING, "Error opening text file for output\n");
6008  inprocess_count(vmu->mailbox, vmu->context, -1);
6009  if (ast_check_realtime("voicemail_data")) {
6010  ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL);
6011  }
6012  res = ast_streamfile(chan, "vm-mailboxfull", chan->language);
6013  goto leave_vm_out;
6014  }
6015  res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag);
6016 
6017  if (txt) {
6018  fprintf(txt, "flag=%s\n", flag);
6019  if (sound_duration < vmu->minsecs) {
6020  fclose(txt);
6021  ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs);
6022  ast_filedelete(tmptxtfile, NULL);
6023  unlink(tmptxtfile);
6024  if (ast_check_realtime("voicemail_data")) {
6025  ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL);
6026  }
6027  inprocess_count(vmu->mailbox, vmu->context, -1);
6028  } else {
6029  fprintf(txt, "duration=%d\n", duration);
6030  fclose(txt);
6031  if (vm_lock_path(dir)) {
6032  ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir);
6033  /* Delete files */
6034  ast_filedelete(tmptxtfile, NULL);
6035  unlink(tmptxtfile);
6036  inprocess_count(vmu->mailbox, vmu->context, -1);
6037  } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) {
6038  ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
6039  unlink(tmptxtfile);
6040  ast_unlock_path(dir);
6041  inprocess_count(vmu->mailbox, vmu->context, -1);
6042  if (ast_check_realtime("voicemail_data")) {
6043  ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL);
6044  }
6045  } else {
6046 #ifndef IMAP_STORAGE
6047  msgnum = last_message_index(vmu, dir) + 1;
6048 #endif
6049  make_file(fn, sizeof(fn), dir, msgnum);
6050 
6051  /* assign a variable with the name of the voicemail file */
6052 #ifndef IMAP_STORAGE
6053  pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn);
6054 #else
6055  pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE");
6056 #endif
6057 
6058  snprintf(txtfile, sizeof(txtfile), "%s.txt", fn);
6059  ast_filerename(tmptxtfile, fn, NULL);
6060  rename(tmptxtfile, txtfile);
6061  inprocess_count(vmu->mailbox, vmu->context, -1);
6062 
6063  /* Properly set permissions on voicemail text descriptor file.
6064  Unfortunately mkstemp() makes this file 0600 on most unix systems. */
6065  if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0)
6066  ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno));
6067 
6068  ast_unlock_path(dir);
6069  if (ast_check_realtime("voicemail_data")) {
6070  snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
6071  ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL);
6072  }
6073  /* We must store the file first, before copying the message, because
6074  * ODBC storage does the entire copy with SQL.
6075  */
6076  if (ast_fileexists(fn, NULL, NULL) > 0) {
6077  STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag);
6078  }
6079 
6080  /* Are there to be more recipients of this message? */
6081  while (tmpptr) {
6082  struct ast_vm_user recipu, *recip;
6083  char *exten, *cntx;
6084 
6085  exten = strsep(&tmpptr, "&");
6086  cntx = strchr(exten, '@');
6087  if (cntx) {
6088  *cntx = '\0';
6089  cntx++;
6090  }
6091  if ((recip = find_user(&recipu, cntx, exten))) {
6092  copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag);
6093  free_user(recip);
6094  }
6095  }
6096 #ifndef IMAP_STORAGE
6097  if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */
6098  /* Move the message from INBOX to Urgent folder if this is urgent! */
6099  char sfn[PATH_MAX];
6100  char dfn[PATH_MAX];
6101  int x;
6102  /* It's easier just to try to make it than to check for its existence */
6103  create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent");
6104  x = last_message_index(vmu, urgdir) + 1;
6105  make_file(sfn, sizeof(sfn), dir, msgnum);
6106  make_file(dfn, sizeof(dfn), urgdir, x);
6107  ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn);
6108  RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn);
6109  /* Notification must happen for this new message in Urgent folder, not INBOX */
6110  ast_copy_string(fn, dfn, sizeof(fn));
6111  msgnum = x;
6112  }
6113 #endif
6114  /* Notification needs to happen after the copy, though. */
6115  if (ast_fileexists(fn, NULL, NULL)) {
6116 #ifdef IMAP_STORAGE
6117  notify_new_message(chan, vmu, vms, msgnum, duration, fmt,
6118  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
6119  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
6120  flag);
6121 #else
6122  notify_new_message(chan, vmu, NULL, msgnum, duration, fmt,
6123  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
6124  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
6125  flag);
6126 #endif
6127  }
6128 
6129  /* Disposal needs to happen after the optional move and copy */
6130  if (ast_fileexists(fn, NULL, NULL)) {
6131  DISPOSE(dir, msgnum);
6132  }
6133  }
6134  }
6135  } else {
6136  inprocess_count(vmu->mailbox, vmu->context, -1);
6137  }
6138  if (res == '0') {
6139  goto transfer;
6140  } else if (res > 0 && res != 't')
6141  res = 0;
6142 
6143  if (sound_duration < vmu->minsecs)
6144  /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */
6145  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
6146  else
6147  pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS");
6148  } else
6149  ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n");
6150 leave_vm_out:
6151  free_user(vmu);
6152 
6153 #ifdef IMAP_STORAGE
6154  /* expunge message - use UID Expunge if supported on IMAP server*/
6155  ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup);
6156  if (expungeonhangup == 1) {
6157  ast_mutex_lock(&vms->lock);
6158 #ifdef HAVE_IMAP_TK2006
6159  if (LEVELUIDPLUS (vms->mailstream)) {
6160  mail_expunge_full(vms->mailstream, NIL, EX_UID);
6161  } else
6162 #endif
6163  mail_expunge(vms->mailstream);
6164  ast_mutex_unlock(&vms->lock);
6165  }
6166 #endif
6167 
6168  ast_free(tmp);
6169  return res;
6170 }
#define VM_OPERATOR
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_store_realtime(const char *family,...) attribute_sentinel
Create realtime configuration.
Definition: config.c:2726
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
#define INTRO
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char * strsep(char **str, const char *delims)
static int last_message_index(struct ast_vm_user *vmu, char *dir)
Determines the highest message number in use for a given user and mailbox folder. ...
int priority
Definition: channel.h:841
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag)
#define ast_test_flag(p, flag)
Definition: utils.h:63
int option_debug
Definition: asterisk.c:182
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
char fn[PATH_MAX]
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
#define AST_LOG_WARNING
Definition: logger.h:149
#define VOICEMAIL_DIR_MODE
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define LOG_DEBUG
Definition: logger.h:122
const char * ext
Definition: http.c:112
#define ast_verb(level,...)
Definition: logger.h:243
static int transfer
Definition: chan_mgcp.c:187
static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag)
Copies a message from one mailbox to another.
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:5415
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define RETRIEVE(a, b, c, d)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: config.c:2679
#define AST_LOG_NOTICE
Definition: logger.h:138
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define SENTINEL
Definition: compiler.h:75
#define AST_LOG_ERROR
Definition: logger.h:160
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1074
int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Destroy realtime configuration.
Definition: config.c:2750
#define STORE(a, b, c, d, e, f, g, h, i, j)
static int inprocess_count(const char *context, const char *mailbox, int delta)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
char context[AST_MAX_CONTEXT]
static int my_umask
static int notify_new_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msgnum, long duration, char *fmt, char *cidnum, char *cidname, const char *flag)
Sends email notification that a user has a new voicemail waiting for them.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static char VM_SPOOL_DIR[PATH_MAX]
const ast_string_field name
Definition: channel.h:787
static int get_date(char *s, int len)
Gets the current date and time, as formatted string.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char exit[80]
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
#define ast_free(a)
Definition: astmm.h:97
char macrocontext[AST_MAX_CONTEXT]
Definition: channel.h:870
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
static int invent_message(struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes)
static void free_user(struct ast_vm_user *vmu)
static int count_messages(struct ast_vm_user *vmu, char *dir)
Find all .txt files - even if they are not in sequence from 0000.
#define RENAME(a, b, c, d, e, f, g, h)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
signed char record_gain
Definition: app_minivm.c:637
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
#define DISPOSE(a, b)
#define VOICEMAIL_FILE_MODE
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char vmfmts[80]
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
#define OPERATOR_EXIT
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int newmessages
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int load_config ( int  reload)
static

Definition at line 11764 of file app_voicemail_odbcstorage.c.

References actual_load_config(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_unload_realtime(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.

Referenced by handle_voicemail_reload(), load_module(), and reload().

11765 {
11766  struct ast_config *cfg, *ucfg;
11767  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
11768  int res;
11769 
11770  ast_unload_realtime("voicemail");
11771  ast_unload_realtime("voicemail_data");
11772 
11773  if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
11774  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
11775  return 0;
11776  } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
11777  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n");
11778  ucfg = NULL;
11779  }
11780  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11781  if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) {
11782  ast_config_destroy(ucfg);
11783  ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
11784  return 0;
11785  }
11786  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
11787  ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
11788  return 0;
11789  } else {
11790  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11791  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
11792  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n");
11793  ucfg = NULL;
11794  }
11795  }
11796 
11797  res = actual_load_config(reload, cfg, ucfg);
11798 
11799  ast_config_destroy(cfg);
11800  ast_config_destroy(ucfg);
11801 
11802  return res;
11803 }
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: config.c:2630
#define VOICEMAIL_CONFIG
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int reload(void)
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int actual_load_config(int reload, struct ast_config *cfg, struct ast_config *ucfg)
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int load_module ( void  )
static

Definition at line 13065 of file app_voicemail_odbcstorage.c.

References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), AST_LOG_WARNING, ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_hash_fn(), load_config(), manager_list_voicemail_users(), messagecount(), RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_exec(), vm_execmain(), vmauthenticate(), and vmsayname_exec().

13066 {
13067  int res;
13068  my_umask = umask(0);
13069  umask(my_umask);
13070 
13072  return AST_MODULE_LOAD_DECLINE;
13073  }
13074 
13075  /* compute the location of the voicemail spool directory */
13076  snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
13077 
13078  if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) {
13079  ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n");
13080  }
13081 
13082  if ((res = load_config(0)))
13083  return res;
13084 
13092 #ifdef TEST_FRAMEWORK
13093  res |= AST_TEST_REGISTER(test_voicemail_vmsayname);
13094  res |= AST_TEST_REGISTER(test_voicemail_msgcount);
13095  res |= AST_TEST_REGISTER(test_voicemail_vmuser);
13096  res |= AST_TEST_REGISTER(test_voicemail_notify_endl);
13097  res |= AST_TEST_REGISTER(test_voicemail_load_config);
13098 #endif
13099 
13100  if (res)
13101  return res;
13102 
13105 
13107  ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL);
13108  ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL);
13109 
13110  return res;
13111 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
static int vm_exec(struct ast_channel *chan, const char *data)
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int vmauthenticate(struct ast_channel *chan, const char *data)
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
#define AST_LOG_WARNING
Definition: logger.h:149
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static int vm_execmain(struct ast_channel *chan, const char *data)
static int has_voicemail(const char *mailbox, const char *folder)
Determines if the given folder has messages.
static char * app
static int vm_box_exists(struct ast_channel *chan, const char *data)
Definition: config.h:68
#define SENTINEL
Definition: compiler.h:75
static int sayname(struct ast_channel *chan, const char *mailbox, const char *context)
static int load_config(int reload)
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static int my_umask
#define ast_data_register_multiple(data_entries, entries)
Definition: data.h:377
static struct ast_data_entry vm_data_providers[]
static int inprocess_cmp_fn(void *obj, void *arg, int flags)
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char * app4
static int inprocess_hash_fn(const void *obj, const int flags)
const char * ast_config_AST_SPOOL_DIR
Definition: asterisk.c:259
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
Definition: config.c:2606
void ast_install_vm_functions(int(*has_voicemail_func)(const char *mailbox, const char *folder), int(*inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs), int(*inboxcount2_func)(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs), int(*messagecount_func)(const char *context, const char *mailbox, const char *folder), int(*sayname_func)(struct ast_channel *chan, const char *mailbox, const char *context))
Set voicemail function callbacks.
Definition: app.c:399
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static int messagecount(const char *context, const char *mailbox, const char *folder)
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
static int vmsayname_exec(struct ast_channel *chan, const char *data)
static struct ast_cli_entry cli_voicemail[]
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
static char * app3
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static struct ast_custom_function mailbox_exists_acf
static char * app2
static char * sayname_app
static int manager_list_voicemail_users(struct mansession *s, const struct message *m)
Manager list voicemail users command.
static struct ast_taskprocessor * mwi_subscription_tps
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
struct ao2_container * inprocess_container
static int make_dir ( char *  dest,
int  len,
const char *  context,
const char *  ext,
const char *  folder 
)
static

Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.

Parameters
destThe variable to hold the output generated path expression. This buffer should be of size PATH_MAX.
lenThe length of the path string that was written out.
context
ext
folder

The path is constructed as VM_SPOOL_DIRcontext/ext/folder

Returns
zero on success, -1 on error.

Definition at line 1633 of file app_voicemail_odbcstorage.c.

Referenced by copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().

1634 {
1635  return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
1636 }
const char * ext
Definition: http.c:112
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char VM_SPOOL_DIR[PATH_MAX]
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static void make_email_file ( FILE *  p,
char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
const char *  fromfolder,
char *  cidnum,
char *  cidname,
char *  attach,
char *  attach2,
char *  format,
int  duration,
int  attach_user_voicemail,
struct ast_channel chan,
const char *  category,
int  imap,
const char *  flag 
)
static

Creates the email file to be sent to indicate a new voicemail exists for a user.

Parameters
pThe output file to generate the email contents into.
srcemailThe email address to send the email to, presumably the email address for the owner of the mailbox.
vmuThe voicemail user who is sending the voicemail.
msgnumThe message index in the mailbox folder.
context
mailboxThe voicemail box to read the voicemail to be notified in this email.
fromfolder
cidnumThe caller ID number.
cidnameThe caller ID name.
attachthe name of the sound file to be attached to the email, if attach_user_voicemail == 1.
attach2
formatThe message sound file format. i.e. .wav
durationThe time of the message content, in seconds.
attach_user_voicemailif 1, the sound file is attached to the email.
chan
category
imapif == 1, indicates the target folder for the email notification to be sent to will be an IMAP mailstore. This causes additional mailbox headers to be set, which would facilitate searching for the email in the destination IMAP folder.
flagThe email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email. That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function.

Definition at line 4548 of file app_voicemail_odbcstorage.c.

References add_email_attachment(), ast_channel_unref, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, ast_vm_user::emailsubject, emailsubject, ENDL, first_line, ast_vm_user::fullname, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), valid_config(), VM_PBXSKIP, and vmu_tm().

Referenced by sendmail().

4549 {
4550  char date[256];
4551  char host[MAXHOSTNAMELEN] = "";
4552  char who[256];
4553  char bound[256];
4554  char dur[256];
4555  struct ast_tm tm;
4556  char enc_cidnum[256] = "", enc_cidname[256] = "";
4557  struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
4558  char *greeting_attachment;
4559  char filename[256];
4560 
4561  if (!str1 || !str2) {
4562  ast_free(str1);
4563  ast_free(str2);
4564  return;
4565  }
4566 
4567  if (cidnum) {
4568  strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum));
4569  }
4570  if (cidname) {
4571  strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
4572  }
4573  gethostname(host, sizeof(host) - 1);
4574 
4575  if (strchr(srcemail, '@')) {
4576  ast_copy_string(who, srcemail, sizeof(who));
4577  } else {
4578  snprintf(who, sizeof(who), "%s@%s", srcemail, host);
4579  }
4580 
4581  greeting_attachment = strrchr(ast_strdupa(attach), '/');
4582  if (greeting_attachment) {
4583  *greeting_attachment++ = '\0';
4584  }
4585 
4586  snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
4587  ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
4588  fprintf(p, "Date: %s" ENDL, date);
4589 
4590  /* Set date format for voicemail mail */
4591  ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL));
4592 
4593  if (!ast_strlen_zero(fromstring)) {
4594  struct ast_channel *ast;
4595  if ((ast = ast_dummy_channel_alloc())) {
4596  char *ptr;
4597  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag);
4598  ast_str_substitute_variables(&str1, 0, ast, fromstring);
4599 
4600  if (check_mime(ast_str_buffer(str1))) {
4601  int first_line = 1;
4602  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3);
4603  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4604  *ptr = '\0';
4605  fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2));
4606  first_line = 0;
4607  /* Substring is smaller, so this will never grow */
4608  ast_str_set(&str2, 0, "%s", ptr + 1);
4609  }
4610  fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who);
4611  } else {
4612  fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who);
4613  }
4614  ast = ast_channel_unref(ast);
4615  } else {
4616  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4617  }
4618  } else {
4619  fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
4620  }
4621 
4622  if (check_mime(vmu->fullname)) {
4623  int first_line = 1;
4624  char *ptr;
4625  ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3);
4626  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4627  *ptr = '\0';
4628  fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2));
4629  first_line = 0;
4630  /* Substring is smaller, so this will never grow */
4631  ast_str_set(&str2, 0, "%s", ptr + 1);
4632  }
4633  fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email);
4634  } else {
4635  fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email);
4636  }
4637 
4639  char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject;
4640  struct ast_channel *ast;
4641  if ((ast = ast_dummy_channel_alloc())) {
4642  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
4643  ast_str_substitute_variables(&str1, 0, ast, e_subj);
4644  if (check_mime(ast_str_buffer(str1))) {
4645  int first_line = 1;
4646  char *ptr;
4647  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0);
4648  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4649  *ptr = '\0';
4650  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
4651  first_line = 0;
4652  /* Substring is smaller, so this will never grow */
4653  ast_str_set(&str2, 0, "%s", ptr + 1);
4654  }
4655  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
4656  } else {
4657  fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1));
4658  }
4659  ast = ast_channel_unref(ast);
4660  } else {
4661  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4662  }
4663  } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
4664  if (ast_strlen_zero(flag)) {
4665  fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
4666  } else {
4667  fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox);
4668  }
4669  } else {
4670  if (ast_strlen_zero(flag)) {
4671  fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
4672  } else {
4673  fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox);
4674  }
4675  }
4676 
4677  fprintf(p, "Message-ID: <Asterisk-%d-%u-%s-%d@%s>" ENDL, msgnum + 1,
4678  (unsigned int) ast_random(), mailbox, (int) getpid(), host);
4679  if (imap) {
4680  /* additional information needed for IMAP searching */
4681  fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
4682  /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
4683  fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
4684  fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
4685 #ifdef IMAP_STORAGE
4686  fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
4687 #else
4688  fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
4689 #endif
4690  /* flag added for Urgent */
4691  fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag);
4692  fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
4693  fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
4694  fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
4695  fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
4696  fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
4697  if (!ast_strlen_zero(category)) {
4698  fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
4699  } else {
4700  fprintf(p, "X-Asterisk-VM-Category: " ENDL);
4701  }
4702  fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment);
4703  fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
4704  fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL));
4705  }
4706  if (!ast_strlen_zero(cidnum)) {
4707  fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
4708  }
4709  if (!ast_strlen_zero(cidname)) {
4710  fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
4711  }
4712  fprintf(p, "MIME-Version: 1.0" ENDL);
4713  if (attach_user_voicemail) {
4714  /* Something unique. */
4715  snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%u", msgnum + 1, mailbox,
4716  (int) getpid(), (unsigned int) ast_random());
4717 
4718  fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
4719  fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
4720  fprintf(p, "--%s" ENDL, bound);
4721  }
4722  fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
4723  if (emailbody || vmu->emailbody) {
4724  char* e_body = vmu->emailbody ? vmu->emailbody : emailbody;
4725  struct ast_channel *ast;
4726  if ((ast = ast_dummy_channel_alloc())) {
4727  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
4728  ast_str_substitute_variables(&str1, 0, ast, e_body);
4729 #ifdef IMAP_STORAGE
4730  {
4731  /* Convert body to native line terminators for IMAP backend */
4732  char *line = ast_str_buffer(str1), *next;
4733  do {
4734  /* Terminate line before outputting it to the file */
4735  if ((next = strchr(line, '\n'))) {
4736  *next++ = '\0';
4737  }
4738  fprintf(p, "%s" ENDL, line);
4739  line = next;
4740  } while (!ast_strlen_zero(line));
4741  }
4742 #else
4743  fprintf(p, "%s" ENDL, ast_str_buffer(str1));
4744 #endif
4745  ast = ast_channel_unref(ast);
4746  } else {
4747  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4748  }
4749  } else if (msgnum > -1) {
4750  if (strcmp(vmu->mailbox, mailbox)) {
4751  /* Forwarded type */
4752  struct ast_config *msg_cfg;
4753  const char *v;
4754  int inttime;
4755  char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = "";
4756  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
4757  /* Retrieve info from VM attribute file */
4758  make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
4759  make_file(fromfile, sizeof(fromfile), fromdir, msgnum);
4760  if (strlen(fromfile) < sizeof(fromfile) - 5) {
4761  strcat(fromfile, ".txt");
4762  }
4763  if ((msg_cfg = ast_config_load(fromfile, config_flags)) && valid_config(msg_cfg)) {
4764  if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
4765  ast_copy_string(origcallerid, v, sizeof(origcallerid));
4766  }
4767 
4768  /* You might be tempted to do origdate, except that a) it's in the wrong
4769  * format, and b) it's missing for IMAP recordings. */
4770  if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) {
4771  struct timeval tv = { inttime, };
4772  struct ast_tm tm;
4773  ast_localtime(&tv, &tm, NULL);
4774  ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL));
4775  }
4776  fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded"
4777  " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL
4778  "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a"
4779  " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur,
4780  msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")),
4781  date, origcallerid, origdate);
4782  ast_config_destroy(msg_cfg);
4783  } else {
4784  goto plain_message;
4785  }
4786  } else {
4787 plain_message:
4788  fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a "
4789  "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL
4790  "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk"
4791  ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox,
4792  (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
4793  }
4794  } else {
4795  fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL
4796  "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date);
4797  }
4798 
4799  if (imap || attach_user_voicemail) {
4800  if (!ast_strlen_zero(attach2)) {
4801  snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format);
4802  ast_debug(5, "creating second attachment filename %s\n", filename);
4803  add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum);
4804  snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format);
4805  ast_debug(5, "creating attachment filename %s\n", filename);
4806  add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum);
4807  } else {
4808  snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format);
4809  ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename);
4810  add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum);
4811  }
4812  }
4813  ast_free(str1);
4814  ast_free(str2);
4815 }
static const char * ast_str_encode_mime(struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble)
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain ...
Main Channel structure associated with a channel.
Definition: channel.h:742
static struct ast_flags globalflags
static int check_mime(const char *str)
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail sof...
char fullname[80]
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define VM_PBXSKIP
int priority
Definition: channel.h:841
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
static int add_email_attachment(FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum)
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
#define AST_LOG_WARNING
Definition: logger.h:149
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Definition: pbx.c:4468
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
static char charset[32]
#define MAXHOSTNAMELEN
Definition: network.h:69
char locale[20]
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
char * emailsubject
static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static char * emailbody
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char mailbox[AST_MAX_EXTENSION]
static char * strip_control_and_high(const char *input, char *buf, size_t buflen)
Strips control and non 7-bit clean characters from input string.
char context[AST_MAX_CONTEXT]
long int ast_random(void)
Definition: utils.c:1640
int ast_strftime_locale(char *buf, size_t len, const char *format, const struct ast_tm *tm, const char *locale)
Definition: localtime.c:2280
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static struct ast_tm * vmu_tm(const struct ast_vm_user *vmu, struct ast_tm *tm)
fill in *tm for current time according to the proper timezone, if any.
char * emailbody
static char fromstring[100]
static char emaildateformat[32]
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char * ast_str_quote(struct ast_str **buf, ssize_t maxlen, const char *from)
Wraps a character sequence in double quotes, escaping occurences of quotes within the string...
#define ast_free(a)
Definition: astmm.h:97
static char * emailsubject
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct timeval tv
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
static snd_pcm_format_t format
Definition: chan_alsa.c:93
char email[80]
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
yylloc first_line
Definition: ast_expr2.c:1857
#define ENDL
static int make_file ( char *  dest,
const int  len,
const char *  dir,
const int  num 
)
static

Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.

Parameters
destThe variable to hold the output generated path expression. This buffer should be of size PATH_MAX.
lenThe length of the path string that was written out.
dir
num

The path is constructed as VM_SPOOL_DIRcontext/ext/folder

Returns
zero on success, -1 on error.

Definition at line 1650 of file app_voicemail_odbcstorage.c.

Referenced by advanced_options(), close_mailbox(), copy_message(), forward_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), resequence_mailbox(), save_to_folder(), vm_execmain(), and vm_forwardoptions().

1651 {
1652  return snprintf(dest, len, "%s/msg%04d", dir, num);
1653 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int manager_list_voicemail_users ( struct mansession s,
const struct message m 
)
static

Manager list voicemail users command.

Definition at line 11595 of file app_voicemail_odbcstorage.c.

References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_ack(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::context, count_messages(), ast_vm_user::dialout, ast_vm_user::email, ast_vm_user::exit, ast_vm_user::fullname, inboxcount(), ast_vm_user::language, ast_vm_user::mailbox, make_dir(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::pager, RESULT_SUCCESS, ast_vm_user::saydurationm, ast_vm_user::serveremail, ast_vm_user::uniqueid, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_OPERATOR, VM_REVIEW, VM_SAYCID, ast_vm_user::volgain, and ast_vm_user::zonetag.

Referenced by load_module().

11596 {
11597  struct ast_vm_user *vmu = NULL;
11598  const char *id = astman_get_header(m, "ActionID");
11599  char actionid[128] = "";
11600 
11601  if (!ast_strlen_zero(id))
11602  snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id);
11603 
11604  AST_LIST_LOCK(&users);
11605 
11606  if (AST_LIST_EMPTY(&users)) {
11607  astman_send_ack(s, m, "There are no voicemail users currently defined.");
11609  return RESULT_SUCCESS;
11610  }
11611 
11612  astman_send_ack(s, m, "Voicemail user list will follow");
11613 
11614  AST_LIST_TRAVERSE(&users, vmu, list) {
11615  char dirname[256];
11616 
11617 #ifdef IMAP_STORAGE
11618  int new, old;
11619  inboxcount(vmu->mailbox, &new, &old);
11620 #endif
11621 
11622  make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX");
11623  astman_append(s,
11624  "%s"
11625  "Event: VoicemailUserEntry\r\n"
11626  "VMContext: %s\r\n"
11627  "VoiceMailbox: %s\r\n"
11628  "Fullname: %s\r\n"
11629  "Email: %s\r\n"
11630  "Pager: %s\r\n"
11631  "ServerEmail: %s\r\n"
11632  "MailCommand: %s\r\n"
11633  "Language: %s\r\n"
11634  "TimeZone: %s\r\n"
11635  "Callback: %s\r\n"
11636  "Dialout: %s\r\n"
11637  "UniqueID: %s\r\n"
11638  "ExitContext: %s\r\n"
11639  "SayDurationMinimum: %d\r\n"
11640  "SayEnvelope: %s\r\n"
11641  "SayCID: %s\r\n"
11642  "AttachMessage: %s\r\n"
11643  "AttachmentFormat: %s\r\n"
11644  "DeleteMessage: %s\r\n"
11645  "VolumeGain: %.2f\r\n"
11646  "CanReview: %s\r\n"
11647  "CallOperator: %s\r\n"
11648  "MaxMessageCount: %d\r\n"
11649  "MaxMessageLength: %d\r\n"
11650  "NewMessageCount: %d\r\n"
11651 #ifdef IMAP_STORAGE
11652  "OldMessageCount: %d\r\n"
11653  "IMAPUser: %s\r\n"
11654 #endif
11655  "\r\n",
11656  actionid,
11657  vmu->context,
11658  vmu->mailbox,
11659  vmu->fullname,
11660  vmu->email,
11661  vmu->pager,
11663  mailcmd,
11664  vmu->language,
11665  vmu->zonetag,
11666  vmu->callback,
11667  vmu->dialout,
11668  vmu->uniqueid,
11669  vmu->exit,
11670  vmu->saydurationm,
11671  ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No",
11672  ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No",
11673  ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No",
11674  vmu->attachfmt,
11675  ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No",
11676  vmu->volgain,
11677  ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No",
11678  ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No",
11679  vmu->maxmsg,
11680  vmu->maxsecs,
11681 #ifdef IMAP_STORAGE
11682  new, old, vmu->imapuser
11683 #else
11684  count_messages(vmu, dirname)
11685 #endif
11686  );
11687  }
11688  astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid);
11689 
11691 
11692  return RESULT_SUCCESS;
11693 }
double volgain
#define VM_OPERATOR
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char uniqueid[80]
char fullname[80]
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
char attachfmt[20]
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
list of users found in the config file
#define VM_ENVELOPE
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
#define VM_ATTACH
struct ast_vm_user::@65 list
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#define VM_SAYCID
char zonetag[80]
char pager[80]
char exit[80]
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define VM_REVIEW
static int count_messages(struct ast_vm_user *vmu, char *dir)
Find all .txt files - even if they are not in sequence from 0000.
char language[MAX_LANGUAGE]
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
static char serveremail[80]
#define VM_DELETE
char dialout[80]
char callback[80]
char serveremail[80]
#define RESULT_SUCCESS
Definition: cli.h:39
char email[80]
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
static char mailcmd[160]
static void* mb_poll_thread ( void *  data)
static

Definition at line 11416 of file app_voicemail_odbcstorage.c.

References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_lock, and poll_subscribed_mailboxes().

Referenced by start_poll_thread().

11417 {
11418  while (poll_thread_run) {
11419  struct timespec ts = { 0, };
11420  struct timeval wait;
11421 
11422  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1));
11423  ts.tv_sec = wait.tv_sec;
11424  ts.tv_nsec = wait.tv_usec * 1000;
11425 
11429 
11430  if (!poll_thread_run)
11431  break;
11432 
11434  }
11435 
11436  return NULL;
11437 }
static void poll_subscribed_mailboxes(void)
static unsigned int poll_freq
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t poll_lock
static ast_cond_t poll_cond
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:191
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static unsigned char poll_thread_run
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:172
#define ast_mutex_unlock(a)
Definition: lock.h:156
static const char* mbox ( struct ast_vm_user vmu,
int  id 
)
static

Definition at line 1711 of file app_voicemail_odbcstorage.c.

References ARRAY_LEN, and id.

Referenced by acf_mailbox_exists(), adsi_load_vmail(), copy_message(), get_folder(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().

1712 {
1713 #ifdef IMAP_STORAGE
1714  if (vmu && id == 0) {
1715  return vmu->imapfolder;
1716  }
1717 #endif
1718  return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown";
1719 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const char *const mailbox_folders[]
enum queue_result id
Definition: app_queue.c:1090
static int messagecount ( const char *  context,
const char *  mailbox,
const char *  folder 
)
static

Definition at line 5398 of file app_voicemail_odbcstorage.c.

References __has_voicemail().

Referenced by load_module().

5399 {
5400  return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0));
5401 }
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static void mwi_sub_destroy ( struct mwi_sub mwi_sub)
static

Definition at line 11439 of file app_voicemail_odbcstorage.c.

References ast_free.

Referenced by handle_unsubscribe().

11440 {
11441  ast_free(mwi_sub);
11442 }
#define ast_free(a)
Definition: astmm.h:97
static void mwi_sub_event_cb ( const struct ast_event event,
void *  userdata 
)
static

Definition at line 11527 of file app_voicemail_odbcstorage.c.

References ast_calloc, ast_event_get_ie_str(), ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_SUB, ast_free, ast_log(), ast_strdup, ast_taskprocessor_push(), mwi_sub_task::context, handle_subscribe(), LOG_ERROR, mwi_sub_task::mailbox, and mwi_sub_task::uniqueid.

Referenced by start_poll_thread().

11528 {
11529  struct mwi_sub_task *mwist;
11530 
11531  if (ast_event_get_type(event) != AST_EVENT_SUB)
11532  return;
11533 
11535  return;
11536 
11537  if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) {
11538  ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n");
11539  return;
11540  }
11544 
11546  ast_free(mwist);
11547  }
11548 }
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
Definition: event.c:1070
#define ast_strdup(a)
Definition: astmm.h:109
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
const char * context
const char * mailbox
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
uint32_t uniqueid
Event type Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: UINT.
Definition: event_defs.h:95
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int handle_subscribe(void *datap)
#define ast_free(a)
Definition: astmm.h:97
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
#define ast_calloc(a, b)
Definition: astmm.h:82
Unique ID Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: UINT.
Definition: event_defs.h:89
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition: event.c:1102
static struct ast_taskprocessor * mwi_subscription_tps
Mailbox name.
Definition: event_defs.h:83
static void mwi_unsub_event_cb ( const struct ast_event event,
void *  userdata 
)
static

Definition at line 11501 of file app_voicemail_odbcstorage.c.

References ast_calloc, ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, ast_free, ast_log(), ast_taskprocessor_push(), handle_unsubscribe(), LOG_ERROR, and mwi_sub_task::uniqueid.

Referenced by start_poll_thread().

11502 {
11503  uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid));
11504 
11505  if (!uniqueid) {
11506  ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n");
11507  return;
11508  }
11509 
11510  if (ast_event_get_type(event) != AST_EVENT_UNSUB) {
11511  ast_free(uniqueid);
11512  return;
11513  }
11514 
11516  ast_free(uniqueid);
11517  return;
11518  }
11519 
11521  *uniqueid = u;
11523  ast_free(uniqueid);
11524  }
11525 }
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
Definition: event.c:1070
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap)
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
static int handle_unsubscribe(void *datap)
uint32_t uniqueid
Event type Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: UINT.
Definition: event_defs.h:95
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition: event.c:1075
#define ast_calloc(a, b)
Definition: astmm.h:82
Unique ID Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: UINT.
Definition: event_defs.h:89
static struct ast_taskprocessor * mwi_subscription_tps
static int notify_new_message ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
int  msgnum,
long  duration,
char *  fmt,
char *  cidnum,
char *  cidname,
const char *  flag 
)
static

Sends email notification that a user has a new voicemail waiting for them.

Parameters
chan
vmu
vms
msgnum
duration
fmt
cidnumThe Caller ID phone number value.
cidnameThe Caller ID name value.
flag
Returns
zero on success, -1 on error.

Definition at line 7084 of file app_voicemail_odbcstorage.c.

References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), AST_LOG_WARNING, ast_manager_event, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::attachfmt, ast_vm_user::context, vm_state::curmsg, DELETE, DISPOSE, ast_vm_user::email, EVENT_FLAG_CALL, ast_vm_user::mailbox, make_dir(), make_file(), mbox(), vm_state::newmessages, ast_vm_user::pager, pbx_builtin_getvar_helper(), queue_mwi_event(), RETRIEVE, run_externnotify(), sendmail(), sendpage(), ast_vm_user::serveremail, serveremail, strsep(), VM_ATTACH, VM_DELETE, and vm_delete().

Referenced by copy_message(), and leave_voicemail().

7085 {
7086  char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
7087  int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;
7088  const char *category;
7089  char *myserveremail = serveremail;
7090 
7091  ast_channel_lock(chan);
7092  if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) {
7093  category = ast_strdupa(category);
7094  }
7095  ast_channel_unlock(chan);
7096 
7097 #ifndef IMAP_STORAGE
7098  make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX");
7099 #else
7100  snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR);
7101 #endif
7102  make_file(fn, sizeof(fn), todir, msgnum);
7103  snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
7104 
7105  if (!ast_strlen_zero(vmu->attachfmt)) {
7106  if (strstr(fmt, vmu->attachfmt))
7107  fmt = vmu->attachfmt;
7108  else
7109  ast_log(AST_LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'. Falling back to default format for '%s@%s'.\n", vmu->attachfmt, fmt, vmu->mailbox, vmu->context);
7110  }
7111 
7112  /* Attach only the first format */
7113  fmt = ast_strdupa(fmt);
7114  stringp = fmt;
7115  strsep(&stringp, "|");
7116 
7117  if (!ast_strlen_zero(vmu->serveremail))
7118  myserveremail = vmu->serveremail;
7119 
7120  if (!ast_strlen_zero(vmu->email)) {
7121  int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
7122 
7123  if (attach_user_voicemail)
7124  RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
7125 
7126  /* XXX possible imap issue, should category be NULL XXX */
7127  sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag);
7128 
7129  if (attach_user_voicemail)
7130  DISPOSE(todir, msgnum);
7131  }
7132 
7133  if (!ast_strlen_zero(vmu->pager)) {
7134  sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag);
7135  }
7136 
7137  if (ast_test_flag(vmu, VM_DELETE))
7138  DELETE(todir, msgnum, fn, vmu);
7139 
7140  /* Leave voicemail for someone */
7141  if (ast_app_has_voicemail(ext_context, NULL))
7142  ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs);
7143 
7144  queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs);
7145 
7146  ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s@%s\r\nWaiting: %d\r\nNew: %d\r\nOld: %d\r\n", vmu->mailbox, vmu->context, ast_app_has_voicemail(ext_context, NULL), newmsgs, oldmsgs);
7147  run_externnotify(vmu->context, vmu->mailbox, flag);
7148 
7149 #ifdef IMAP_STORAGE
7150  vm_delete(fn); /* Delete the file, but not the IMAP message */
7151  if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */
7152  vm_imap_delete(NULL, vms->curmsg, vmu);
7153  vms->newmessages--; /* Fix new message count */
7154  }
7155 #endif
7156 
7157  return 0;
7158 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
char * strsep(char **str, const char *delims)
char attachfmt[20]
#define DELETE(a, b, c, d)
static int vm_delete(char *file)
Removes the voicemail sound and information file.
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_app_has_voicemail(const char *mailbox, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to &quot;INBOX&quot;. If folder is &quot;INBOX&quot;, includes the number of messages in the &quot;Urgent&quot; folder.
Definition: app.c:421
#define AST_LOG_WARNING
Definition: logger.h:149
#define EVENT_FLAG_CALL
Definition: manager.h:72
static void queue_mwi_event(const char *box, int urgent, int new, int old)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
#define RETRIEVE(a, b, c, d)
#define VM_ATTACH
static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
static void run_externnotify(char *context, char *extension, const char *flag)
char context[AST_MAX_CONTEXT]
int ast_app_inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Determine number of urgent/new/old messages in a mailbox.
Definition: app.c:455
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
char pager[80]
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char * mbox(struct ast_vm_user *vmu, int id)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
#define DISPOSE(a, b)
static char serveremail[80]
#define VM_DELETE
char serveremail[80]
char email[80]
int newmessages
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, const char *flag)
static int ochar ( struct baseio bio,
int  c,
FILE *  so 
)
static

utility used by base_encode()

Definition at line 4268 of file app_voicemail_odbcstorage.c.

References BASELINELEN, ENDL, and baseio::linelength.

Referenced by base_encode().

4269 {
4270  if (bio->linelength >= BASELINELEN) {
4271  if (fputs(ENDL, so) == EOF) {
4272  return -1;
4273  }
4274 
4275  bio->linelength = 0;
4276  }
4277 
4278  if (putc(((unsigned char) c), so) == EOF) {
4279  return -1;
4280  }
4281 
4282  bio->linelength++;
4283 
4284  return 1;
4285 }
#define BASELINELEN
int linelength
#define ENDL
static int open_mailbox ( struct vm_state vms,
struct ast_vm_user vmu,
int  box 
)
static

Definition at line 7932 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), ast_log(), AST_LOG_ERROR, ast_unlock_path(), ast_vm_user::context, count_messages(), create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, last_message_index(), vm_state::lastmsg, LOG_NOTICE, ast_vm_user::maxmsg, mbox(), resequence_mailbox(), vm_state::username, vm_allocate_dh(), vm_lock_path(), and vm_state::vmbox.

Referenced by vm_execmain().

7933 {
7934  int count_msg, last_msg;
7935 
7936  ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox));
7937 
7938  /* Rename the member vmbox HERE so that we don't try to return before
7939  * we know what's going on.
7940  */
7941  snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
7942 
7943  /* Faster to make the directory than to check if it exists. */
7944  create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
7945 
7946  /* traverses directory using readdir (or select query for ODBC) */
7947  count_msg = count_messages(vmu, vms->curdir);
7948  if (count_msg < 0) {
7949  return count_msg;
7950  } else {
7951  vms->lastmsg = count_msg - 1;
7952  }
7953 
7954  if (vm_allocate_dh(vms, vmu, count_msg)) {
7955  return -1;
7956  }
7957 
7958  /*
7959  The following test is needed in case sequencing gets messed up.
7960  There appears to be more than one way to mess up sequence, so
7961  we will not try to find all of the root causes--just fix it when
7962  detected.
7963  */
7964 
7965  if (vm_lock_path(vms->curdir)) {
7966  ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir);
7967  return ERROR_LOCK_PATH;
7968  }
7969 
7970  /* for local storage, checks directory for messages up to maxmsg limit */
7971  last_msg = last_message_index(vmu, vms->curdir);
7972  ast_unlock_path(vms->curdir);
7973 
7974  if (last_msg < -1) {
7975  return last_msg;
7976  } else if (vms->lastmsg != last_msg) {
7977  ast_log(LOG_NOTICE, "Resequencing Mailbox: %s, expected %d but found %d message(s) in box with max threshold of %d.\n", vms->curdir, last_msg + 1, vms->lastmsg + 1, vmu->maxmsg);
7978  resequence_mailbox(vmu, vms->curdir, count_msg);
7979  }
7980 
7981  return 0;
7982 }
static int last_message_index(struct ast_vm_user *vmu, char *dir)
Determines the highest message number in use for a given user and mailbox folder. ...
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
char curdir[PATH_MAX]
char vmbox[PATH_MAX]
#define AST_LOG_ERROR
Definition: logger.h:160
char username[80]
char context[AST_MAX_CONTEXT]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static const char * mbox(struct ast_vm_user *vmu, int id)
static int count_messages(struct ast_vm_user *vmu, char *dir)
Find all .txt files - even if they are not in sequence from 0000.
#define ERROR_LOCK_PATH
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int vm_allocate_dh(struct vm_state *vms, struct ast_vm_user *vmu, int count_msg)
char curbox[80]
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
static int resequence_mailbox(struct ast_vm_user *vmu, char *dir, int stopcount)
static int play_message ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
)
static

Definition at line 7706 of file app_voicemail_odbcstorage.c.

References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, context, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, ast_channel::language, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, valid_config(), VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().

Referenced by vm_browse_messages_en(), vm_browse_messages_he(), vm_browse_messages_latin(), vm_browse_messages_vi(), vm_browse_messages_zh(), and vm_execmain().

7707 {
7708  int res = 0;
7709  char filename[256], *cid;
7710  const char *origtime, *context, *category, *duration, *flag;
7711  struct ast_config *msg_cfg;
7712  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
7713 
7714  vms->starting = 0;
7715  make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
7716  adsi_message(chan, vms);
7717  if (!vms->curmsg) {
7718  res = wait_file2(chan, vms, "vm-first"); /* "First" */
7719  } else if (vms->curmsg == vms->lastmsg) {
7720  res = wait_file2(chan, vms, "vm-last"); /* "last" */
7721  }
7722 
7723  snprintf(filename, sizeof(filename), "%s.txt", vms->fn);
7724  RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
7725  msg_cfg = ast_config_load(filename, config_flags);
7726  if (!valid_config(msg_cfg)) {
7727  ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
7728  return 0;
7729  }
7730  flag = ast_variable_retrieve(msg_cfg, "message", "flag");
7731 
7732  /* Play the word urgent if we are listening to urgent messages */
7733  if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) {
7734  res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */
7735  }
7736 
7737  if (!res) {
7738  /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */
7739  /* POLISH syntax */
7740  if (!strncasecmp(chan->language, "pl", 2)) {
7741  if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
7742  int ten, one;
7743  char nextmsg[256];
7744  ten = (vms->curmsg + 1) / 10;
7745  one = (vms->curmsg + 1) % 10;
7746 
7747  if (vms->curmsg < 20) {
7748  snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
7749  res = wait_file2(chan, vms, nextmsg);
7750  } else {
7751  snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
7752  res = wait_file2(chan, vms, nextmsg);
7753  if (one > 0) {
7754  if (!res) {
7755  snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
7756  res = wait_file2(chan, vms, nextmsg);
7757  }
7758  }
7759  }
7760  }
7761  if (!res)
7762  res = wait_file2(chan, vms, "vm-message");
7763  /* HEBREW syntax */
7764  } else if (!strncasecmp(chan->language, "he", 2)) {
7765  if (!vms->curmsg) {
7766  res = wait_file2(chan, vms, "vm-message");
7767  res = wait_file2(chan, vms, "vm-first");
7768  } else if (vms->curmsg == vms->lastmsg) {
7769  res = wait_file2(chan, vms, "vm-message");
7770  res = wait_file2(chan, vms, "vm-last");
7771  } else {
7772  res = wait_file2(chan, vms, "vm-message");
7773  res = wait_file2(chan, vms, "vm-number");
7774  res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
7775  }
7776  /* VIETNAMESE syntax */
7777  } else if (!strncasecmp(chan->language, "vi", 2)) {
7778  if (!vms->curmsg) {
7779  res = wait_file2(chan, vms, "vm-message");
7780  res = wait_file2(chan, vms, "vm-first");
7781  } else if (vms->curmsg == vms->lastmsg) {
7782  res = wait_file2(chan, vms, "vm-message");
7783  res = wait_file2(chan, vms, "vm-last");
7784  } else {
7785  res = wait_file2(chan, vms, "vm-message");
7786  res = wait_file2(chan, vms, "vm-number");
7787  res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
7788  }
7789  } else {
7790  if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */
7791  res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */
7792  } else { /* DEFAULT syntax */
7793  res = wait_file2(chan, vms, "vm-message");
7794  }
7795  if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
7796  if (!res) {
7797  ast_test_suite_event_notify("PLAYBACK", "Message: message number");
7798  res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
7799  }
7800  }
7801  }
7802  }
7803 
7804  if (!valid_config(msg_cfg)) {
7805  ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
7806  return 0;
7807  }
7808 
7809  if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
7810  ast_log(AST_LOG_WARNING, "No origtime?!\n");
7811  DISPOSE(vms->curdir, vms->curmsg);
7812  ast_config_destroy(msg_cfg);
7813  return 0;
7814  }
7815 
7816  cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
7817  duration = ast_variable_retrieve(msg_cfg, "message", "duration");
7818  category = ast_variable_retrieve(msg_cfg, "message", "category");
7819 
7820  context = ast_variable_retrieve(msg_cfg, "message", "context");
7821  if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
7822  context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
7823  if (!res) {
7824  res = play_message_category(chan, category);
7825  }
7826  if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) {
7827  res = play_message_datetime(chan, vmu, origtime, filename);
7828  }
7829  if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) {
7830  res = play_message_callerid(chan, vms, cid, context, 0);
7831  }
7832  if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) {
7833  res = play_message_duration(chan, vms, duration, vmu->saydurationm);
7834  }
7835  /* Allow pressing '1' to skip envelope / callerid */
7836  if (res == '1') {
7837  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
7838  res = 0;
7839  }
7840  ast_config_destroy(msg_cfg);
7841 
7842  if (!res) {
7843  make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
7844 #ifdef IMAP_STORAGE
7845  ast_mutex_lock(&vms->lock);
7846 #endif
7847  vms->heard[vms->curmsg] = 1;
7848 #ifdef IMAP_STORAGE
7849  ast_mutex_unlock(&vms->lock);
7850  /*IMAP storage stores any prepended message from a forward
7851  * as a separate file from the rest of the message
7852  */
7853  if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) {
7854  wait_file(chan, vms, vms->introfn);
7855  }
7856 #endif
7857  if ((res = wait_file(chan, vms, vms->fn)) < 0) {
7858  ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn);
7859  res = 0;
7860  }
7861  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
7862  }
7863  DISPOSE(vms->curdir, vms->curmsg);
7864  return res;
7865 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file)
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_test_flag(p, flag)
Definition: utils.h:63
char fn[PATH_MAX]
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
char curdir[PATH_MAX]
#define ast_mutex_lock(a)
Definition: lock.h:155
static int play_message_category(struct ast_channel *chan, const char *category)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define VM_ENVELOPE
#define VM_SAYDURATION
#define RETRIEVE(a, b, c, d)
static int play_message_duration(struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char mailbox[AST_MAX_EXTENSION]
static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
char context[AST_MAX_CONTEXT]
#define VM_SAYCID
int * heard
static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
Structure used to handle boolean flags.
Definition: utils.h:200
#define DISPOSE(a, b)
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static void adsi_message(struct ast_channel *chan, struct vm_state *vms)
static int play_message_callerid(struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int play_message_callerid ( struct ast_channel chan,
struct vm_state vms,
char *  cid,
const char *  context,
int  callback 
)
static

Definition at line 7592 of file app_voicemail_odbcstorage.c.

References ast_callerid_parse(), ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_say_digit_str(), ast_stream_and_wait(), ast_strlen_zero(), ast_verb, ast_channel::language, MAX_NUM_CID_CONTEXTS, name, and wait_file2().

Referenced by advanced_options(), and play_message().

7593 {
7594  int res = 0;
7595  int i;
7596  char *callerid, *name;
7597  char prefile[PATH_MAX] = "";
7598 
7599 
7600  /* If voicemail cid is not enabled, or we didn't get cid or context from
7601  * the attribute file, leave now.
7602  *
7603  * TODO Still need to change this so that if this function is called by the
7604  * message envelope (and someone is explicitly requesting to hear the CID),
7605  * it does not check to see if CID is enabled in the config file.
7606  */
7607  if ((cid == NULL)||(context == NULL))
7608  return res;
7609 
7610  /* Strip off caller ID number from name */
7611  ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
7612  ast_callerid_parse(cid, &name, &callerid);
7613  if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
7614  /* Check for internal contexts and only */
7615  /* say extension when the call didn't come from an internal context in the list */
7616  for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
7617  ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
7618  if ((strcmp(cidinternalcontexts[i], context) == 0))
7619  break;
7620  }
7621  if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
7622  if (!res) {
7623  snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
7624  if (!ast_strlen_zero(prefile)) {
7625  /* See if we can find a recorded name for this person instead of their extension number */
7626  if (ast_fileexists(prefile, NULL, NULL) > 0) {
7627  ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
7628  if (!callback)
7629  res = wait_file2(chan, vms, "vm-from");
7630  res = ast_stream_and_wait(chan, prefile, "");
7631  } else {
7632  ast_verb(3, "Playing envelope info: message from '%s'\n", callerid);
7633  /* Say "from extension" as one saying to sound smoother */
7634  if (!callback)
7635  res = wait_file2(chan, vms, "vm-from-extension");
7636  res = ast_say_digit_str(chan, callerid, "", chan->language);
7637  }
7638  }
7639  }
7640  } else if (!res) {
7641  ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid);
7642  /* Since this is all nicely figured out, why not say "from phone number" in this case? */
7643  if (!callback)
7644  res = wait_file2(chan, vms, "vm-from-phonenumber");
7645  res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
7646  }
7647  } else {
7648  /* Number unknown */
7649  ast_debug(1, "VM-CID: From an unknown number\n");
7650  /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
7651  res = wait_file2(chan, vms, "vm-unknown-caller");
7652  }
7653  return res;
7654 }
#define AST_DIGIT_ANY
Definition: file.h:47
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
Definition: channel.c:8415
#define ast_verb(level,...)
Definition: logger.h:243
#define MAX_NUM_CID_CONTEXTS
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
static char VM_SPOOL_DIR[PATH_MAX]
static const char name[]
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64]
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
static int play_message_category ( struct ast_channel chan,
const char *  category 
)
static

Definition at line 7503 of file app_voicemail_odbcstorage.c.

References ast_log(), AST_LOG_WARNING, ast_play_and_wait(), and ast_strlen_zero().

Referenced by play_message().

7504 {
7505  int res = 0;
7506 
7507  if (!ast_strlen_zero(category))
7508  res = ast_play_and_wait(chan, category);
7509 
7510  if (res) {
7511  ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category);
7512  res = 0;
7513  }
7514 
7515  return res;
7516 }
#define AST_LOG_WARNING
Definition: logger.h:149
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int play_message_datetime ( struct ast_channel chan,
struct ast_vm_user vmu,
const char *  origtime,
const char *  filename 
)
static

Definition at line 7518 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_get_time_t(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), AST_LOG_WARNING, ast_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, vm_zone::msg_format, vm_zone::name, pbx_builtin_setvar_helper(), vm_zone::timezone, and ast_vm_user::zonetag.

Referenced by advanced_options(), and play_message().

7519 {
7520  int res = 0;
7521  struct vm_zone *the_zone = NULL;
7522  time_t t;
7523 
7524  if (ast_get_time_t(origtime, &t, 0, NULL)) {
7525  ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename);
7526  return 0;
7527  }
7528 
7529  /* Does this user have a timezone specified? */
7530  if (!ast_strlen_zero(vmu->zonetag)) {
7531  /* Find the zone in the list */
7532  struct vm_zone *z;
7533  AST_LIST_LOCK(&zones);
7534  AST_LIST_TRAVERSE(&zones, z, list) {
7535  if (!strcmp(z->name, vmu->zonetag)) {
7536  the_zone = z;
7537  break;
7538  }
7539  }
7541  }
7542 
7543 /* No internal variable parsing for now, so we'll comment it out for the time being */
7544 #if 0
7545  /* Set the DIFF_* variables */
7546  ast_localtime(&t, &time_now, NULL);
7547  tv_now = ast_tvnow();
7548  ast_localtime(&tv_now, &time_then, NULL);
7549 
7550  /* Day difference */
7551  if (time_now.tm_year == time_then.tm_year)
7552  snprintf(temp, sizeof(temp), "%d", time_now.tm_yday);
7553  else
7554  snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
7555  pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
7556 
7557  /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
7558 #endif
7559  if (the_zone) {
7560  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
7561  } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
7562  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
7563  } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */
7564  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL);
7565  } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
7566  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
7567  } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */
7568  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
7569  } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */
7570  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
7571  } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */
7572  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
7573  } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */
7574  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Ad 'digits/pt-de' B 'digits/pt-de' Y 'digits/pt-as' HM ", NULL);
7575  } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */
7576  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
7577  } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */
7578  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL);
7579  } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */
7580  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' A 'digits/day' dB 'digits/year' Y 'digits/at' k 'hours' M 'minutes'", NULL);
7581  } else {
7582  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
7583  }
7584 #if 0
7585  pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
7586 #endif
7587  return res;
7588 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char msg_format[512]
char name[80]
#define AST_DIGIT_ANY
Definition: file.h:47
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char timezone[80]
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
#define AST_LOG_WARNING
Definition: logger.h:149
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
get values from config variables.
Definition: utils.c:2118
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char zonetag[80]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
SAY_EXTERN int(* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format)
Definition: say.h:168
const ast_string_field language
Definition: channel.h:787
struct vm_zone::@66 list
static int play_message_duration ( struct ast_channel chan,
struct vm_state vms,
const char *  duration,
int  minduration 
)
static

Definition at line 7656 of file app_voicemail_odbcstorage.c.

References ast_debug, AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, say_and_wait(), and wait_file2().

Referenced by play_message().

7657 {
7658  int res = 0;
7659  int durationm;
7660  int durations;
7661  /* Verify that we have a duration for the message */
7662  if (duration == NULL)
7663  return res;
7664 
7665  /* Convert from seconds to minutes */
7666  durations = atoi(duration);
7667  durationm = (durations / 60);
7668 
7669  ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
7670 
7671  if ((!res) && (durationm >= minduration)) {
7672  res = wait_file2(chan, vms, "vm-duration");
7673 
7674  /* POLISH syntax */
7675  if (!strncasecmp(chan->language, "pl", 2)) {
7676  div_t num = div(durationm, 10);
7677 
7678  if (durationm == 1) {
7679  res = ast_play_and_wait(chan, "digits/1z");
7680  res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
7681  } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
7682  if (num.rem == 2) {
7683  if (!num.quot) {
7684  res = ast_play_and_wait(chan, "digits/2-ie");
7685  } else {
7686  res = say_and_wait(chan, durationm - 2 , chan->language);
7687  res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
7688  }
7689  } else {
7690  res = say_and_wait(chan, durationm, chan->language);
7691  }
7692  res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
7693  } else {
7694  res = say_and_wait(chan, durationm, chan->language);
7695  res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
7696  }
7697  /* DEFAULT syntax */
7698  } else {
7699  res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
7700  res = wait_file2(chan, vms, "vm-minutes");
7701  }
7702  }
7703  return res;
7704 }
#define AST_DIGIT_ANY
Definition: file.h:47
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
const ast_string_field language
Definition: channel.h:787
static int play_record_review ( struct ast_channel chan,
char *  playfile,
char *  recordfile,
int  maxtime,
char *  fmt,
int  outsidecaller,
struct ast_vm_user vmu,
int *  duration,
int *  sound_duration,
const char *  unlockdir,
signed char  record_gain,
struct vm_state vms,
char *  flag 
)
static

Definition at line 13378 of file app_voicemail_odbcstorage.c.

References acceptdtmf, ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), AST_LOG_WARNING, AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose(), ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, INTRO, ast_vm_user::mailbox, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.

Referenced by leave_voicemail(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().

13381 {
13382  /* Record message & let caller review or re-record it, or set options if applicable */
13383  int res = 0;
13384  int cmd = 0;
13385  int max_attempts = 3;
13386  int attempts = 0;
13387  int recorded = 0;
13388  int msg_exists = 0;
13389  signed char zero_gain = 0;
13390  char tempfile[PATH_MAX];
13391  char *acceptdtmf = "#";
13392  char *canceldtmf = "";
13393  int canceleddtmf = 0;
13394 
13395  /* Note that urgent and private are for flagging messages as such in the future */
13396 
13397  /* barf if no pointer passed to store duration in */
13398  if (duration == NULL) {
13399  ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n");
13400  return -1;
13401  }
13402 
13403  if (!outsidecaller)
13404  snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile);
13405  else
13406  ast_copy_string(tempfile, recordfile, sizeof(tempfile));
13407 
13408  cmd = '3'; /* Want to start by recording */
13409 
13410  while ((cmd >= 0) && (cmd != 't')) {
13411  switch (cmd) {
13412  case '1':
13413  if (!msg_exists) {
13414  /* In this case, 1 is to record a message */
13415  cmd = '3';
13416  break;
13417  } else {
13418  /* Otherwise 1 is to save the existing message */
13419  ast_verb(3, "Saving message as is\n");
13420  if (!outsidecaller)
13421  ast_filerename(tempfile, recordfile, NULL);
13422  ast_stream_and_wait(chan, "vm-msgsaved", "");
13423  if (!outsidecaller) {
13424  /* Saves to IMAP server only if imapgreeting=yes */
13425  STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag);
13426  DISPOSE(recordfile, -1);
13427  }
13428  cmd = 't';
13429  return res;
13430  }
13431  case '2':
13432  /* Review */
13433  ast_verb(3, "Reviewing the message\n");
13434  cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY);
13435  break;
13436  case '3':
13437  msg_exists = 0;
13438  /* Record */
13439  if (recorded == 1)
13440  ast_verb(3, "Re-recording the message\n");
13441  else
13442  ast_verb(3, "Recording the message\n");
13443 
13444  if (recorded && outsidecaller) {
13445  cmd = ast_play_and_wait(chan, INTRO);
13446  cmd = ast_play_and_wait(chan, "beep");
13447  }
13448  recorded = 1;
13449  /* 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 */
13450  if (record_gain)
13451  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
13452  if (ast_test_flag(vmu, VM_OPERATOR))
13453  canceldtmf = "0";
13454  cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf);
13455  if (strchr(canceldtmf, cmd)) {
13456  /* need this flag here to distinguish between pressing '0' during message recording or after */
13457  canceleddtmf = 1;
13458  }
13459  if (record_gain)
13460  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
13461  if (cmd == -1) {
13462  /* User has hung up, no options to give */
13463  if (!outsidecaller) {
13464  /* user was recording a greeting and they hung up, so let's delete the recording. */
13465  ast_filedelete(tempfile, NULL);
13466  }
13467  return cmd;
13468  }
13469  if (cmd == '0') {
13470  break;
13471  } else if (cmd == '*') {
13472  break;
13473 #if 0
13474  } else if (vmu->review && sound_duration && (*sound_duration < 5)) {
13475  /* Message is too short */
13476  ast_verb(3, "Message too short\n");
13477  cmd = ast_play_and_wait(chan, "vm-tooshort");
13478  cmd = ast_filedelete(tempfile, NULL);
13479  break;
13480  } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) {
13481  /* Message is all silence */
13482  ast_verb(3, "Nothing recorded\n");
13483  cmd = ast_filedelete(tempfile, NULL);
13484  cmd = ast_play_and_wait(chan, "vm-nothingrecorded");
13485  if (!cmd)
13486  cmd = ast_play_and_wait(chan, "vm-speakup");
13487  break;
13488 #endif
13489  } else {
13490  /* If all is well, a message exists */
13491  msg_exists = 1;
13492  cmd = 0;
13493  }
13494  break;
13495  case '4':
13496  if (outsidecaller) { /* only mark vm messages */
13497  /* Mark Urgent */
13498  if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) {
13499  ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n");
13500  res = ast_play_and_wait(chan, "vm-marked-urgent");
13501  strcpy(flag, "Urgent");
13502  } else if (flag) {
13503  ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n");
13504  res = ast_play_and_wait(chan, "vm-marked-nonurgent");
13505  strcpy(flag, "");
13506  } else {
13507  ast_play_and_wait(chan, "vm-sorry");
13508  }
13509  cmd = 0;
13510  } else {
13511  cmd = ast_play_and_wait(chan, "vm-sorry");
13512  }
13513  break;
13514  case '5':
13515  case '6':
13516  case '7':
13517  case '8':
13518  case '9':
13519  case '*':
13520  case '#':
13521  cmd = ast_play_and_wait(chan, "vm-sorry");
13522  break;
13523 #if 0
13524 /* XXX Commented out for the moment because of the dangers of deleting
13525  a message while recording (can put the message numbers out of sync) */
13526  case '*':
13527  /* Cancel recording, delete message, offer to take another message*/
13528  cmd = ast_play_and_wait(chan, "vm-deleted");
13529  cmd = ast_filedelete(tempfile, NULL);
13530  if (outsidecaller) {
13531  res = vm_exec(chan, NULL);
13532  return res;
13533  }
13534  else
13535  return 1;
13536 #endif
13537  case '0':
13538  if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) {
13539  cmd = ast_play_and_wait(chan, "vm-sorry");
13540  break;
13541  }
13542  if (msg_exists || recorded) {
13543  cmd = ast_play_and_wait(chan, "vm-saveoper");
13544  if (!cmd)
13545  cmd = ast_waitfordigit(chan, 3000);
13546  if (cmd == '1') {
13547  ast_filerename(tempfile, recordfile, NULL);
13548  ast_play_and_wait(chan, "vm-msgsaved");
13549  cmd = '0';
13550  } else if (cmd == '4') {
13551  if (flag) {
13552  ast_play_and_wait(chan, "vm-marked-urgent");
13553  strcpy(flag, "Urgent");
13554  }
13555  ast_play_and_wait(chan, "vm-msgsaved");
13556  cmd = '0';
13557  } else {
13558  ast_play_and_wait(chan, "vm-deleted");
13559  DELETE(tempfile, -1, tempfile, vmu);
13560  cmd = '0';
13561  }
13562  }
13563  return cmd;
13564  default:
13565  /* If the caller is an ouside caller, and the review option is enabled,
13566  allow them to review the message, but let the owner of the box review
13567  their OGM's */
13568  if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW))
13569  return cmd;
13570  if (msg_exists) {
13571  cmd = ast_play_and_wait(chan, "vm-review");
13572  if (!cmd && outsidecaller) {
13573  if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) {
13574  cmd = ast_play_and_wait(chan, "vm-review-urgent");
13575  } else if (flag) {
13576  cmd = ast_play_and_wait(chan, "vm-review-nonurgent");
13577  }
13578  }
13579  } else {
13580  cmd = ast_play_and_wait(chan, "vm-torerecord");
13581  if (!cmd)
13582  cmd = ast_waitfordigit(chan, 600);
13583  }
13584 
13585  if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) {
13586  cmd = ast_play_and_wait(chan, "vm-reachoper");
13587  if (!cmd)
13588  cmd = ast_waitfordigit(chan, 600);
13589  }
13590 #if 0
13591  if (!cmd)
13592  cmd = ast_play_and_wait(chan, "vm-tocancelmsg");
13593 #endif
13594  if (!cmd)
13595  cmd = ast_waitfordigit(chan, 6000);
13596  if (!cmd) {
13597  attempts++;
13598  }
13599  if (attempts > max_attempts) {
13600  cmd = 't';
13601  }
13602  }
13603  }
13604  if (!outsidecaller && (cmd == -1 || cmd == 't')) {
13605  /* Hang up or timeout, so delete the recording. */
13606  ast_filedelete(tempfile, NULL);
13607  }
13608 
13609  if (cmd != 't' && outsidecaller)
13610  ast_play_and_wait(chan, "vm-goodbye");
13611 
13612  return cmd;
13613 }
#define VM_OPERATOR
static int vm_exec(struct ast_channel *chan, const char *data)
#define INTRO
int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf)
Record a file based on input from a channel This function will play &quot;auth-thankyou&quot; upon successful r...
Definition: app.c:1178
#define AST_DIGIT_ANY
Definition: file.h:47
#define DELETE(a, b, c, d)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define VERBOSE_PREFIX_3
Definition: logger.h:43
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define AST_LOG_WARNING
Definition: logger.h:149
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7795
#define ast_verb(level,...)
Definition: logger.h:243
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define STORE(a, b, c, d, e, f, g, h, i, j)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
#define VM_REVIEW
static char acceptdtmf
Definition: chan_agent.c:227
static int silencethreshold
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
#define DISPOSE(a, b)
static int maxsilence
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define AST_OPTION_RXGAIN
Definition: frame.h:463
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
static void poll_subscribed_mailbox ( struct mwi_sub mwi_sub)
static

Definition at line 11388 of file app_voicemail_odbcstorage.c.

References inboxcount2(), queue_mwi_event(), and run_externnotify().

Referenced by handle_subscribe(), and poll_subscribed_mailboxes().

11389 {
11390  int new = 0, old = 0, urgent = 0;
11391 
11392  inboxcount2(mwi_sub->mailbox, &urgent, &new, &old);
11393 
11394  if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) {
11395  mwi_sub->old_urgent = urgent;
11396  mwi_sub->old_new = new;
11397  mwi_sub->old_old = old;
11398  queue_mwi_event(mwi_sub->mailbox, urgent, new, old);
11399  run_externnotify(NULL, mwi_sub->mailbox, NULL);
11400  }
11401 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
static void queue_mwi_event(const char *box, int urgent, int new, int old)
static void run_externnotify(char *context, char *extension, const char *flag)
static void poll_subscribed_mailboxes ( void  )
static

Definition at line 11403 of file app_voicemail_odbcstorage.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub, and poll_subscribed_mailbox().

Referenced by mb_poll_thread().

11404 {
11405  struct mwi_sub *mwi_sub;
11406 
11408  AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {
11409  if (!ast_strlen_zero(mwi_sub->mailbox)) {
11410  poll_subscribed_mailbox(mwi_sub);
11411  }
11412  }
11414 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
An MWI subscription.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
static struct ast_event_sub * mwi_sub
Definition: res_jabber.c:394
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
static void poll_subscribed_mailbox(struct mwi_sub *mwi_sub)
static void populate_defaults ( struct ast_vm_user vmu)
static

Sets default voicemail system options to a voicemail user.

This applies select global settings to a newly created (dynamic) instance of a voicemail user.

  • all the globalflags
  • the saydurationminfo
  • the callcontext
  • the dialcontext
  • the exitcontext
  • vmmaxsecs, vmmaxmsg, maxdeletedmsg
  • volume gain
  • emailsubject, emailbody set to NULL

Definition at line 995 of file app_voicemail_odbcstorage.c.

References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, ast_free, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, maxdeletedmsg, ast_vm_user::maxmsg, maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, ast_vm_user::passwordlocation, passwordlocation, ast_vm_user::saydurationm, saydurationminfo, vmmaxsecs, vmminsecs, ast_vm_user::volgain, volgain, and ast_vm_user::zonetag.

Referenced by actual_load_config(), append_mailbox(), AST_TEST_DEFINE(), and find_user_realtime().

996 {
999  if (saydurationminfo) {
1001  }
1002  ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
1003  ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
1004  ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
1005  ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
1006  ast_copy_string(vmu->locale, locale, sizeof(vmu->locale));
1007  if (vmminsecs) {
1008  vmu->minsecs = vmminsecs;
1009  }
1010  if (vmmaxsecs) {
1011  vmu->maxsecs = vmmaxsecs;
1012  }
1013  if (maxmsg) {
1014  vmu->maxmsg = maxmsg;
1015  }
1016  if (maxdeletedmsg) {
1018  }
1019  vmu->volgain = volgain;
1020  ast_free(vmu->emailsubject);
1021  vmu->emailsubject = NULL;
1022  ast_free(vmu->emailbody);
1023  vmu->emailbody = NULL;
1024 #ifdef IMAP_STORAGE
1025  ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder));
1026 #endif
1027 }
double volgain
static double volgain
static struct ast_flags globalflags
static int vmmaxsecs
static char zonetag[80]
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
static char locale[20]
char locale[20]
char * emailsubject
static int saydurationminfo
static char exitcontext[AST_MAX_CONTEXT]
int passwordlocation
char zonetag[80]
static int vmminsecs
char * emailbody
char exit[80]
#define ast_free(a)
Definition: astmm.h:97
#define AST_FLAGS_ALL
Definition: utils.h:196
static char dialcontext[AST_MAX_CONTEXT]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int maxmsg
char dialout[80]
static int maxdeletedmsg
char callback[80]
static int passwordlocation
static char callcontext[AST_MAX_CONTEXT]
static void prep_email_sub_vars ( struct ast_channel ast,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
const char *  fromfolder,
char *  cidnum,
char *  cidname,
char *  dur,
char *  date,
const char *  category,
const char *  flag 
)
static

Definition at line 4356 of file app_voicemail_odbcstorage.c.

References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), S_OR, and valid_config().

Referenced by make_email_file(), and sendpage().

4357 {
4358  char callerid[256];
4359  char num[12];
4360  char fromdir[256], fromfile[256];
4361  struct ast_config *msg_cfg;
4362  const char *origcallerid, *origtime;
4363  char origcidname[80], origcidnum[80], origdate[80];
4364  int inttime;
4365  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
4366 
4367  /* Prepare variables for substitution in email body and subject */
4368  pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
4369  pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
4370  snprintf(num, sizeof(num), "%d", msgnum);
4371  pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num);
4372  pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
4373  pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
4374  pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
4375  ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
4376  pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
4377  pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
4378  pbx_builtin_setvar_helper(ast, "VM_DATE", date);
4379  pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
4380  pbx_builtin_setvar_helper(ast, "VM_FLAG", flag);
4381 
4382  /* Retrieve info from VM attribute file */
4383  make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
4384  make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
4385  if (strlen(fromfile) < sizeof(fromfile) - 5) {
4386  strcat(fromfile, ".txt");
4387  }
4388  if (!(msg_cfg = ast_config_load(fromfile, config_flags)) || !(valid_config(msg_cfg))) {
4389  if (option_debug > 0) {
4390  ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
4391  }
4392  return;
4393  }
4394 
4395  if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
4396  pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
4397  ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
4398  pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
4399  pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
4400  }
4401 
4402  if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) {
4403  struct timeval tv = { inttime, };
4404  struct ast_tm tm;
4405  ast_localtime(&tv, &tm, NULL);
4406  ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL));
4407  pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
4408  }
4409  ast_config_destroy(msg_cfg);
4410 }
char fullname[80]
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1093
int option_debug
Definition: asterisk.c:182
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
#define LOG_DEBUG
Definition: logger.h:122
char locale[20]
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
char * ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown)
Definition: callerid.c:1074
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
int ast_strftime_locale(char *buf, size_t len, const char *format, const struct ast_tm *tm, const char *locale)
Definition: localtime.c:2280
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static char emaildateformat[32]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
Structure used to handle boolean flags.
Definition: utils.h:200
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct timeval tv
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int make_dir(char *dest, int len, const char *context, const char *ext, const char *folder)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static void queue_mwi_event ( const char *  box,
int  urgent,
int  new,
int  old 
)
static

Definition at line 7047 of file app_voicemail_odbcstorage.c.

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

Referenced by append_mailbox(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().

7048 {
7049  struct ast_event *event;
7050  char *mailbox, *context;
7051 
7052  /* Strip off @default */
7053  context = mailbox = ast_strdupa(box);
7054  strsep(&context, "@");
7055  if (ast_strlen_zero(context))
7056  context = "default";
7057 
7058  if (!(event = ast_event_new(AST_EVENT_MWI,
7063  AST_EVENT_IE_END))) {
7064  return;
7065  }
7066 
7068 }
An event.
Definition: event.c:85
char * strsep(char **str, const char *delims)
int ast_event_queue_and_cache(struct ast_event *event)
Queue and cache an event.
Definition: event.c:1465
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:71
Number of Used by: AST_EVENT_MWI Payload type: UINT.
Definition: event_defs.h:77
Context IE Used by AST_EVENT_MWI Payload type: str.
Definition: event_defs.h:121
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:1202
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
Mailbox name.
Definition: event_defs.h:83
static void read_password_from_file ( const char *  secretfn,
char *  password,
int  passwordlen 
)
static

Definition at line 12494 of file app_voicemail_odbcstorage.c.

References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), LOG_NOTICE, and valid_config().

Referenced by actual_load_config(), and append_mailbox().

12494  {
12495  struct ast_config *pwconf;
12496  struct ast_flags config_flags = { 0 };
12497 
12498  pwconf = ast_config_load(secretfn, config_flags);
12499  if (valid_config(pwconf)) {
12500  const char *val = ast_variable_retrieve(pwconf, "general", "password");
12501  if (val) {
12502  ast_copy_string(password, val, passwordlen);
12503  ast_config_destroy(pwconf);
12504  return;
12505  }
12506  ast_config_destroy(pwconf);
12507  }
12508  ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn);
12509 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
Definition: ast_expr2.c:325
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int reload ( void  )
static

Definition at line 13025 of file app_voicemail_odbcstorage.c.

References load_config().

13026 {
13027  return load_config(1);
13028 }
static int load_config(int reload)
static void rename_file ( char *  sfn,
char *  dfn 
)
static

Renames a message in a mailbox folder.

Parameters
sfnThe path to the mailbox information and data file to be renamed.
dfnThe path for where the message data and information files will be renamed to.

This method is used by the RENAME macro when mailboxes are stored on the filesystem. (not ODBC and not IMAP).

Definition at line 4026 of file app_voicemail_odbcstorage.c.

References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.

4027 {
4028  char stxt[PATH_MAX];
4029  char dtxt[PATH_MAX];
4030  ast_filerename(sfn, dfn, NULL);
4031  snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
4032  snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
4033  if (ast_check_realtime("voicemail_data")) {
4034  ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL);
4035  }
4036  rename(stxt, dtxt);
4037 }
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
Definition: config.c:2679
#define SENTINEL
Definition: compiler.h:75
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
static int resequence_mailbox ( struct ast_vm_user vmu,
char *  dir,
int  stopcount 
)
static

Definition at line 6173 of file app_voicemail_odbcstorage.c.

References ast_unlock_path(), ast_vm_user::context, ERROR_LOCK_PATH, EXISTS, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, RENAME, and vm_lock_path().

Referenced by open_mailbox().

6174 {
6175  /* we know the actual number of messages, so stop process when number is hit */
6176 
6177  int x, dest;
6178  char sfn[PATH_MAX];
6179  char dfn[PATH_MAX];
6180 
6181  if (vm_lock_path(dir)) {
6182  return ERROR_LOCK_PATH;
6183  }
6184 
6185  for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) {
6186  make_file(sfn, sizeof(sfn), dir, x);
6187  if (EXISTS(dir, x, sfn, NULL)) {
6188 
6189  if (x != dest) {
6190  make_file(dfn, sizeof(dfn), dir, dest);
6191  RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
6192  }
6193 
6194  dest++;
6195  }
6196  }
6197  ast_unlock_path(dir);
6198 
6199  return dest;
6200 }
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#define RENAME(a, b, c, d, e, f, g, h)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
#define EXISTS(a, b, c, d)
#define ERROR_LOCK_PATH
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
static int reset_user_pw ( const char *  context,
const char *  mailbox,
const char *  newpass 
)
static

Resets a user password to a specified password.

Parameters
context
mailbox
newpassThis does the actual change password work, called by the vm_change_password() function.
Returns
zero on success, -1 on error.

Definition at line 1465 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, ast_vm_user::mailbox, and ast_vm_user::password.

Referenced by vm_change_password(), and vm_change_password_shell().

1466 {
1467  /* This function could be made to generate one from a database, too */
1468  struct ast_vm_user *cur;
1469  int res = -1;
1470  AST_LIST_LOCK(&users);
1471  AST_LIST_TRAVERSE(&users, cur, list) {
1472  if ((!context || !strcasecmp(context, cur->context)) &&
1473  (!strcasecmp(mailbox, cur->mailbox)))
1474  break;
1475  }
1476  if (cur) {
1477  ast_copy_string(cur->password, newpass, sizeof(cur->password));
1478  res = 0;
1479  }
1481  return res;
1482 }
#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
list of users found in the config file
struct ast_vm_user::@65 list
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#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:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
char password[80]
static void run_externnotify ( char *  context,
char *  extension,
const char *  flag 
)
static

Definition at line 5541 of file app_voicemail_odbcstorage.c.

References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_safe_system(), ast_smdi_mwi_message_destroy(), ast_smdi_mwi_message_wait_station(), ast_smdi_mwi_set(), ast_smdi_mwi_unset(), ast_strlen_zero(), ASTOBJ_UNREF, ast_smdi_mwi_message::cause, ast_smdi_mwi_message::fwd_st, inboxcount2(), S_OR, and SMDI_MWI_WAIT_TIMEOUT.

Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().

5542 {
5543  char arguments[255];
5544  char ext_context[256] = "";
5545  int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0;
5546  struct ast_smdi_mwi_message *mwi_msg;
5547 
5548  if (!ast_strlen_zero(context))
5549  snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
5550  else
5551  ast_copy_string(ext_context, extension, sizeof(ext_context));
5552 
5553  if (smdi_iface) {
5554  if (ast_app_has_voicemail(ext_context, NULL))
5556  else
5558 
5560  ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
5561  if (!strncmp(mwi_msg->cause, "INV", 3))
5562  ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
5563  else if (!strncmp(mwi_msg->cause, "BLK", 3))
5564  ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
5565  ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
5567  } else {
5568  ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension);
5569  }
5570  }
5571 
5572  if (!ast_strlen_zero(externnotify)) {
5573  if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) {
5574  ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
5575  } else {
5576  snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &",
5577  externnotify, S_OR(context, "\"\""),
5578  extension, newvoicemails,
5579  oldvoicemails, urgentvoicemails);
5580  ast_debug(1, "Executing %s\n", arguments);
5581  ast_safe_system(arguments);
5582  }
5583  }
5584 }
#define SMDI_MWI_WAIT_TIMEOUT
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
int ast_app_has_voicemail(const char *mailbox, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to &quot;INBOX&quot;. If folder is &quot;INBOX&quot;, includes the number of messages in the &quot;Urgent&quot; folder.
Definition: app.c:421
static char externnotify[160]
#define AST_LOG_WARNING
Definition: logger.h:149
char cause[SMDI_MWI_FAIL_CAUSE_LEN+1]
Definition: smdi.h:58
int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox)
Set the MWI indicator for a mailbox.
Definition: res_smdi.c:319
static struct ast_smdi_interface * smdi_iface
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_LOG_ERROR
Definition: logger.h:160
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char fwd_st[SMDI_MAX_STATION_NUM_LEN+1]
Definition: smdi.h:56
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg)
ast_smdi_mwi_message destructor.
Definition: res_smdi.c:829
int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox)
Unset the MWI indicator for a mailbox.
Definition: res_smdi.c:324
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_smdi_mwi_message * ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface, int timeout, const char *station)
Definition: res_smdi.c:620
An SMDI message waiting indicator message.
Definition: smdi.h:55
static int save_to_folder ( struct ast_vm_user vmu,
struct vm_state vms,
int  msg,
int  box 
)
static

Definition at line 6210 of file app_voicemail_odbcstorage.c.

References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock, ast_mutex_unlock, ast_unlock_path(), ast_vm_user::context, COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().

Referenced by close_mailbox(), and vm_execmain().

6211 {
6212 #ifdef IMAP_STORAGE
6213  /* we must use mbox(x) folder names, and copy the message there */
6214  /* simple. huh? */
6215  char sequence[10];
6216  char mailbox[256];
6217  int res;
6218 
6219  /* get the real IMAP message number for this message */
6220  snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
6221 
6222  ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box));
6223  ast_mutex_lock(&vms->lock);
6224  /* if save to Old folder, put in INBOX as read */
6225  if (box == OLD_FOLDER) {
6226  mail_setflag(vms->mailstream, sequence, "\\Seen");
6227  mail_clearflag(vms->mailstream, sequence, "\\Unseen");
6228  } else if (box == NEW_FOLDER) {
6229  mail_setflag(vms->mailstream, sequence, "\\Unseen");
6230  mail_clearflag(vms->mailstream, sequence, "\\Seen");
6231  }
6232  if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) {
6233  ast_mutex_unlock(&vms->lock);
6234  return 0;
6235  }
6236  /* Create the folder if it don't exist */
6237  imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */
6238  ast_debug(5, "Checking if folder exists: %s\n", mailbox);
6239  if (mail_create(vms->mailstream, mailbox) == NIL)
6240  ast_debug(5, "Folder exists.\n");
6241  else
6242  ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
6243  res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box));
6244  ast_mutex_unlock(&vms->lock);
6245  return res;
6246 #else
6247  char *dir = vms->curdir;
6248  char *username = vms->username;
6249  char *context = vmu->context;
6250  char sfn[PATH_MAX];
6251  char dfn[PATH_MAX];
6252  char ddir[PATH_MAX];
6253  const char *dbox = mbox(vmu, box);
6254  int x, i;
6255  create_dirpath(ddir, sizeof(ddir), context, username, dbox);
6256 
6257  if (vm_lock_path(ddir))
6258  return ERROR_LOCK_PATH;
6259 
6260  x = last_message_index(vmu, ddir) + 1;
6261 
6262  if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/
6263  x--;
6264  for (i = 1; i <= x; i++) {
6265  /* Push files down a "slot". The oldest file (msg0000) will be deleted. */
6266  make_file(sfn, sizeof(sfn), ddir, i);
6267  make_file(dfn, sizeof(dfn), ddir, i - 1);
6268  if (EXISTS(ddir, i, sfn, NULL)) {
6269  RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn);
6270  } else
6271  break;
6272  }
6273  } else {
6274  if (x >= vmu->maxmsg) {
6275  ast_unlock_path(ddir);
6276  return -1;
6277  }
6278  }
6279  make_file(sfn, sizeof(sfn), dir, msg);
6280  make_file(dfn, sizeof(dfn), ddir, x);
6281  if (strcmp(sfn, dfn)) {
6282  COPY(dir, msg, ddir, x, username, context, sfn, dfn);
6283  }
6284  ast_unlock_path(ddir);
6285 #endif
6286  return 0;
6287 }
static int last_message_index(struct ast_vm_user *vmu, char *dir)
Determines the highest message number in use for a given user and mailbox folder. ...
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
char curdir[PATH_MAX]
#define ast_mutex_lock(a)
Definition: lock.h:155
#define AST_LOG_NOTICE
Definition: logger.h:138
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define COPY(a, b, c, d, e, f, g, h)
char mailbox[AST_MAX_EXTENSION]
char username[80]
char context[AST_MAX_CONTEXT]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char * mbox(struct ast_vm_user *vmu, int id)
#define RENAME(a, b, c, d, e, f, g, h)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
#define EXISTS(a, b, c, d)
#define ERROR_LOCK_PATH
char curbox[80]
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int vm_lock_path(const char *path)
Lock file path only return failure if ast_lock_path returns &#39;timeout&#39;, not if the path does not exist...
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int say_and_wait ( struct ast_channel chan,
int  num,
const char *  language 
)
static

Definition at line 6203 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, and ast_say_number().

Referenced by play_message_duration(), vm_execmain(), vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_it(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_se(), vm_intro_vi(), and vm_intro_zh().

6204 {
6205  int d;
6206  d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL);
6207  return d;
6208 }
#define AST_DIGIT_ANY
Definition: file.h:47
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
static int sayname ( struct ast_channel chan,
const char *  mailbox,
const char *  context 
)
static

Definition at line 12480 of file app_voicemail_odbcstorage.c.

References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.

Referenced by load_module(), and vmsayname_exec().

12481 {
12482  int res = -1;
12483  char dir[PATH_MAX];
12484  snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox);
12485  ast_debug(2, "About to try retrieving name file %s\n", dir);
12486  RETRIEVE(dir, -1, mailbox, context);
12487  if (ast_fileexists(dir, NULL, NULL)) {
12488  res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY);
12489  }
12490  DISPOSE(dir, -1);
12491  return res;
12492 }
#define AST_DIGIT_ANY
Definition: file.h:47
#define RETRIEVE(a, b, c, d)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static char VM_SPOOL_DIR[PATH_MAX]
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
#define DISPOSE(a, b)
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int sendmail ( char *  srcemail,
struct ast_vm_user vmu,
int  msgnum,
char *  context,
char *  mailbox,
const char *  fromfolder,
char *  cidnum,
char *  cidname,
char *  attach,
char *  attach2,
char *  format,
int  duration,
int  attach_user_voicemail,
struct ast_channel chan,
const char *  category,
const char *  flag 
)
static

Definition at line 4871 of file app_voicemail_odbcstorage.c.

References ast_debug, ast_log(), AST_LOG_WARNING, ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, format, ast_vm_user::mailbox, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().

Referenced by forward_message(), and notify_new_message().

4872 {
4873  FILE *p = NULL;
4874  char tmp[80] = "/tmp/astmail-XXXXXX";
4875  char tmp2[256];
4876  char *stringp;
4877 
4878  if (vmu && ast_strlen_zero(vmu->email)) {
4879  ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox);
4880  return(0);
4881  }
4882 
4883  /* Mail only the first format */
4885  stringp = format;
4886  strsep(&stringp, "|");
4887 
4888  if (!strcmp(format, "wav49"))
4889  format = "WAV";
4890  ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %u\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH));
4891  /* Make a temporary file instead of piping directly to sendmail, in case the mail
4892  command hangs */
4893  if ((p = vm_mkftemp(tmp)) == NULL) {
4894  ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
4895  return -1;
4896  } else {
4897  make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag);
4898  fclose(p);
4899  snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
4900  ast_safe_system(tmp2);
4901  ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
4902  }
4903  return 0;
4904 }
static struct ast_flags globalflags
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
char * strsep(char **str, const char *delims)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_LOG_WARNING
Definition: logger.h:149
#define VM_ATTACH
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static FILE * vm_mkftemp(char *template)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static snd_pcm_format_t format
Definition: chan_alsa.c:93
char email[80]
static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag)
Creates the email file to be sent to indicate a new voicemail exists for a user.
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static char mailcmd[160]
static int sendpage ( char *  srcemail,
char *  pager,
int  msgnum,
char *  context,
char *  mailbox,
const char *  fromfolder,
char *  cidnum,
char *  cidname,
int  duration,
struct ast_vm_user vmu,
const char *  category,
const char *  flag 
)
static

Definition at line 4906 of file app_voicemail_odbcstorage.c.

References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_log(), AST_LOG_WARNING, 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_strftime_locale(), ast_strlen_zero(), check_mime(), ENDL, first_line, ast_vm_user::fullname, ast_vm_user::locale, MAXHOSTNAMELEN, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().

Referenced by notify_new_message().

4907 {
4908  char enc_cidnum[256], enc_cidname[256];
4909  char date[256];
4910  char host[MAXHOSTNAMELEN] = "";
4911  char who[256];
4912  char dur[PATH_MAX];
4913  char tmp[80] = "/tmp/astmail-XXXXXX";
4914  char tmp2[PATH_MAX];
4915  struct ast_tm tm;
4916  FILE *p;
4917  struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
4918 
4919  if (!str1 || !str2) {
4920  ast_free(str1);
4921  ast_free(str2);
4922  return -1;
4923  }
4924 
4925  if (cidnum) {
4926  strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum));
4927  }
4928  if (cidname) {
4929  strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
4930  }
4931 
4932  if ((p = vm_mkftemp(tmp)) == NULL) {
4933  ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
4934  ast_free(str1);
4935  ast_free(str2);
4936  return -1;
4937  }
4938  gethostname(host, sizeof(host)-1);
4939  if (strchr(srcemail, '@')) {
4940  ast_copy_string(who, srcemail, sizeof(who));
4941  } else {
4942  snprintf(who, sizeof(who), "%s@%s", srcemail, host);
4943  }
4944  snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
4945  ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
4946  fprintf(p, "Date: %s\n", date);
4947 
4948  /* Reformat for custom pager format */
4949  ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL));
4950 
4952  struct ast_channel *ast;
4953  if ((ast = ast_dummy_channel_alloc())) {
4954  char *ptr;
4955  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag);
4957 
4958  if (check_mime(ast_str_buffer(str1))) {
4959  int first_line = 1;
4960  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3);
4961  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4962  *ptr = '\0';
4963  fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2));
4964  first_line = 0;
4965  /* Substring is smaller, so this will never grow */
4966  ast_str_set(&str2, 0, "%s", ptr + 1);
4967  }
4968  fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who);
4969  } else {
4970  fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who);
4971  }
4972  ast = ast_channel_unref(ast);
4973  } else {
4974  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4975  }
4976  } else {
4977  fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
4978  }
4979 
4980  if (check_mime(vmu->fullname)) {
4981  int first_line = 1;
4982  char *ptr;
4983  ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3);
4984  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4985  *ptr = '\0';
4986  fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2));
4987  first_line = 0;
4988  /* Substring is smaller, so this will never grow */
4989  ast_str_set(&str2, 0, "%s", ptr + 1);
4990  }
4991  fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager);
4992  } else {
4993  fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager);
4994  }
4995 
4996  if (!ast_strlen_zero(pagersubject)) {
4997  struct ast_channel *ast;
4998  if ((ast = ast_dummy_channel_alloc())) {
4999  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
5001  if (check_mime(ast_str_buffer(str1))) {
5002  int first_line = 1;
5003  char *ptr;
5004  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0);
5005  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
5006  *ptr = '\0';
5007  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
5008  first_line = 0;
5009  /* Substring is smaller, so this will never grow */
5010  ast_str_set(&str2, 0, "%s", ptr + 1);
5011  }
5012  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
5013  } else {
5014  fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1));
5015  }
5016  ast = ast_channel_unref(ast);
5017  } else {
5018  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
5019  }
5020  } else {
5021  if (ast_strlen_zero(flag)) {
5022  fprintf(p, "Subject: New VM\n\n");
5023  } else {
5024  fprintf(p, "Subject: New %s VM\n\n", flag);
5025  }
5026  }
5027 
5028  if (pagerbody) {
5029  struct ast_channel *ast;
5030  if ((ast = ast_dummy_channel_alloc())) {
5031  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
5032  ast_str_substitute_variables(&str1, 0, ast, pagerbody);
5033  fprintf(p, "%s" ENDL, ast_str_buffer(str1));
5034  ast = ast_channel_unref(ast);
5035  } else {
5036  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
5037  }
5038  } else {
5039  fprintf(p, "New %s long %s msg in box %s\n"
5040  "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
5041  }
5042 
5043  fclose(p);
5044  snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
5045  ast_safe_system(tmp2);
5046  ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd);
5047  ast_free(str1);
5048  ast_free(str2);
5049  return 0;
5050 }
static const char * ast_str_encode_mime(struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble)
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain ...
Main Channel structure associated with a channel.
Definition: channel.h:742
static int check_mime(const char *str)
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail sof...
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
char fullname[80]
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
static char pagerdateformat[32]
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define AST_LOG_WARNING
Definition: logger.h:149
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Definition: pbx.c:4468
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define MAXHOSTNAMELEN
Definition: network.h:69
char locale[20]
static void prep_email_sub_vars(struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static FILE * vm_mkftemp(char *template)
static char * pagersubject
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char * strip_control_and_high(const char *input, char *buf, size_t buflen)
Strips control and non 7-bit clean characters from input string.
int ast_strftime_locale(char *buf, size_t len, const char *format, const struct ast_tm *tm, const char *locale)
Definition: localtime.c:2280
static char * pagerbody
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static struct ast_tm * vmu_tm(const struct ast_vm_user *vmu, struct ast_tm *tm)
fill in *tm for current time according to the proper timezone, if any.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char * ast_str_quote(struct ast_str **buf, ssize_t maxlen, const char *from)
Wraps a character sequence in double quotes, escaping occurences of quotes within the string...
#define ast_free(a)
Definition: astmm.h:97
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static char pagerfromstring[100]
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static char mailcmd[160]
#define ENDL
yylloc first_line
Definition: ast_expr2.c:1857
static char* show_users_realtime ( int  fd,
const char *  context 
)
static

Definition at line 11045 of file app_voicemail_odbcstorage.c.

References ast_category_browse(), ast_cli(), ast_config_destroy(), ast_load_realtime_multientry(), ast_variable_browse(), CLI_FAILURE, CLI_SUCCESS, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

Referenced by handle_voicemail_show_users().

11046 {
11047  struct ast_config *cfg;
11048  const char *cat = NULL;
11049 
11050  if (!(cfg = ast_load_realtime_multientry("voicemail",
11051  "context", context, SENTINEL))) {
11052  return CLI_FAILURE;
11053  }
11054 
11055  ast_cli(fd,
11056  "\n"
11057  "=============================================================\n"
11058  "=== Configured Voicemail Users ==============================\n"
11059  "=============================================================\n"
11060  "===\n");
11061 
11062  while ((cat = ast_category_browse(cfg, cat))) {
11063  struct ast_variable *var = NULL;
11064  ast_cli(fd,
11065  "=== Mailbox ...\n"
11066  "===\n");
11067  for (var = ast_variable_browse(cfg, cat); var; var = var->next)
11068  ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value);
11069  ast_cli(fd,
11070  "===\n"
11071  "=== ---------------------------------------------------------\n"
11072  "===\n");
11073  }
11074 
11075  ast_cli(fd,
11076  "=============================================================\n"
11077  "\n");
11078 
11079  ast_config_destroy(cfg);
11080 
11081  return CLI_SUCCESS;
11082 }
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define SENTINEL
Definition: compiler.h:75
const char * value
Definition: config.h:79
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
#define CLI_FAILURE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:43
struct ast_variable * next
Definition: config.h:82
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2650
static void start_poll_thread ( void  )
static

Definition at line 11550 of file app_voicemail_odbcstorage.c.

References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_log(), ast_pthread_create, LOG_ERROR, mb_poll_thread(), mwi_sub_event_cb(), and mwi_unsub_event_cb().

Referenced by actual_load_config().

11551 {
11552  int errcode;
11553  mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL,
11556 
11557  mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL,
11560 
11561  if (mwi_sub_sub)
11563 
11564  poll_thread_run = 1;
11565 
11566  if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) {
11567  ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode));
11568  }
11569 }
static void mwi_unsub_event_cb(const struct ast_event *event, void *userdata)
static void * mb_poll_thread(void *data)
static struct ast_event_sub * mwi_sub_sub
void ast_event_report_subs(const struct ast_event_sub *sub)
Report current subscriptions to a subscription subscriber.
Definition: event.c:701
Event type Used by: AST_EVENT_SUB, AST_EVENT_UNSUB Payload type: UINT.
Definition: event_defs.h:95
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static unsigned char poll_thread_run
static struct ast_event_sub * mwi_unsub_sub
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:418
static pthread_t poll_thread
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
Definition: event.c:909
static void mwi_sub_event_cb(const struct ast_event *event, void *userdata)
static void stop_poll_thread ( void  )
static

Definition at line 11571 of file app_voicemail_odbcstorage.c.

References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, and poll_lock.

Referenced by actual_load_config(), and unload_module().

11572 {
11573  poll_thread_run = 0;
11574 
11575  if (mwi_sub_sub) {
11577  mwi_sub_sub = NULL;
11578  }
11579 
11580  if (mwi_unsub_sub) {
11582  mwi_unsub_sub = NULL;
11583  }
11584 
11588 
11589  pthread_join(poll_thread, NULL);
11590 
11592 }
static struct ast_event_sub * mwi_sub_sub
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
static ast_mutex_t poll_lock
#define AST_PTHREADT_NULL
Definition: lock.h:65
static ast_cond_t poll_cond
static unsigned char poll_thread_run
static struct ast_event_sub * mwi_unsub_sub
static pthread_t poll_thread
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
Definition: event.c:987
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* strip_control_and_high ( const char *  input,
char *  buf,
size_t  buflen 
)
static

Strips control and non 7-bit clean characters from input string.

Note
To map control and none 7-bit characters to a 7-bit clean characters please use ast_str_encode_mine().

Definition at line 965 of file app_voicemail_odbcstorage.c.

References input().

Referenced by make_email_file(), and sendpage().

966 {
967  char *bufptr = buf;
968  for (; *input; input++) {
969  if (*input < 32) {
970  continue;
971  }
972  *bufptr++ = *input;
973  if (bufptr == buf + buflen - 1) {
974  break;
975  }
976  }
977  *bufptr = '\0';
978  return buf;
979 }
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1575
static const char * substitute_escapes ( const char *  value)
static

Definition at line 11717 of file app_voicemail_odbcstorage.c.

References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_buffer(), ast_str_reset(), and ast_str_thread_get().

Referenced by actual_load_config(), apply_option(), and apply_options_full().

11718 {
11719  char *current;
11720 
11721  /* Add 16 for fudge factor */
11722  struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16);
11723 
11724  ast_str_reset(str);
11725 
11726  /* Substitute strings \r, \n, and \t into the appropriate characters */
11727  for (current = (char *) value; *current; current++) {
11728  if (*current == '\\') {
11729  current++;
11730  if (!*current) {
11731  ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n");
11732  break;
11733  }
11734  switch (*current) {
11735  case '\\':
11736  ast_str_append(&str, 0, "\\");
11737  break;
11738  case 'r':
11739  ast_str_append(&str, 0, "\r");
11740  break;
11741  case 'n':
11742 #ifdef IMAP_STORAGE
11743  if (!str->used || str->str[str->used - 1] != '\r') {
11744  ast_str_append(&str, 0, "\r");
11745  }
11746 #endif
11747  ast_str_append(&str, 0, "\n");
11748  break;
11749  case 't':
11750  ast_str_append(&str, 0, "\t");
11751  break;
11752  default:
11753  ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current);
11754  break;
11755  }
11756  } else {
11757  ast_str_append(&str, 0, "%c", *current);
11758  }
11759  }
11760 
11761  return ast_str_buffer(str);
11762 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
const char * str
Definition: app_jack.c:144
int value
Definition: syslog.c:39
#define AST_LOG_NOTICE
Definition: logger.h:138
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:436
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:669
static int unload_module ( void  )
static

Definition at line 13030 of file app_voicemail_odbcstorage.c.

References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), free_vm_users(), free_vm_zones(), and stop_poll_thread().

13031 {
13032  int res;
13033 
13040  res |= ast_manager_unregister("VoicemailUsersList");
13041  res |= ast_data_unregister(NULL);
13042 #ifdef TEST_FRAMEWORK
13043  res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname);
13044  res |= AST_TEST_UNREGISTER(test_voicemail_msgcount);
13045  res |= AST_TEST_UNREGISTER(test_voicemail_vmuser);
13046  res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl);
13047  res |= AST_TEST_UNREGISTER(test_voicemail_load_config);
13048 #endif
13052 
13054  stop_poll_thread();
13055 
13057  ast_unload_realtime("voicemail");
13058  ast_unload_realtime("voicemail_data");
13059 
13060  free_vm_users();
13061  free_vm_zones();
13062  return res;
13063 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: config.c:2630
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static void free_vm_zones(void)
Free the zones structure.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static char * app
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ast_data_unregister(path)
Definition: data.h:394
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static void stop_poll_thread(void)
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static char * app4
static pthread_t poll_thread
static struct ast_cli_entry cli_voicemail[]
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
static char * app3
static struct ast_custom_function mailbox_exists_acf
static char * app2
static void free_vm_users(void)
Free the users structure.
static char * sayname_app
static struct ast_taskprocessor * mwi_subscription_tps
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
struct ao2_container * inprocess_container
void ast_uninstall_vm_functions(void)
Definition: app.c:412
static int valid_config ( const struct ast_config cfg)
inlinestatic

Check if configuration file is valid.

Definition at line 1487 of file app_voicemail_odbcstorage.c.

References CONFIG_STATUS_FILEINVALID.

Referenced by advanced_options(), make_email_file(), play_message(), prep_email_sub_vars(), read_password_from_file(), vm_change_password(), and vm_forwardoptions().

1488 {
1489  return cfg && cfg != CONFIG_STATUS_FILEINVALID;
1490 }
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int vm_allocate_dh ( struct vm_state vms,
struct ast_vm_user vmu,
int  count_msg 
)
static

Definition at line 1748 of file app_voicemail_odbcstorage.c.

References ast_calloc, ast_free, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.

Referenced by open_mailbox().

1748  {
1749 
1750  int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg);
1751 
1752  /* remove old allocation */
1753  if (vms->deleted) {
1754  ast_free(vms->deleted);
1755  vms->deleted = NULL;
1756  }
1757  if (vms->heard) {
1758  ast_free(vms->heard);
1759  vms->heard = NULL;
1760  }
1761  vms->dh_arraysize = 0;
1762 
1763  if (arraysize > 0) {
1764  if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) {
1765  return -1;
1766  }
1767  if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) {
1768  ast_free(vms->deleted);
1769  vms->deleted = NULL;
1770  return -1;
1771  }
1772  vms->dh_arraysize = arraysize;
1773  }
1774 
1775  return 0;
1776 }
int dh_arraysize
int * heard
#define ast_free(a)
Definition: astmm.h:97
int * deleted
#define ast_calloc(a, b)
Definition: astmm.h:82
static int vm_authenticate ( struct ast_channel chan,
char *  mailbox,
int  mailbox_size,
struct ast_vm_user res_vmu,
const char *  context,
const char *  prefix,
int  skipuser,
int  max_logins,
int  silent 
)
static

Definition at line 9725 of file app_voicemail_odbcstorage.c.

References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_verb, ast_waitstream(), ast_channel::caller, ast_channel::context, find_user(), ast_party_caller::id, ast_channel::language, ast_party_id::number, ast_vm_user::password, S_COR, ast_party_number::str, and ast_party_number::valid.

Referenced by vm_execmain(), and vmauthenticate().

9728 {
9729  int useadsi = 0, valid = 0, logretries = 0;
9730  char password[AST_MAX_EXTENSION]="", *passptr;
9731  struct ast_vm_user vmus, *vmu = NULL;
9732 
9733  /* If ADSI is supported, setup login screen */
9734  adsi_begin(chan, &useadsi);
9735  if (!skipuser && useadsi)
9736  adsi_login(chan);
9737  if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
9738  ast_log(AST_LOG_WARNING, "Couldn't stream login file\n");
9739  return -1;
9740  }
9741 
9742  /* Authenticate them and get their mailbox/password */
9743 
9744  while (!valid && (logretries < max_logins)) {
9745  /* Prompt for, and read in the username */
9746  if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
9747  ast_log(AST_LOG_WARNING, "Couldn't read username\n");
9748  return -1;
9749  }
9750  if (ast_strlen_zero(mailbox)) {
9751  if (chan->caller.id.number.valid && chan->caller.id.number.str) {
9752  ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size);
9753  } else {
9754  ast_verb(3, "Username not entered\n");
9755  return -1;
9756  }
9757  } else if (mailbox[0] == '*') {
9758  /* user entered '*' */
9759  ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n");
9760  if (ast_exists_extension(chan, chan->context, "a", 1,
9761  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
9762  return -1;
9763  }
9764  ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n");
9765  mailbox[0] = '\0';
9766  }
9767 
9768  if (useadsi)
9769  adsi_password(chan);
9770 
9771  if (!ast_strlen_zero(prefix)) {
9772  char fullusername[80] = "";
9773  ast_copy_string(fullusername, prefix, sizeof(fullusername));
9774  strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
9775  ast_copy_string(mailbox, fullusername, mailbox_size);
9776  }
9777 
9778  ast_debug(1, "Before find user for mailbox %s\n", mailbox);
9779  vmu = find_user(&vmus, context, mailbox);
9780  if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
9781  /* saved password is blank, so don't bother asking */
9782  password[0] = '\0';
9783  } else {
9784  if (ast_streamfile(chan, vm_password, chan->language)) {
9785  ast_log(AST_LOG_WARNING, "Unable to stream password file\n");
9786  return -1;
9787  }
9788  if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
9789  ast_log(AST_LOG_WARNING, "Unable to read password\n");
9790  return -1;
9791  } else if (password[0] == '*') {
9792  /* user entered '*' */
9793  ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n");
9794  if (ast_exists_extension(chan, chan->context, "a", 1,
9795  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
9796  mailbox[0] = '*';
9797  return -1;
9798  }
9799  ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n");
9800  mailbox[0] = '\0';
9801  /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */
9802  vmu = NULL;
9803  }
9804  }
9805 
9806  if (vmu) {
9807  passptr = vmu->password;
9808  if (passptr[0] == '-') passptr++;
9809  }
9810  if (vmu && !strcmp(passptr, password))
9811  valid++;
9812  else {
9813  ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
9814  if (!ast_strlen_zero(prefix))
9815  mailbox[0] = '\0';
9816  }
9817  logretries++;
9818  if (!valid) {
9819  if (skipuser || logretries >= max_logins) {
9820  if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
9821  ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n");
9822  return -1;
9823  }
9824  } else {
9825  if (useadsi)
9826  adsi_login(chan);
9827  if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
9828  ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n");
9829  return -1;
9830  }
9831  }
9832  if (ast_waitstream(chan, "")) /* Channel is hung up */
9833  return -1;
9834  }
9835  }
9836  if (!valid && (logretries >= max_logins)) {
9837  ast_stopstream(chan);
9838  ast_play_and_wait(chan, "vm-goodbye");
9839  return -1;
9840  }
9841  if (vmu && !skipuser) {
9842  memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
9843  }
9844  return 0;
9845 }
static void adsi_password(struct ast_channel *chan)
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
static char vm_password[80]
#define AST_LOG_WARNING
Definition: logger.h:149
#define ast_verb(level,...)
Definition: logger.h:243
static void adsi_login(struct ast_channel *chan)
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void adsi_begin(struct ast_channel *chan, int *useadsi)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1343
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
char password[80]
static char prefix[MAX_PREFIX]
Definition: http.c:107
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int vm_box_exists ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10940 of file app_voicemail_odbcstorage.c.

References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), context, find_user(), mbox(), and pbx_builtin_setvar_helper().

Referenced by load_module().

10941 {
10942  struct ast_vm_user svm;
10943  char *context, *box;
10945  AST_APP_ARG(mbox);
10946  AST_APP_ARG(options);
10947  );
10948  static int dep_warning = 0;
10949 
10950  if (ast_strlen_zero(data)) {
10951  ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
10952  return -1;
10953  }
10954 
10955  if (!dep_warning) {
10956  dep_warning = 1;
10957  ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data);
10958  }
10959 
10960  box = ast_strdupa(data);
10961 
10963 
10964  if (args.options) {
10965  }
10966 
10967  if ((context = strchr(args.mbox, '@'))) {
10968  *context = '\0';
10969  context++;
10970  }
10971 
10972  if (find_user(&svm, context, args.mbox)) {
10973  pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
10974  } else
10975  pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
10976 
10977  return 0;
10978 }
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
#define AST_LOG_WARNING
Definition: logger.h:149
#define AST_LOG_ERROR
Definition: logger.h:160
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char * mbox(struct ast_vm_user *vmu, int id)
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int vm_browse_messages ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Top level method to invoke the language variant vm_browse_messages_XX function.

Parameters
chanThe channel for the current user. We read the language property from this.
vmspassed into the language-specific vm_browse_messages function.
vmupassed into the language-specific vm_browse_messages function.

The method to be invoked is determined by the value of language code property in the user's channel. The default (when unable to match) is to use english.

Returns
zero on success, -1 on error.

Definition at line 9707 of file app_voicemail_odbcstorage.c.

References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_he(), vm_browse_messages_latin(), vm_browse_messages_vi(), and vm_browse_messages_zh().

Referenced by vm_execmain().

9708 {
9709  if (!strncasecmp(chan->language, "es", 2) ||
9710  !strncasecmp(chan->language, "it", 2) ||
9711  !strncasecmp(chan->language, "pt", 2) ||
9712  !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
9713  return vm_browse_messages_latin(chan, vms, vmu);
9714  } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */
9715  return vm_browse_messages_he(chan, vms, vmu);
9716  } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */
9717  return vm_browse_messages_vi(chan, vms, vmu);
9718  } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */
9719  return vm_browse_messages_zh(chan, vms, vmu);
9720  } else { /* Default to English syntax */
9721  return vm_browse_messages_en(chan, vms, vmu);
9722  }
9723 }
static int vm_browse_messages_he(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages_en(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Default English syntax for &#39;You have N messages&#39; greeting.
static int vm_browse_messages_zh(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Chinese (Taiwan)syntax for &#39;You have N messages&#39; greeting.
const ast_string_field language
Definition: channel.h:787
static int vm_browse_messages_latin(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Common LATIN languages syntax for &#39;You have N messages&#39; greeting.
static int vm_browse_messages_vi(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Vietnamese syntax for &#39;You have N messages&#39; greeting.
static int vm_browse_messages_en ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Default English syntax for 'You have N messages' greeting.

Parameters
chan
vms
vmu
Returns
zero on success, -1 on error.

Definition at line 9588 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

9589 {
9590  int cmd = 0;
9591 
9592  if (vms->lastmsg > -1) {
9593  cmd = play_message(chan, vmu, vms);
9594  } else {
9595  cmd = ast_play_and_wait(chan, "vm-youhave");
9596  if (!cmd)
9597  cmd = ast_play_and_wait(chan, "vm-no");
9598  if (!cmd) {
9599  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9600  cmd = ast_play_and_wait(chan, vms->fn);
9601  }
9602  if (!cmd)
9603  cmd = ast_play_and_wait(chan, "vm-messages");
9604  }
9605  return cmd;
9606 }
char fn[PATH_MAX]
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
char curbox[80]
static int vm_browse_messages_he ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Definition at line 9564 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

9565 {
9566  int cmd = 0;
9567 
9568  if (vms->lastmsg > -1) {
9569  cmd = play_message(chan, vmu, vms);
9570  } else {
9571  if (!strcasecmp(vms->fn, "INBOX")) {
9572  cmd = ast_play_and_wait(chan, "vm-nonewmessages");
9573  } else {
9574  cmd = ast_play_and_wait(chan, "vm-nomessages");
9575  }
9576  }
9577  return cmd;
9578 }
char fn[PATH_MAX]
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_browse_messages_latin ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Common LATIN languages syntax for 'You have N messages' greeting.

Parameters
chan
vms
vmu
Returns
zero on success, -1 on error.

Definition at line 9617 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, play_message(), and vm_state::vmbox.

Referenced by vm_browse_messages().

9618 {
9619  int cmd;
9620 
9621  if (vms->lastmsg > -1) {
9622  cmd = play_message(chan, vmu, vms);
9623  } else {
9624  cmd = ast_play_and_wait(chan, "vm-youhaveno");
9625  if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
9626  if (!cmd) {
9627  snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
9628  cmd = ast_play_and_wait(chan, vms->fn);
9629  }
9630  if (!cmd)
9631  cmd = ast_play_and_wait(chan, "vm-messages");
9632  } else {
9633  if (!cmd)
9634  cmd = ast_play_and_wait(chan, "vm-messages");
9635  if (!cmd) {
9636  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9637  cmd = ast_play_and_wait(chan, vms->fn);
9638  }
9639  }
9640  }
9641  return cmd;
9642 }
char fn[PATH_MAX]
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
char vmbox[PATH_MAX]
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
char curbox[80]
static int vm_browse_messages_vi ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Vietnamese syntax for 'You have N messages' greeting.

Parameters
chan
vms
vmu
Returns
zero on success, -1 on error.

Definition at line 9680 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

9681 {
9682  int cmd = 0;
9683 
9684  if (vms->lastmsg > -1) {
9685  cmd = play_message(chan, vmu, vms);
9686  } else {
9687  cmd = ast_play_and_wait(chan, "vm-no");
9688  if (!cmd) {
9689  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9690  cmd = ast_play_and_wait(chan, vms->fn);
9691  }
9692  }
9693  return cmd;
9694 }
char fn[PATH_MAX]
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
char curbox[80]
static int vm_browse_messages_zh ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Chinese (Taiwan)syntax for 'You have N messages' greeting.

Parameters
chan
vms
vmu
Returns
zero on success, -1 on error.

Definition at line 9652 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().

Referenced by vm_browse_messages().

9653 {
9654  int cmd;
9655 
9656  if (vms->lastmsg > -1) {
9657  cmd = play_message(chan, vmu, vms);
9658  } else {
9659  cmd = ast_play_and_wait(chan, "vm-you");
9660  if (!cmd)
9661  cmd = ast_play_and_wait(chan, "vm-haveno");
9662  if (!cmd)
9663  cmd = ast_play_and_wait(chan, "vm-messages");
9664  if (!cmd) {
9665  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9666  cmd = ast_play_and_wait(chan, vms->fn);
9667  }
9668  }
9669  return cmd;
9670 }
char fn[PATH_MAX]
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
char curbox[80]
static void vm_change_password ( struct ast_vm_user vmu,
const char *  newpassword 
)
static

The handler for the change password option.

Parameters
vmuThe voicemail user to work with.
newpasswordThe new password (that has been gathered from the appropriate prompting). This is called when a new user logs in for the first time and the option to force them to change their password is set. It is also called when the user wants to change their password from menu option '5' on the mailbox options menu.

Definition at line 1499 of file app_voicemail_odbcstorage.c.

References ast_alloca, ast_category_browse(), ast_category_get(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_copy_string(), ast_debug, ast_free, ast_log(), AST_LOG_WARNING, ast_test_suite_event_notify, ast_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), valid_config(), value, var, VOICEMAIL_CONFIG, and write_password_to_file().

Referenced by vm_newuser(), and vm_options().

1500 {
1501  struct ast_config *cfg = NULL;
1502  struct ast_variable *var = NULL;
1503  struct ast_category *cat = NULL;
1504  char *category = NULL, *value = NULL, *new = NULL;
1505  const char *tmp = NULL;
1506  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
1507  char secretfn[PATH_MAX] = "";
1508  int found = 0;
1509 
1510  if (!change_password_realtime(vmu, newpassword))
1511  return;
1512 
1513  /* check if we should store the secret in the spool directory next to the messages */
1514  switch (vmu->passwordlocation) {
1515  case OPT_PWLOC_SPOOLDIR:
1516  snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
1517  if (write_password_to_file(secretfn, newpassword) == 0) {
1518  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf");
1519  ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn);
1520  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1521  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1522  break;
1523  } else {
1524  ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn);
1525  }
1526  /* Fall-through */
1528  if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && valid_config(cfg)) {
1529  while ((category = ast_category_browse(cfg, category))) {
1530  if (!strcasecmp(category, vmu->context)) {
1531  if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
1532  ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n");
1533  break;
1534  }
1535  value = strstr(tmp, ",");
1536  if (!value) {
1537  new = ast_alloca(strlen(newpassword)+1);
1538  sprintf(new, "%s", newpassword);
1539  } else {
1540  new = ast_alloca((strlen(value) + strlen(newpassword) + 1));
1541  sprintf(new, "%s%s", newpassword, value);
1542  }
1543  if (!(cat = ast_category_get(cfg, category))) {
1544  ast_log(AST_LOG_WARNING, "Failed to get category structure.\n");
1545  break;
1546  }
1547  ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
1548  found = 1;
1549  }
1550  }
1551  /* save the results */
1552  if (found) {
1553  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf");
1554  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1555  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1556  ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
1557  ast_config_destroy(cfg);
1558  break;
1559  }
1560 
1561  ast_config_destroy(cfg);
1562  }
1563  /* Fall-through */
1564  case OPT_PWLOC_USERSCONF:
1565  /* check users.conf and update the password stored for the mailbox */
1566  /* if no vmsecret entry exists create one. */
1567  if ((cfg = ast_config_load("users.conf", config_flags)) && valid_config(cfg)) {
1568  ast_debug(4, "we are looking for %s\n", vmu->mailbox);
1569  for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) {
1570  ast_debug(4, "users.conf: %s\n", category);
1571  if (!strcasecmp(category, vmu->mailbox)) {
1572  if (!ast_variable_retrieve(cfg, category, "vmsecret")) {
1573  ast_debug(3, "looks like we need to make vmsecret!\n");
1574  var = ast_variable_new("vmsecret", newpassword, "");
1575  } else {
1576  var = NULL;
1577  }
1578  new = ast_alloca(strlen(newpassword) + 1);
1579  sprintf(new, "%s", newpassword);
1580  if (!(cat = ast_category_get(cfg, category))) {
1581  ast_debug(4, "failed to get category!\n");
1582  ast_free(var);
1583  break;
1584  }
1585  if (!var) {
1586  ast_variable_update(cat, "vmsecret", new, NULL, 0);
1587  } else {
1588  ast_variable_append(cat, var);
1589  }
1590  found = 1;
1591  break;
1592  }
1593  }
1594  /* save the results and clean things up */
1595  if (found) {
1596  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf");
1597  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1598  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1599  ast_config_text_file_save("users.conf", cfg, "AppVoicemail");
1600  }
1601 
1602  ast_config_destroy(cfg);
1603  }
1604  }
1605 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define AST_LOG_WARNING
Definition: logger.h:149
#define var
Definition: ast_expr2f.c:606
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
Definition: config.c:1977
#define VOICEMAIL_CONFIG
int value
Definition: syslog.c:39
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name)
Retrieve a category if it exists.
Definition: config.c:709
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char mailbox[AST_MAX_EXTENSION]
int passwordlocation
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
char context[AST_MAX_CONTEXT]
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
static int write_password_to_file(const char *secretfn, const char *password)
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
Update variable value within a config.
Definition: config.c:942
Structure used to handle boolean flags.
Definition: utils.h:200
static int change_password_realtime(struct ast_vm_user *vmu, const char *password)
Performs a change of the voicemail passowrd in the realtime engine.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int reset_user_pw(const char *context, const char *mailbox, const char *newpass)
Resets a user password to a specified password.
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
char password[80]
static void vm_change_password_shell ( struct ast_vm_user vmu,
char *  newpassword 
)
static

Definition at line 1607 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().

Referenced by vm_newuser(), and vm_options().

1608 {
1609  char buf[255];
1610  snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword);
1611  ast_debug(1, "External password: %s\n",buf);
1612  if (!ast_safe_system(buf)) {
1613  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external");
1614  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1615  /* Reset the password in memory, too */
1616  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1617  }
1618 }
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static char ext_pass_cmd[128]
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int reset_user_pw(const char *context, const char *mailbox, const char *newpass)
Resets a user password to a specified password.
char password[80]
static char* vm_check_password_shell ( char *  command,
char *  buf,
size_t  len 
)
static

Definition at line 1162 of file app_voicemail_odbcstorage.c.

References AST_APP_ARG, ast_close_fds_above_n(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, ast_safe_fork(), ast_strdupa, errno, and LOG_WARNING.

Referenced by check_password().

1163 {
1164  int fds[2], pid = 0;
1165 
1166  memset(buf, 0, len);
1167 
1168  if (pipe(fds)) {
1169  snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno));
1170  } else {
1171  /* good to go*/
1172  pid = ast_safe_fork(0);
1173 
1174  if (pid < 0) {
1175  /* ok maybe not */
1176  close(fds[0]);
1177  close(fds[1]);
1178  snprintf(buf, len, "FAILURE: Fork failed");
1179  } else if (pid) {
1180  /* parent */
1181  close(fds[1]);
1182  if (read(fds[0], buf, len) < 0) {
1183  ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
1184  }
1185  close(fds[0]);
1186  } else {
1187  /* child */
1189  AST_APP_ARG(v)[20];
1190  );
1191  char *mycmd = ast_strdupa(command);
1192 
1193  close(fds[0]);
1194  dup2(fds[1], STDOUT_FILENO);
1195  close(fds[1]);
1196  ast_close_fds_above_n(STDOUT_FILENO);
1197 
1198  AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' ');
1199 
1200  execv(arg.v[0], arg.v);
1201  printf("FAILURE: %s", strerror(errno));
1202  _exit(0);
1203  }
1204  }
1205  return buf;
1206 }
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child...
Definition: app.c:2242
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Definition: app.c:2237
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the &#39;nonstandard&#39; argument separation process for an application.
Definition: app.h:619
static int vm_delete ( char *  file)
static

Removes the voicemail sound and information file.

Parameters
fileThe path to the sound file. This will be the the folder and message index, without the extension.

This is used by the DELETE macro when voicemails are stored on the file system.

Returns
zero on success, -1 on error.

Definition at line 4210 of file app_voicemail_odbcstorage.c.

References ast_alloca, ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.

Referenced by copy_message(), and notify_new_message().

4211 {
4212  char *txt;
4213  int txtsize = 0;
4214 
4215  txtsize = (strlen(file) + 5)*sizeof(char);
4216  txt = ast_alloca(txtsize);
4217  /* Sprintf here would safe because we alloca'd exactly the right length,
4218  * but trying to eliminate all sprintf's anyhow
4219  */
4220  if (ast_check_realtime("voicemail_data")) {
4221  ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL);
4222  }
4223  snprintf(txt, txtsize, "%s.txt", file);
4224  unlink(txt);
4225  return ast_filedelete(file, NULL);
4226 }
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
#define SENTINEL
Definition: compiler.h:75
int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Destroy realtime configuration.
Definition: config.c:2750
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: config.c:2587
static int vm_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 10599 of file app_voicemail_odbcstorage.c.

References ast_channel::_state, args, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_copy_flags, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_play_and_wait(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, leave_vm_options::exitcontext, leave_voicemail(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_DTMFEXIT, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), leave_vm_options::record_gain, and vm_app_options.

Referenced by load_module(), and play_record_review().

10600 {
10601  int res = 0;
10602  char *tmp;
10603  struct leave_vm_options leave_options;
10604  struct ast_flags flags = { 0 };
10605  char *opts[OPT_ARG_ARRAY_SIZE];
10607  AST_APP_ARG(argv0);
10608  AST_APP_ARG(argv1);
10609  );
10610 
10611  memset(&leave_options, 0, sizeof(leave_options));
10612 
10613  if (chan->_state != AST_STATE_UP)
10614  ast_answer(chan);
10615 
10616  if (!ast_strlen_zero(data)) {
10617  tmp = ast_strdupa(data);
10619  if (args.argc == 2) {
10620  if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
10621  return -1;
10623  if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
10624  int gain;
10625 
10626  if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
10627  ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
10628  return -1;
10629  } else {
10630  leave_options.record_gain = (signed char) gain;
10631  }
10632  }
10633  if (ast_test_flag(&flags, OPT_DTMFEXIT)) {
10634  if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT]))
10635  leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT];
10636  }
10637  }
10638  } else {
10639  char temp[256];
10640  res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0);
10641  if (res < 0)
10642  return res;
10643  if (ast_strlen_zero(temp))
10644  return 0;
10645  args.argv0 = ast_strdupa(temp);
10646  }
10647 
10648  res = leave_voicemail(chan, args.argv0, &leave_options);
10649  if (res == 't') {
10650  ast_play_and_wait(chan, "vm-goodbye");
10651  res = 0;
10652  }
10653 
10654  if (res == OPERATOR_EXIT) {
10655  res = 0;
10656  }
10657 
10658  if (res == ERROR_LOCK_PATH) {
10659  ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
10660  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
10661  res = 0;
10662  }
10663 
10664  return res;
10665 }
int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
Plays a stream and gets DTMF data from a channel.
Definition: app.c:178
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
unsigned int flags
Definition: utils.h:201
#define AST_LOG_WARNING
Definition: logger.h:149
static int leave_voicemail(struct ast_channel *chan, char *ext, struct leave_vm_options *options)
Prompts the user and records a voicemail to a mailbox.
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define AST_LOG_ERROR
Definition: logger.h:160
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_app_option vm_app_options[128]
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:635
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define ERROR_LOCK_PATH
#define OPERATOR_EXIT
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static int vm_execmain ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 9847 of file app_voicemail_odbcstorage.c.

References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), AST_LOG_WARNING, ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_suite_assert, ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), ast_vm_user::callback, close_mailbox(), ast_vm_user::context, vm_state::context, ast_channel::context, vm_state::curdir, vm_state::curmsg, vm_state::deleted, ast_vm_user::dialout, dialout(), ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), vm_state::fn, forward_message(), free_user(), get_folder2(), get_folder_by_name(), has_voicemail(), vm_state::heard, language, ast_vm_user::language, ast_channel::language, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, mbox(), NEW_FOLDER, vm_state::newmessages, OLD_FOLDER, vm_state::oldmessages, open_mailbox(), OPERATOR_EXIT, OPT_ARG_ARRAY_SIZE, OPT_ARG_PLAYFOLDER, OPT_ARG_RECORDGAIN, OPT_AUTOPLAY, OPT_PREPEND_MAILBOX, OPT_RECORDGAIN, OPT_SILENT, parse(), ast_vm_user::password, play_message(), queue_mwi_event(), vm_state::repeats, run_externnotify(), save_to_folder(), say_and_wait(), vm_state::starting, vm_state::urgentmessages, vm_state::username, vm_app_options, vm_authenticate(), vm_browse_messages(), VM_FORCEGREET, VM_FORCENAME, vm_instructions(), vm_intro(), VM_MESSAGEWRAP, vm_newuser(), vm_options(), vm_play_folder_name(), VM_SKIPAFTERCMD, VM_SVMAIL, and vm_state::vmbox.

Referenced by load_module().

9848 {
9849  /* XXX This is, admittedly, some pretty horrendous code. For some
9850  reason it just seemed a lot easier to do with GOTO's. I feel
9851  like I'm back in my GWBASIC days. XXX */
9852  int res = -1;
9853  int cmd = 0;
9854  int valid = 0;
9855  char prefixstr[80] ="";
9856  char ext_context[256]="";
9857  int box;
9858  int useadsi = 0;
9859  int skipuser = 0;
9860  struct vm_state vms;
9861  struct ast_vm_user *vmu = NULL, vmus;
9862  char *context = NULL;
9863  int silentexit = 0;
9864  struct ast_flags flags = { 0 };
9865  signed char record_gain = 0;
9866  int play_auto = 0;
9867  int play_folder = 0;
9868  int in_urgent = 0;
9869 #ifdef IMAP_STORAGE
9870  int deleted = 0;
9871 #endif
9872 
9873  /* Add the vm_state to the active list and keep it active */
9874  memset(&vms, 0, sizeof(vms));
9875 
9876  vms.lastmsg = -1;
9877 
9878  memset(&vmus, 0, sizeof(vmus));
9879 
9880  ast_test_suite_event_notify("START", "Message: vm_execmain started");
9881  if (chan->_state != AST_STATE_UP) {
9882  ast_debug(1, "Before ast_answer\n");
9883  ast_answer(chan);
9884  }
9885 
9886  if (!ast_strlen_zero(data)) {
9887  char *opts[OPT_ARG_ARRAY_SIZE];
9888  char *parse;
9890  AST_APP_ARG(argv0);
9891  AST_APP_ARG(argv1);
9892  );
9893 
9894  parse = ast_strdupa(data);
9895 
9896  AST_STANDARD_APP_ARGS(args, parse);
9897 
9898  if (args.argc == 2) {
9899  if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
9900  return -1;
9901  if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
9902  int gain;
9903  if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) {
9904  if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
9905  ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
9906  return -1;
9907  } else {
9908  record_gain = (signed char) gain;
9909  }
9910  } else {
9911  ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n");
9912  }
9913  }
9914  if (ast_test_flag(&flags, OPT_AUTOPLAY) ) {
9915  play_auto = 1;
9916  if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) {
9917  /* See if it is a folder name first */
9918  if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) {
9919  if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) {
9920  play_folder = -1;
9921  }
9922  } else {
9923  play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]);
9924  }
9925  } else {
9926  ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n");
9927  }
9928  if (play_folder > 9 || play_folder < 0) {
9930  "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n",
9931  opts[OPT_ARG_PLAYFOLDER]);
9932  play_folder = 0;
9933  }
9934  }
9935  } else {
9936  /* old style options parsing */
9937  while (*(args.argv0)) {
9938  if (*(args.argv0) == 's')
9939  ast_set_flag(&flags, OPT_SILENT);
9940  else if (*(args.argv0) == 'p')
9942  else
9943  break;
9944  (args.argv0)++;
9945  }
9946 
9947  }
9948 
9949  valid = ast_test_flag(&flags, OPT_SILENT);
9950 
9951  if ((context = strchr(args.argv0, '@')))
9952  *context++ = '\0';
9953 
9954  if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX))
9955  ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr));
9956  else
9957  ast_copy_string(vms.username, args.argv0, sizeof(vms.username));
9958 
9959  if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
9960  skipuser++;
9961  else
9962  valid = 0;
9963  }
9964 
9965  if (!valid)
9966  res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0);
9967 
9968  ast_debug(1, "After vm_authenticate\n");
9969 
9970  if (vms.username[0] == '*') {
9971  ast_debug(1, "user pressed * in context '%s'\n", chan->context);
9972 
9973  /* user entered '*' */
9974  if (!ast_goto_if_exists(chan, chan->context, "a", 1)) {
9975  ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension");
9976  res = 0; /* prevent hangup */
9977  goto out;
9978  }
9979  }
9980 
9981  if (!res) {
9982  valid = 1;
9983  if (!skipuser)
9984  vmu = &vmus;
9985  } else {
9986  res = 0;
9987  }
9988 
9989  /* If ADSI is supported, setup login screen */
9990  adsi_begin(chan, &useadsi);
9991 
9992  ast_test_suite_assert(valid);
9993  if (!valid) {
9994  goto out;
9995  }
9996  ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated");
9997 
9998 #ifdef IMAP_STORAGE
9999  pthread_once(&ts_vmstate.once, ts_vmstate.key_init);
10000  pthread_setspecific(ts_vmstate.key, &vms);
10001 
10002  vms.interactive = 1;
10003  vms.updated = 1;
10004  if (vmu)
10005  ast_copy_string(vms.context, vmu->context, sizeof(vms.context));
10006  vmstate_insert(&vms);
10007  init_vm_state(&vms);
10008 #endif
10009 
10010  /* Set language from config to override channel language */
10011  if (!ast_strlen_zero(vmu->language))
10012  ast_string_field_set(chan, language, vmu->language);
10013 
10014  /* Retrieve urgent, old and new message counts */
10015  ast_debug(1, "Before open_mailbox\n");
10016  res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */
10017  if (res < 0)
10018  goto out;
10019  vms.oldmessages = vms.lastmsg + 1;
10020  ast_debug(1, "Number of old messages: %d\n", vms.oldmessages);
10021  /* check INBOX */
10022  res = open_mailbox(&vms, vmu, NEW_FOLDER);
10023  if (res < 0)
10024  goto out;
10025  vms.newmessages = vms.lastmsg + 1;
10026  ast_debug(1, "Number of new messages: %d\n", vms.newmessages);
10027  /* Start in Urgent */
10028  in_urgent = 1;
10029  res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */
10030  if (res < 0)
10031  goto out;
10032  vms.urgentmessages = vms.lastmsg + 1;
10033  ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages);
10034 
10035  /* Select proper mailbox FIRST!! */
10036  if (play_auto) {
10037  ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages");
10038  if (vms.urgentmessages) {
10039  in_urgent = 1;
10040  res = open_mailbox(&vms, vmu, 11);
10041  } else {
10042  in_urgent = 0;
10043  res = open_mailbox(&vms, vmu, play_folder);
10044  }
10045  if (res < 0)
10046  goto out;
10047 
10048  /* If there are no new messages, inform the user and hangup */
10049  if (vms.lastmsg == -1) {
10050  in_urgent = 0;
10051  cmd = vm_browse_messages(chan, &vms, vmu);
10052  res = 0;
10053  goto out;
10054  }
10055  } else {
10056  if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) {
10057  /* If we only have old messages start here */
10058  res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */
10059  in_urgent = 0;
10060  play_folder = 1;
10061  if (res < 0)
10062  goto out;
10063  } else if (!vms.urgentmessages && vms.newmessages) {
10064  /* If we have new messages but none are urgent */
10065  in_urgent = 0;
10066  res = open_mailbox(&vms, vmu, NEW_FOLDER);
10067  if (res < 0)
10068  goto out;
10069  }
10070  }
10071 
10072  if (useadsi)
10073  adsi_status(chan, &vms);
10074  res = 0;
10075 
10076  /* Check to see if this is a new user */
10077  if (!strcasecmp(vmu->mailbox, vmu->password) &&
10079  if (ast_play_and_wait(chan, "vm-newuser") == -1)
10080  ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n");
10081  cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain);
10082  if ((cmd == 't') || (cmd == '#')) {
10083  /* Timeout */
10084  ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out");
10085  res = 0;
10086  goto out;
10087  } else if (cmd < 0) {
10088  /* Hangup */
10089  ast_test_suite_event_notify("HANGUP", "Message: hangup detected");
10090  res = -1;
10091  goto out;
10092  }
10093  }
10094 #ifdef IMAP_STORAGE
10095  ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit);
10096  if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) {
10097  ast_debug(1, "*** QUOTA EXCEEDED!!\n");
10098  cmd = ast_play_and_wait(chan, "vm-mailboxfull");
10099  }
10100  ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg);
10101  if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) {
10102  ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg);
10103  cmd = ast_play_and_wait(chan, "vm-mailboxfull");
10104  }
10105 #endif
10106 
10107  ast_test_suite_event_notify("INTRO", "Message: playing intro menu");
10108  if (play_auto) {
10109  cmd = '1';
10110  } else {
10111  cmd = vm_intro(chan, vmu, &vms);
10112  }
10113  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
10114 
10115  vms.repeats = 0;
10116  vms.starting = 1;
10117  while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
10118  /* Run main menu */
10119  switch (cmd) {
10120  case '1': /* First message */
10121  vms.curmsg = 0;
10122  /* Fall through */
10123  case '5': /* Play current message */
10124  ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg);
10125  cmd = vm_browse_messages(chan, &vms, vmu);
10126  break;
10127  case '2': /* Change folders */
10128  ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder");
10129  if (useadsi)
10130  adsi_folders(chan, 0, "Change to folder...");
10131 
10132  cmd = get_folder2(chan, "vm-changeto", 0);
10133  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
10134  if (cmd == '#') {
10135  cmd = 0;
10136  } else if (cmd > 0) {
10137  cmd = cmd - '0';
10138  res = close_mailbox(&vms, vmu);
10139  if (res == ERROR_LOCK_PATH)
10140  goto out;
10141  /* If folder is not urgent, set in_urgent to zero! */
10142  if (cmd != 11) in_urgent = 0;
10143  res = open_mailbox(&vms, vmu, cmd);
10144  if (res < 0)
10145  goto out;
10146  play_folder = cmd;
10147  cmd = 0;
10148  }
10149  if (useadsi)
10150  adsi_status2(chan, &vms);
10151 
10152  if (!cmd) {
10153  cmd = vm_play_folder_name(chan, vms.vmbox);
10154  }
10155 
10156  vms.starting = 1;
10157  vms.curmsg = 0;
10158  break;
10159  case '3': /* Advanced options */
10160  ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu");
10161  cmd = 0;
10162  vms.repeats = 0;
10163  while ((cmd > -1) && (cmd != 't') && (cmd != '#')) {
10164  switch (cmd) {
10165  case '1': /* Reply */
10166  if (vms.lastmsg > -1 && !vms.starting) {
10167  cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain);
10168  if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) {
10169  res = cmd;
10170  goto out;
10171  }
10172  } else {
10173  cmd = ast_play_and_wait(chan, "vm-sorry");
10174  }
10175  cmd = 't';
10176  break;
10177  case '2': /* Callback */
10178  if (!vms.starting)
10179  ast_verb(3, "Callback Requested\n");
10180  if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) {
10181  cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain);
10182  if (cmd == 9) {
10183  silentexit = 1;
10184  goto out;
10185  } else if (cmd == ERROR_LOCK_PATH) {
10186  res = cmd;
10187  goto out;
10188  }
10189  } else {
10190  cmd = ast_play_and_wait(chan, "vm-sorry");
10191  }
10192  cmd = 't';
10193  break;
10194  case '3': /* Envelope */
10195  if (vms.lastmsg > -1 && !vms.starting) {
10196  cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain);
10197  if (cmd == ERROR_LOCK_PATH) {
10198  res = cmd;
10199  goto out;
10200  }
10201  } else {
10202  cmd = ast_play_and_wait(chan, "vm-sorry");
10203  }
10204  cmd = 't';
10205  break;
10206  case '4': /* Dialout */
10207  if (!ast_strlen_zero(vmu->dialout)) {
10208  cmd = dialout(chan, vmu, NULL, vmu->dialout);
10209  if (cmd == 9) {
10210  silentexit = 1;
10211  goto out;
10212  }
10213  } else {
10214  cmd = ast_play_and_wait(chan, "vm-sorry");
10215  }
10216  cmd = 't';
10217  break;
10218 
10219  case '5': /* Leave VoiceMail */
10220  if (ast_test_flag(vmu, VM_SVMAIL)) {
10221  cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0);
10222  if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) {
10223  res = cmd;
10224  goto out;
10225  }
10226  } else {
10227  cmd = ast_play_and_wait(chan, "vm-sorry");
10228  }
10229  cmd = 't';
10230  break;
10231 
10232  case '*': /* Return to main menu */
10233  cmd = 't';
10234  break;
10235 
10236  default:
10237  cmd = 0;
10238  if (!vms.starting) {
10239  cmd = ast_play_and_wait(chan, "vm-toreply");
10240  }
10241  if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) {
10242  cmd = ast_play_and_wait(chan, "vm-tocallback");
10243  }
10244  if (!cmd && !vms.starting) {
10245  cmd = ast_play_and_wait(chan, "vm-tohearenv");
10246  }
10247  if (!ast_strlen_zero(vmu->dialout) && !cmd) {
10248  cmd = ast_play_and_wait(chan, "vm-tomakecall");
10249  }
10250  if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) {
10251  cmd = ast_play_and_wait(chan, "vm-leavemsg");
10252  }
10253  if (!cmd) {
10254  cmd = ast_play_and_wait(chan, "vm-starmain");
10255  }
10256  if (!cmd) {
10257  cmd = ast_waitfordigit(chan, 6000);
10258  }
10259  if (!cmd) {
10260  vms.repeats++;
10261  }
10262  if (vms.repeats > 3) {
10263  cmd = 't';
10264  }
10265  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
10266  }
10267  }
10268  if (cmd == 't') {
10269  cmd = 0;
10270  vms.repeats = 0;
10271  }
10272  break;
10273  case '4': /* Go to the previous message */
10274  ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1);
10275  if (vms.curmsg > 0) {
10276  vms.curmsg--;
10277  cmd = play_message(chan, vmu, &vms);
10278  } else {
10279  /* Check if we were listening to new
10280  messages. If so, go to Urgent messages
10281  instead of saying "no more messages"
10282  */
10283  if (in_urgent == 0 && vms.urgentmessages > 0) {
10284  /* Check for Urgent messages */
10285  in_urgent = 1;
10286  res = close_mailbox(&vms, vmu);
10287  if (res == ERROR_LOCK_PATH)
10288  goto out;
10289  res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */
10290  if (res < 0)
10291  goto out;
10292  ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1);
10293  vms.curmsg = vms.lastmsg;
10294  if (vms.lastmsg < 0) {
10295  cmd = ast_play_and_wait(chan, "vm-nomore");
10296  }
10297  } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) {
10298  vms.curmsg = vms.lastmsg;
10299  cmd = play_message(chan, vmu, &vms);
10300  } else {
10301  cmd = ast_play_and_wait(chan, "vm-nomore");
10302  }
10303  }
10304  break;
10305  case '6': /* Go to the next message */
10306  ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1);
10307  if (vms.curmsg < vms.lastmsg) {
10308  vms.curmsg++;
10309  cmd = play_message(chan, vmu, &vms);
10310  } else {
10311  if (in_urgent && vms.newmessages > 0) {
10312  /* Check if we were listening to urgent
10313  * messages. If so, go to regular new messages
10314  * instead of saying "no more messages"
10315  */
10316  in_urgent = 0;
10317  res = close_mailbox(&vms, vmu);
10318  if (res == ERROR_LOCK_PATH)
10319  goto out;
10320  res = open_mailbox(&vms, vmu, NEW_FOLDER);
10321  if (res < 0)
10322  goto out;
10323  ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1);
10324  vms.curmsg = -1;
10325  if (vms.lastmsg < 0) {
10326  cmd = ast_play_and_wait(chan, "vm-nomore");
10327  }
10328  } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) {
10329  vms.curmsg = 0;
10330  cmd = play_message(chan, vmu, &vms);
10331  } else {
10332  cmd = ast_play_and_wait(chan, "vm-nomore");
10333  }
10334  }
10335  break;
10336  case '7': /* Delete the current message */
10337  if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) {
10338  vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg];
10339  if (useadsi)
10340  adsi_delete(chan, &vms);
10341  if (vms.deleted[vms.curmsg]) {
10342  if (play_folder == 0) {
10343  if (in_urgent) {
10344  vms.urgentmessages--;
10345  } else {
10346  vms.newmessages--;
10347  }
10348  }
10349  else if (play_folder == 1)
10350  vms.oldmessages--;
10351  cmd = ast_play_and_wait(chan, "vm-deleted");
10352  } else {
10353  if (play_folder == 0) {
10354  if (in_urgent) {
10355  vms.urgentmessages++;
10356  } else {
10357  vms.newmessages++;
10358  }
10359  }
10360  else if (play_folder == 1)
10361  vms.oldmessages++;
10362  cmd = ast_play_and_wait(chan, "vm-undeleted");
10363  }
10364  if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) {
10365  if (vms.curmsg < vms.lastmsg) {
10366  vms.curmsg++;
10367  cmd = play_message(chan, vmu, &vms);
10368  } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) {
10369  vms.curmsg = 0;
10370  cmd = play_message(chan, vmu, &vms);
10371  } else {
10372  /* Check if we were listening to urgent
10373  messages. If so, go to regular new messages
10374  instead of saying "no more messages"
10375  */
10376  if (in_urgent == 1) {
10377  /* Check for new messages */
10378  in_urgent = 0;
10379  res = close_mailbox(&vms, vmu);
10380  if (res == ERROR_LOCK_PATH)
10381  goto out;
10382  res = open_mailbox(&vms, vmu, NEW_FOLDER);
10383  if (res < 0)
10384  goto out;
10385  ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1);
10386  vms.curmsg = -1;
10387  if (vms.lastmsg < 0) {
10388  cmd = ast_play_and_wait(chan, "vm-nomore");
10389  }
10390  } else {
10391  cmd = ast_play_and_wait(chan, "vm-nomore");
10392  }
10393  }
10394  }
10395  } else /* Delete not valid if we haven't selected a message */
10396  cmd = 0;
10397 #ifdef IMAP_STORAGE
10398  deleted = 1;
10399 #endif
10400  break;
10401 
10402  case '8': /* Forward the current message */
10403  if (vms.lastmsg > -1) {
10404  cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent);
10405  if (cmd == ERROR_LOCK_PATH) {
10406  res = cmd;
10407  goto out;
10408  }
10409  } else {
10410  /* Check if we were listening to urgent
10411  messages. If so, go to regular new messages
10412  instead of saying "no more messages"
10413  */
10414  if (in_urgent == 1 && vms.newmessages > 0) {
10415  /* Check for new messages */
10416  in_urgent = 0;
10417  res = close_mailbox(&vms, vmu);
10418  if (res == ERROR_LOCK_PATH)
10419  goto out;
10420  res = open_mailbox(&vms, vmu, NEW_FOLDER);
10421  if (res < 0)
10422  goto out;
10423  ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1);
10424  vms.curmsg = -1;
10425  if (vms.lastmsg < 0) {
10426  cmd = ast_play_and_wait(chan, "vm-nomore");
10427  }
10428  } else {
10429  cmd = ast_play_and_wait(chan, "vm-nomore");
10430  }
10431  }
10432  break;
10433  case '9': /* Save message to folder */
10434  ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg);
10435  if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) {
10436  /* No message selected */
10437  cmd = 0;
10438  break;
10439  }
10440  if (useadsi)
10441  adsi_folders(chan, 1, "Save to folder...");
10442  cmd = get_folder2(chan, "vm-savefolder", 1);
10443  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
10444  box = 0; /* Shut up compiler */
10445  if (cmd == '#') {
10446  cmd = 0;
10447  break;
10448  } else if (cmd > 0) {
10449  box = cmd = cmd - '0';
10450  cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd);
10451  if (cmd == ERROR_LOCK_PATH) {
10452  res = cmd;
10453  goto out;
10454 #ifndef IMAP_STORAGE
10455  } else if (!cmd) {
10456  vms.deleted[vms.curmsg] = 1;
10457 #endif
10458  } else {
10459  vms.deleted[vms.curmsg] = 0;
10460  vms.heard[vms.curmsg] = 0;
10461  }
10462  }
10463  make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg);
10464  if (useadsi)
10465  adsi_message(chan, &vms);
10466  snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box));
10467  if (!cmd) {
10468  cmd = ast_play_and_wait(chan, "vm-message");
10469  if (!cmd)
10470  cmd = say_and_wait(chan, vms.curmsg + 1, chan->language);
10471  if (!cmd)
10472  cmd = ast_play_and_wait(chan, "vm-savedto");
10473  if (!cmd)
10474  cmd = vm_play_folder_name(chan, vms.fn);
10475  } else {
10476  cmd = ast_play_and_wait(chan, "vm-mailboxfull");
10477  }
10479  if (vms.curmsg < vms.lastmsg) {
10480  vms.curmsg++;
10481  cmd = play_message(chan, vmu, &vms);
10482  } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) {
10483  vms.curmsg = 0;
10484  cmd = play_message(chan, vmu, &vms);
10485  } else {
10486  /* Check if we were listening to urgent
10487  messages. If so, go to regular new messages
10488  instead of saying "no more messages"
10489  */
10490  if (in_urgent == 1 && vms.newmessages > 0) {
10491  /* Check for new messages */
10492  in_urgent = 0;
10493  res = close_mailbox(&vms, vmu);
10494  if (res == ERROR_LOCK_PATH)
10495  goto out;
10496  res = open_mailbox(&vms, vmu, NEW_FOLDER);
10497  if (res < 0)
10498  goto out;
10499  ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1);
10500  vms.curmsg = -1;
10501  if (vms.lastmsg < 0) {
10502  cmd = ast_play_and_wait(chan, "vm-nomore");
10503  }
10504  } else {
10505  cmd = ast_play_and_wait(chan, "vm-nomore");
10506  }
10507  }
10508  }
10509  break;
10510  case '*': /* Help */
10511  if (!vms.starting) {
10512  cmd = ast_play_and_wait(chan, "vm-onefor");
10513  if (!strncasecmp(chan->language, "he", 2)) {
10514  cmd = ast_play_and_wait(chan, "vm-for");
10515  }
10516  if (!cmd)
10517  cmd = vm_play_folder_name(chan, vms.vmbox);
10518  if (!cmd)
10519  cmd = ast_play_and_wait(chan, "vm-opts");
10520  if (!cmd)
10521  cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
10522  } else
10523  cmd = 0;
10524  break;
10525  case '0': /* Mailbox options */
10526  cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain);
10527  if (useadsi)
10528  adsi_status(chan, &vms);
10529  break;
10530  default: /* Nothing */
10531  ast_test_suite_event_notify("PLAYBACK", "Message: instructions");
10532  cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent);
10533  break;
10534  }
10535  }
10536  if ((cmd == 't') || (cmd == '#')) {
10537  /* Timeout */
10538  res = 0;
10539  } else {
10540  /* Hangup */
10541  res = -1;
10542  }
10543 
10544 out:
10545  if (res > -1) {
10546  ast_stopstream(chan);
10547  adsi_goodbye(chan);
10548  if (valid && res != OPERATOR_EXIT) {
10549  if (silentexit)
10550  res = ast_play_and_wait(chan, "vm-dialout");
10551  else
10552  res = ast_play_and_wait(chan, "vm-goodbye");
10553  }
10554  if ((valid && res > 0) || res == OPERATOR_EXIT) {
10555  res = 0;
10556  }
10557  if (useadsi)
10559  }
10560  if (vmu)
10561  close_mailbox(&vms, vmu);
10562  if (valid) {
10563  int new = 0, old = 0, urgent = 0;
10564  snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context);
10565  ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL));
10566  /* Urgent flag not passwd to externnotify here */
10567  run_externnotify(vmu->context, vmu->mailbox, NULL);
10568  ast_app_inboxcount2(ext_context, &urgent, &new, &old);
10569  queue_mwi_event(ext_context, urgent, new, old);
10570  }
10571 #ifdef IMAP_STORAGE
10572  /* expunge message - use UID Expunge if supported on IMAP server*/
10573  ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup);
10574  if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) {
10575  ast_mutex_lock(&vms.lock);
10576 #ifdef HAVE_IMAP_TK2006
10577  if (LEVELUIDPLUS (vms.mailstream)) {
10578  mail_expunge_full(vms.mailstream, NIL, EX_UID);
10579  } else
10580 #endif
10581  mail_expunge(vms.mailstream);
10582  ast_mutex_unlock(&vms.lock);
10583  }
10584  /* before we delete the state, we should copy pertinent info
10585  * back to the persistent model */
10586  if (vmu) {
10587  vmstate_delete(&vms);
10588  }
10589 #endif
10590  if (vmu)
10591  free_user(vmu);
10592 
10593 #ifdef IMAP_STORAGE
10594  pthread_setspecific(ts_vmstate.key, NULL);
10595 #endif
10596  return res;
10597 }
static int vm_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
static struct ast_flags globalflags
static struct ast_vm_user * find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
Finds a voicemail user from the users file or the realtime engine.
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int vm_newuser(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
The advanced options within a message.
#define VM_FORCEGREET
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
unsigned int flags
Definition: utils.h:201
#define AST_LOG_WARNING
Definition: logger.h:149
static void adsi_delete(struct ast_channel *chan, struct vm_state *vms)
#define EVENT_FLAG_CALL
Definition: manager.h:72
static void queue_mwi_event(const char *box, int urgent, int new, int old)
static int get_folder_by_name(const char *name)
static int has_voicemail(const char *mailbox, const char *folder)
Determines if the given folder has messages.
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
#define ast_mutex_lock(a)
Definition: lock.h:155
static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
static int maxlogins
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_test_suite_assert(exp)
Definition: test.h:185
static void adsi_status(struct ast_channel *chan, struct vm_state *vms)
static int get_folder2(struct ast_channel *chan, char *fn, int start)
plays a prompt and waits for a keypress.
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
static void adsi_status2(struct ast_channel *chan, struct vm_state *vms)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define VM_SKIPAFTERCMD
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
static void run_externnotify(char *context, char *extension, const char *flag)
char context[AST_MAX_CONTEXT]
static struct ast_app_option vm_app_options[128]
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
int ast_app_inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Determine number of urgent/new/old messages in a mailbox.
Definition: app.c:455
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static void adsi_goodbye(struct ast_channel *chan)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
enum ast_channel_state _state
Definition: channel.h:839
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
#define VM_SVMAIL
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
#define VM_MESSAGEWRAP
static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent)
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
static const char * mbox(struct ast_vm_user *vmu, int id)
static void free_user(struct ast_vm_user *vmu)
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
Structure used to handle boolean flags.
Definition: utils.h:200
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static void adsi_begin(struct ast_channel *chan, int *useadsi)
char language[MAX_LANGUAGE]
static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, int box)
static void adsi_folders(struct ast_channel *chan, int start, char *label)
#define ERROR_LOCK_PATH
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char vmfmts[80]
char dialout[80]
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
#define OPERATOR_EXIT
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
static void adsi_message(struct ast_channel *chan, struct vm_state *vms)
char callback[80]
static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms, struct ast_vm_user *sender, char *fmt, int is_new_message, signed char record_gain, int urgent)
Sends a voicemail message to a mailbox recipient.
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_adsi_unload_session(struct ast_channel *chan)
Definition: adsi.c:87
static int close_mailbox(struct vm_state *vms, struct ast_vm_user *vmu)
static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
Top level method to invoke the language variant vm_browse_messages_XX function.
#define VM_FORCENAME
const ast_string_field language
Definition: channel.h:787
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
char password[80]
static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
#define ast_mutex_unlock(a)
Definition: lock.h:156
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static int vm_forwardoptions ( struct ast_channel chan,
struct ast_vm_user vmu,
char *  curdir,
int  curmsg,
char *  vm_fmts,
char *  context,
signed char  record_gain,
long *  duration,
struct vm_state vms,
char *  flag 
)
static

presents the option to prepend to an existing message when forwarding it.

Parameters
chan
vmu
curdir
curmsg
vm_fmts
context
record_gain
duration
vms
flag

Presents a prompt for 1 to prepend the current message, 2 to forward the message without prepending, or * to return to the main menu.

This is invoked from forward_message() when performing a forward operation (option 8 from main menu).

Returns
zero on success, -1 on error.

Definition at line 6891 of file app_voicemail_odbcstorage.c.

References ast_category_get(), ast_channel_setoption(), ast_config_destroy(), ast_config_load, ast_config_text_file_save(), ast_filecopy(), ast_filerename(), AST_OPTION_RXGAIN, ast_play_and_prepend(), ast_play_and_wait(), ast_stream_and_wait(), ast_test_suite_event_notify, ast_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, copy(), INTRO, make_file(), ast_vm_user::maxsecs, play_record_review(), and valid_config().

Referenced by forward_message().

6893 {
6894  int cmd = 0;
6895  int retries = 0, prepend_duration = 0, already_recorded = 0;
6896  char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX];
6897  char textfile[PATH_MAX];
6898  struct ast_config *msg_cfg;
6899  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
6900 #ifndef IMAP_STORAGE
6901  signed char zero_gain = 0;
6902 #endif
6903  const char *duration_str;
6904 
6905  /* Must always populate duration correctly */
6906  make_file(msgfile, sizeof(msgfile), curdir, curmsg);
6907  strcpy(textfile, msgfile);
6908  strcpy(backup, msgfile);
6909  strcpy(backup_textfile, msgfile);
6910  strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
6911  strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
6912  strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
6913 
6914  if ((msg_cfg = ast_config_load(textfile, config_flags)) && valid_config(msg_cfg) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) {
6915  *duration = atoi(duration_str);
6916  } else {
6917  *duration = 0;
6918  }
6919 
6920  while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
6921  if (cmd)
6922  retries = 0;
6923  switch (cmd) {
6924  case '1':
6925 
6926 #ifdef IMAP_STORAGE
6927  /* Record new intro file */
6928  make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg);
6929  strncat(vms->introfn, "intro", sizeof(vms->introfn));
6930  ast_play_and_wait(chan, INTRO);
6931  ast_play_and_wait(chan, "beep");
6932  cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag);
6933  if (cmd == -1) {
6934  break;
6935  }
6936  cmd = 't';
6937 #else
6938 
6939  /* prepend a message to the current message, update the metadata and return */
6940 
6941  make_file(msgfile, sizeof(msgfile), curdir, curmsg);
6942  strcpy(textfile, msgfile);
6943  strncat(textfile, ".txt", sizeof(textfile) - 1);
6944  *duration = 0;
6945 
6946  /* if we can't read the message metadata, stop now */
6947  if (!valid_config(msg_cfg)) {
6948  cmd = 0;
6949  break;
6950  }
6951 
6952  /* Back up the original file, so we can retry the prepend and restore it after forward. */
6953 #ifndef IMAP_STORAGE
6954  if (already_recorded) {
6955  ast_filecopy(backup, msgfile, NULL);
6956  copy(backup_textfile, textfile);
6957  }
6958  else {
6959  ast_filecopy(msgfile, backup, NULL);
6960  copy(textfile, backup_textfile);
6961  }
6962 #endif
6963  already_recorded = 1;
6964 
6965  if (record_gain)
6966  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
6967 
6968  cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence);
6969 
6970  if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */
6971  ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */
6973  ast_filerename(backup, msgfile, NULL);
6974  }
6975 
6976  if (record_gain)
6977  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
6978 
6979 
6980  if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
6981  *duration = atoi(duration_str);
6982 
6983  if (prepend_duration) {
6984  struct ast_category *msg_cat;
6985  /* need enough space for a maximum-length message duration */
6986  char duration_buf[12];
6987 
6988  *duration += prepend_duration;
6989  msg_cat = ast_category_get(msg_cfg, "message");
6990  snprintf(duration_buf, 11, "%ld", *duration);
6991  if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) {
6992  ast_config_text_file_save(textfile, msg_cfg, "app_voicemail");
6993  }
6994  }
6995 
6996 #endif
6997  break;
6998  case '2':
6999  /* NULL out introfile so we know there is no intro! */
7000 #ifdef IMAP_STORAGE
7001  *vms->introfn = '\0';
7002 #endif
7003  cmd = 't';
7004  break;
7005  case '*':
7006  cmd = '*';
7007  break;
7008  default:
7009  /* If time_out and return to menu, reset already_recorded */
7010  already_recorded = 0;
7011 
7012  cmd = ast_play_and_wait(chan, "vm-forwardoptions");
7013  /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
7014  if (!cmd) {
7015  cmd = ast_play_and_wait(chan, "vm-starmain");
7016  /* "press star to return to the main menu" */
7017  }
7018  if (!cmd) {
7019  cmd = ast_waitfordigit(chan, 6000);
7020  }
7021  if (!cmd) {
7022  retries++;
7023  }
7024  if (retries > 3) {
7025  cmd = '*'; /* Let's cancel this beast */
7026  }
7027  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
7028  }
7029  }
7030 
7031  if (valid_config(msg_cfg))
7032  ast_config_destroy(msg_cfg);
7033  if (prepend_duration)
7034  *duration = prepend_duration;
7035 
7036  if (already_recorded && cmd == -1) {
7037  /* restore original message if prepention cancelled */
7038  ast_filerename(backup, msgfile, NULL);
7039  rename(backup_textfile, textfile);
7040  }
7041 
7042  if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */
7043  cmd = 0;
7044  return cmd;
7045 }
int ast_filecopy(const char *oldname, const char *newname, const char *fmt)
Copies a file.
Definition: file.c:941
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define INTRO
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag)
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
Definition: config.c:1977
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
Definition: channel.c:7795
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name)
Retrieve a category if it exists.
Definition: config.c:709
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static int copy(char *infile, char *outfile)
Utility function to copy a file.
static char vm_pls_try_again[80]
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
Update variable value within a config.
Definition: config.c:942
static int make_file(char *dest, const int len, const char *dir, const int num)
Creates a file system path expression for a folder within the voicemail data folder and the appropria...
Structure used to handle boolean flags.
Definition: utils.h:200
static int silencethreshold
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int *sound_duration, int beep, int silencethreshold, int maxsilence_ms)
Record a file based on input frm a channel. Recording is performed in &#39;prepend&#39; mode which works a li...
Definition: app.c:1188
static int maxsilence
#define AST_OPTION_RXGAIN
Definition: frame.h:463
static char vm_prepend_timeout[80]
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
static int vm_instructions ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
int  skipadvanced,
int  in_urgent 
)
static

Definition at line 9245 of file app_voicemail_odbcstorage.c.

References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().

Referenced by vm_execmain().

9246 {
9247  if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */
9248  return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
9249  } else { /* Default to ENGLISH */
9250  return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
9251  }
9252 }
static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
const ast_string_field language
Definition: channel.h:787
static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
static int vm_instructions_en ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
int  skipadvanced,
int  in_urgent 
)
static

Definition at line 9133 of file app_voicemail_odbcstorage.c.

References ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::newmessages, vm_state::repeats, vm_state::starting, vm_state::urgentmessages, VM_MESSAGEWRAP, vm_play_folder_name(), and vm_state::vmbox.

Referenced by vm_instructions(), and vm_instructions_zh().

9134 {
9135  int res = 0;
9136  /* Play instructions and wait for new command */
9137  while (!res) {
9138  if (vms->starting) {
9139  if (vms->lastmsg > -1) {
9140  if (skipadvanced)
9141  res = ast_play_and_wait(chan, "vm-onefor-full");
9142  else
9143  res = ast_play_and_wait(chan, "vm-onefor");
9144  if (!res)
9145  res = vm_play_folder_name(chan, vms->vmbox);
9146  }
9147  if (!res) {
9148  if (skipadvanced)
9149  res = ast_play_and_wait(chan, "vm-opts-full");
9150  else
9151  res = ast_play_and_wait(chan, "vm-opts");
9152  }
9153  } else {
9154  /* Added for additional help */
9155  if (skipadvanced) {
9156  res = ast_play_and_wait(chan, "vm-onefor-full");
9157  if (!res)
9158  res = vm_play_folder_name(chan, vms->vmbox);
9159  res = ast_play_and_wait(chan, "vm-opts-full");
9160  }
9161  /* Logic:
9162  * If the current message is not the first OR
9163  * if we're listening to the first new message and there are
9164  * also urgent messages, then prompt for navigation to the
9165  * previous message
9166  */
9167  if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) {
9168  res = ast_play_and_wait(chan, "vm-prev");
9169  }
9170  if (!res && !skipadvanced)
9171  res = ast_play_and_wait(chan, "vm-advopts");
9172  if (!res)
9173  res = ast_play_and_wait(chan, "vm-repeat");
9174  /* Logic:
9175  * If we're not listening to the last message OR
9176  * we're listening to the last urgent message and there are
9177  * also new non-urgent messages, then prompt for navigation
9178  * to the next message
9179  */
9180  if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) ||
9181  (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) {
9182  res = ast_play_and_wait(chan, "vm-next");
9183  }
9184  if (!res) {
9185  int curmsg_deleted;
9186 #ifdef IMAP_STORAGE
9187  ast_mutex_lock(&vms->lock);
9188 #endif
9189  curmsg_deleted = vms->deleted[vms->curmsg];
9190 #ifdef IMAP_STORAGE
9191  ast_mutex_unlock(&vms->lock);
9192 #endif
9193  if (!curmsg_deleted) {
9194  res = ast_play_and_wait(chan, "vm-delete");
9195  } else {
9196  res = ast_play_and_wait(chan, "vm-undelete");
9197  }
9198  if (!res) {
9199  res = ast_play_and_wait(chan, "vm-toforward");
9200  }
9201  if (!res) {
9202  res = ast_play_and_wait(chan, "vm-savemessage");
9203  }
9204  }
9205  }
9206  if (!res) {
9207  res = ast_play_and_wait(chan, "vm-helpexit");
9208  }
9209  if (!res)
9210  res = ast_waitfordigit(chan, 6000);
9211  if (!res) {
9212  vms->repeats++;
9213  if (vms->repeats > 2) {
9214  res = 't';
9215  }
9216  }
9217  }
9218  return res;
9219 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_mutex_lock(a)
Definition: lock.h:155
int urgentmessages
char vmbox[PATH_MAX]
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
#define VM_MESSAGEWRAP
int * deleted
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int newmessages
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int vm_instructions_zh ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
int  skipadvanced,
int  in_urgent 
)
static

Definition at line 9221 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), vm_state::lastmsg, vm_state::starting, vm_instructions_en(), vm_play_folder_name(), and vm_state::vmbox.

Referenced by vm_instructions().

9222 {
9223  int res = 0;
9224  /* Play instructions and wait for new command */
9225  while (!res) {
9226  if (vms->lastmsg > -1) {
9227  res = ast_play_and_wait(chan, "vm-listen");
9228  if (!res)
9229  res = vm_play_folder_name(chan, vms->vmbox);
9230  if (!res)
9231  res = ast_play_and_wait(chan, "press");
9232  if (!res)
9233  res = ast_play_and_wait(chan, "digits/1");
9234  }
9235  if (!res)
9236  res = ast_play_and_wait(chan, "vm-opts");
9237  if (!res) {
9238  vms->starting = 0;
9239  return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
9240  }
9241  }
9242  return res;
9243 }
static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
char vmbox[PATH_MAX]
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
static int vm_intro ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
)
static

Definition at line 9071 of file app_voicemail_odbcstorage.c.

References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, LOG_WARNING, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_vi(), vm_intro_zh(), and VM_TEMPGREETWARN.

Referenced by vm_execmain().

9072 {
9073  char prefile[256];
9074 
9075  /* Notify the user that the temp greeting is set and give them the option to remove it */
9076  snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
9077  if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
9078  RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
9079  if (ast_fileexists(prefile, NULL, NULL) > 0) {
9080  ast_play_and_wait(chan, "vm-tempgreetactive");
9081  }
9082  DISPOSE(prefile, -1);
9083  }
9084 
9085  /* Play voicemail intro - syntax is different for different languages */
9086  if (0) {
9087  return 0;
9088  } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */
9089  return vm_intro_cs(chan, vms);
9090  } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */
9091  static int deprecation_warning = 0;
9092  if (deprecation_warning++ % 10 == 0) {
9093  ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n");
9094  }
9095  return vm_intro_cs(chan, vms);
9096  } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
9097  return vm_intro_de(chan, vms);
9098  } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */
9099  return vm_intro_es(chan, vms);
9100  } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */
9101  return vm_intro_fr(chan, vms);
9102  } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */
9103  return vm_intro_gr(chan, vms);
9104  } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */
9105  return vm_intro_he(chan, vms);
9106  } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
9107  return vm_intro_it(chan, vms);
9108  } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */
9109  return vm_intro_nl(chan, vms);
9110  } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */
9111  return vm_intro_no(chan, vms);
9112  } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */
9113  return vm_intro_pl(chan, vms);
9114  } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */
9115  return vm_intro_pt_BR(chan, vms);
9116  } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */
9117  return vm_intro_pt(chan, vms);
9118  } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */
9119  return vm_intro_multilang(chan, vms, "n");
9120  } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */
9121  return vm_intro_se(chan, vms);
9122  } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */
9123  return vm_intro_multilang(chan, vms, "n");
9124  } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */
9125  return vm_intro_vi(chan, vms);
9126  } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */
9127  return vm_intro_zh(chan, vms);
9128  } else { /* Default to ENGLISH */
9129  return vm_intro_en(chan, vms);
9130  }
9131 }
static int vm_intro_fr(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pt_BR(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_zh(struct ast_channel *chan, struct vm_state *vms)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
static int vm_intro_no(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_nl(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_it(struct ast_channel *chan, struct vm_state *vms)
#define RETRIEVE(a, b, c, d)
static int vm_intro_pt(struct ast_channel *chan, struct vm_state *vms)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_intro_de(struct ast_channel *chan, struct vm_state *vms)
char mailbox[AST_MAX_EXTENSION]
char username[80]
char context[AST_MAX_CONTEXT]
static int vm_intro_cs(struct ast_channel *chan, struct vm_state *vms)
#define VM_TEMPGREETWARN
static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define DISPOSE(a, b)
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static int vm_intro_multilang(struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
static int vm_intro_gr(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_se(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_vi(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_pl(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_he(struct ast_channel *chan, struct vm_state *vms)
const ast_string_field language
Definition: channel.h:787
static int vm_intro_cs ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8941 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8942 {
8943  int res;
8944  res = ast_play_and_wait(chan, "vm-youhave");
8945  if (!res) {
8946  if (vms->newmessages) {
8947  if (vms->newmessages == 1) {
8948  res = ast_play_and_wait(chan, "digits/jednu");
8949  } else {
8950  res = say_and_wait(chan, vms->newmessages, chan->language);
8951  }
8952  if (!res) {
8953  if ((vms->newmessages == 1))
8954  res = ast_play_and_wait(chan, "vm-novou");
8955  if ((vms->newmessages) > 1 && (vms->newmessages < 5))
8956  res = ast_play_and_wait(chan, "vm-nove");
8957  if (vms->newmessages > 4)
8958  res = ast_play_and_wait(chan, "vm-novych");
8959  }
8960  if (vms->oldmessages && !res)
8961  res = ast_play_and_wait(chan, "vm-and");
8962  else if (!res) {
8963  if ((vms->newmessages == 1))
8964  res = ast_play_and_wait(chan, "vm-zpravu");
8965  if ((vms->newmessages) > 1 && (vms->newmessages < 5))
8966  res = ast_play_and_wait(chan, "vm-zpravy");
8967  if (vms->newmessages > 4)
8968  res = ast_play_and_wait(chan, "vm-zprav");
8969  }
8970  }
8971  if (!res && vms->oldmessages) {
8972  res = say_and_wait(chan, vms->oldmessages, chan->language);
8973  if (!res) {
8974  if ((vms->oldmessages == 1))
8975  res = ast_play_and_wait(chan, "vm-starou");
8976  if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
8977  res = ast_play_and_wait(chan, "vm-stare");
8978  if (vms->oldmessages > 4)
8979  res = ast_play_and_wait(chan, "vm-starych");
8980  }
8981  if (!res) {
8982  if ((vms->oldmessages == 1))
8983  res = ast_play_and_wait(chan, "vm-zpravu");
8984  if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
8985  res = ast_play_and_wait(chan, "vm-zpravy");
8986  if (vms->oldmessages > 4)
8987  res = ast_play_and_wait(chan, "vm-zprav");
8988  }
8989  }
8990  if (!res) {
8991  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8992  res = ast_play_and_wait(chan, "vm-no");
8993  if (!res)
8994  res = ast_play_and_wait(chan, "vm-zpravy");
8995  }
8996  }
8997  }
8998  return res;
8999 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_de ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8637 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8638 {
8639  /* Introduce messages they have */
8640  int res;
8641  res = ast_play_and_wait(chan, "vm-youhave");
8642  if (!res) {
8643  if (vms->newmessages) {
8644  if ((vms->newmessages == 1))
8645  res = ast_play_and_wait(chan, "digits/1F");
8646  else
8647  res = say_and_wait(chan, vms->newmessages, chan->language);
8648  if (!res)
8649  res = ast_play_and_wait(chan, "vm-INBOX");
8650  if (vms->oldmessages && !res)
8651  res = ast_play_and_wait(chan, "vm-and");
8652  else if (!res) {
8653  if ((vms->newmessages == 1))
8654  res = ast_play_and_wait(chan, "vm-message");
8655  else
8656  res = ast_play_and_wait(chan, "vm-messages");
8657  }
8658 
8659  }
8660  if (!res && vms->oldmessages) {
8661  if (vms->oldmessages == 1)
8662  res = ast_play_and_wait(chan, "digits/1F");
8663  else
8664  res = say_and_wait(chan, vms->oldmessages, chan->language);
8665  if (!res)
8666  res = ast_play_and_wait(chan, "vm-Old");
8667  if (!res) {
8668  if (vms->oldmessages == 1)
8669  res = ast_play_and_wait(chan, "vm-message");
8670  else
8671  res = ast_play_and_wait(chan, "vm-messages");
8672  }
8673  }
8674  if (!res) {
8675  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8676  res = ast_play_and_wait(chan, "vm-no");
8677  if (!res)
8678  res = ast_play_and_wait(chan, "vm-messages");
8679  }
8680  }
8681  }
8682  return res;
8683 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_en ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8386 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8387 {
8388  int res;
8389 
8390  /* Introduce messages they have */
8391  res = ast_play_and_wait(chan, "vm-youhave");
8392  if (!res) {
8393  if (vms->urgentmessages) {
8394  res = say_and_wait(chan, vms->urgentmessages, chan->language);
8395  if (!res)
8396  res = ast_play_and_wait(chan, "vm-Urgent");
8397  if ((vms->oldmessages || vms->newmessages) && !res) {
8398  res = ast_play_and_wait(chan, "vm-and");
8399  } else if (!res) {
8400  if ((vms->urgentmessages == 1))
8401  res = ast_play_and_wait(chan, "vm-message");
8402  else
8403  res = ast_play_and_wait(chan, "vm-messages");
8404  }
8405  }
8406  if (vms->newmessages) {
8407  res = say_and_wait(chan, vms->newmessages, chan->language);
8408  if (!res)
8409  res = ast_play_and_wait(chan, "vm-INBOX");
8410  if (vms->oldmessages && !res)
8411  res = ast_play_and_wait(chan, "vm-and");
8412  else if (!res) {
8413  if ((vms->newmessages == 1))
8414  res = ast_play_and_wait(chan, "vm-message");
8415  else
8416  res = ast_play_and_wait(chan, "vm-messages");
8417  }
8418 
8419  }
8420  if (!res && vms->oldmessages) {
8421  res = say_and_wait(chan, vms->oldmessages, chan->language);
8422  if (!res)
8423  res = ast_play_and_wait(chan, "vm-Old");
8424  if (!res) {
8425  if (vms->oldmessages == 1)
8426  res = ast_play_and_wait(chan, "vm-message");
8427  else
8428  res = ast_play_and_wait(chan, "vm-messages");
8429  }
8430  }
8431  if (!res) {
8432  if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) {
8433  res = ast_play_and_wait(chan, "vm-no");
8434  if (!res)
8435  res = ast_play_and_wait(chan, "vm-messages");
8436  }
8437  }
8438  }
8439  return res;
8440 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_es ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8686 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8687 {
8688  /* Introduce messages they have */
8689  int res;
8690  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8691  res = ast_play_and_wait(chan, "vm-youhaveno");
8692  if (!res)
8693  res = ast_play_and_wait(chan, "vm-messages");
8694  } else {
8695  res = ast_play_and_wait(chan, "vm-youhave");
8696  }
8697  if (!res) {
8698  if (vms->newmessages) {
8699  if (!res) {
8700  if ((vms->newmessages == 1)) {
8701  res = ast_play_and_wait(chan, "digits/1");
8702  if (!res)
8703  res = ast_play_and_wait(chan, "vm-message");
8704  if (!res)
8705  res = ast_play_and_wait(chan, "vm-INBOXs");
8706  } else {
8707  res = say_and_wait(chan, vms->newmessages, chan->language);
8708  if (!res)
8709  res = ast_play_and_wait(chan, "vm-messages");
8710  if (!res)
8711  res = ast_play_and_wait(chan, "vm-INBOX");
8712  }
8713  }
8714  if (vms->oldmessages && !res)
8715  res = ast_play_and_wait(chan, "vm-and");
8716  }
8717  if (vms->oldmessages) {
8718  if (!res) {
8719  if (vms->oldmessages == 1) {
8720  res = ast_play_and_wait(chan, "digits/1");
8721  if (!res)
8722  res = ast_play_and_wait(chan, "vm-message");
8723  if (!res)
8724  res = ast_play_and_wait(chan, "vm-Olds");
8725  } else {
8726  res = say_and_wait(chan, vms->oldmessages, chan->language);
8727  if (!res)
8728  res = ast_play_and_wait(chan, "vm-messages");
8729  if (!res)
8730  res = ast_play_and_wait(chan, "vm-Old");
8731  }
8732  }
8733  }
8734  }
8735 return res;
8736 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_fr ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8784 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8785 {
8786  /* Introduce messages they have */
8787  int res;
8788  res = ast_play_and_wait(chan, "vm-youhave");
8789  if (!res) {
8790  if (vms->newmessages) {
8791  res = say_and_wait(chan, vms->newmessages, chan->language);
8792  if (!res)
8793  res = ast_play_and_wait(chan, "vm-INBOX");
8794  if (vms->oldmessages && !res)
8795  res = ast_play_and_wait(chan, "vm-and");
8796  else if (!res) {
8797  if ((vms->newmessages == 1))
8798  res = ast_play_and_wait(chan, "vm-message");
8799  else
8800  res = ast_play_and_wait(chan, "vm-messages");
8801  }
8802 
8803  }
8804  if (!res && vms->oldmessages) {
8805  res = say_and_wait(chan, vms->oldmessages, chan->language);
8806  if (!res)
8807  res = ast_play_and_wait(chan, "vm-Old");
8808  if (!res) {
8809  if (vms->oldmessages == 1)
8810  res = ast_play_and_wait(chan, "vm-message");
8811  else
8812  res = ast_play_and_wait(chan, "vm-messages");
8813  }
8814  }
8815  if (!res) {
8816  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8817  res = ast_play_and_wait(chan, "vm-no");
8818  if (!res)
8819  res = ast_play_and_wait(chan, "vm-messages");
8820  }
8821  }
8822  }
8823  return res;
8824 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_gr ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8185 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

8186 {
8187  int res = 0;
8188 
8189  if (vms->newmessages) {
8190  res = ast_play_and_wait(chan, "vm-youhave");
8191  if (!res)
8192  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
8193  if (!res) {
8194  if ((vms->newmessages == 1)) {
8195  res = ast_play_and_wait(chan, "vm-INBOX");
8196  if (!res)
8197  res = ast_play_and_wait(chan, "vm-message");
8198  } else {
8199  res = ast_play_and_wait(chan, "vm-INBOXs");
8200  if (!res)
8201  res = ast_play_and_wait(chan, "vm-messages");
8202  }
8203  }
8204  } else if (vms->oldmessages){
8205  res = ast_play_and_wait(chan, "vm-youhave");
8206  if (!res)
8207  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
8208  if ((vms->oldmessages == 1)){
8209  res = ast_play_and_wait(chan, "vm-Old");
8210  if (!res)
8211  res = ast_play_and_wait(chan, "vm-message");
8212  } else {
8213  res = ast_play_and_wait(chan, "vm-Olds");
8214  if (!res)
8215  res = ast_play_and_wait(chan, "vm-messages");
8216  }
8217  } else if (!vms->oldmessages && !vms->newmessages)
8218  res = ast_play_and_wait(chan, "vm-denExeteMynhmata");
8219  return res;
8220 }
int oldmessages
#define AST_DIGIT_ANY
Definition: file.h:47
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_he ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8319 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

8320 {
8321  int res = 0;
8322 
8323  /* Introduce messages they have */
8324  if (!res) {
8325  if ((vms->newmessages) || (vms->oldmessages)) {
8326  res = ast_play_and_wait(chan, "vm-youhave");
8327  }
8328  /*
8329  * The word "shtei" refers to the number 2 in hebrew when performing a count
8330  * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
8331  * an element, this is one of them.
8332  */
8333  if (vms->newmessages) {
8334  if (!res) {
8335  if (vms->newmessages == 1) {
8336  res = ast_play_and_wait(chan, "vm-INBOX1");
8337  } else {
8338  if (vms->newmessages == 2) {
8339  res = ast_play_and_wait(chan, "vm-shtei");
8340  } else {
8341  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
8342  }
8343  res = ast_play_and_wait(chan, "vm-INBOX");
8344  }
8345  }
8346  if (vms->oldmessages && !res) {
8347  res = ast_play_and_wait(chan, "vm-and");
8348  if (vms->oldmessages == 1) {
8349  res = ast_play_and_wait(chan, "vm-Old1");
8350  } else {
8351  if (vms->oldmessages == 2) {
8352  res = ast_play_and_wait(chan, "vm-shtei");
8353  } else {
8354  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8355  }
8356  res = ast_play_and_wait(chan, "vm-Old");
8357  }
8358  }
8359  }
8360  if (!res && vms->oldmessages && !vms->newmessages) {
8361  if (!res) {
8362  if (vms->oldmessages == 1) {
8363  res = ast_play_and_wait(chan, "vm-Old1");
8364  } else {
8365  if (vms->oldmessages == 2) {
8366  res = ast_play_and_wait(chan, "vm-shtei");
8367  } else {
8368  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8369  }
8370  res = ast_play_and_wait(chan, "vm-Old");
8371  }
8372  }
8373  }
8374  if (!res) {
8375  if (!vms->oldmessages && !vms->newmessages) {
8376  if (!res) {
8377  res = ast_play_and_wait(chan, "vm-nomessages");
8378  }
8379  }
8380  }
8381  }
8382  return res;
8383 }
int oldmessages
#define AST_DIGIT_ANY
Definition: file.h:47
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_it ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8443 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8444 {
8445  /* Introduce messages they have */
8446  int res;
8447  if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages)
8448  res = ast_play_and_wait(chan, "vm-no") ||
8449  ast_play_and_wait(chan, "vm-message");
8450  else
8451  res = ast_play_and_wait(chan, "vm-youhave");
8452  if (!res && vms->newmessages) {
8453  res = (vms->newmessages == 1) ?
8454  ast_play_and_wait(chan, "digits/un") ||
8455  ast_play_and_wait(chan, "vm-nuovo") ||
8456  ast_play_and_wait(chan, "vm-message") :
8457  /* 2 or more new messages */
8458  say_and_wait(chan, vms->newmessages, chan->language) ||
8459  ast_play_and_wait(chan, "vm-nuovi") ||
8460  ast_play_and_wait(chan, "vm-messages");
8461  if (!res && vms->oldmessages)
8462  res = ast_play_and_wait(chan, "vm-and");
8463  }
8464  if (!res && vms->oldmessages) {
8465  res = (vms->oldmessages == 1) ?
8466  ast_play_and_wait(chan, "digits/un") ||
8467  ast_play_and_wait(chan, "vm-vecchio") ||
8468  ast_play_and_wait(chan, "vm-message") :
8469  /* 2 or more old messages */
8470  say_and_wait(chan, vms->oldmessages, chan->language) ||
8471  ast_play_and_wait(chan, "vm-vecchi") ||
8472  ast_play_and_wait(chan, "vm-messages");
8473  }
8474  return res;
8475 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
static int vm_intro_multilang ( struct ast_channel chan,
struct vm_state vms,
const char  message_gender[] 
)
static

Definition at line 8279 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_counted_adjective(), ast_say_counted_noun(), ast_say_number(), ast_channel::language, vm_state::newmessages, and vm_state::oldmessages.

Referenced by vm_intro().

8280 {
8281  int res;
8282  int lastnum = 0;
8283 
8284  res = ast_play_and_wait(chan, "vm-youhave");
8285 
8286  if (!res && vms->newmessages) {
8287  lastnum = vms->newmessages;
8288 
8289  if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
8290  res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
8291  }
8292 
8293  if (!res && vms->oldmessages) {
8294  res = ast_play_and_wait(chan, "vm-and");
8295  }
8296  }
8297 
8298  if (!res && vms->oldmessages) {
8299  lastnum = vms->oldmessages;
8300 
8301  if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
8302  res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
8303  }
8304  }
8305 
8306  if (!res) {
8307  if (lastnum == 0) {
8308  res = ast_play_and_wait(chan, "vm-no");
8309  }
8310  if (!res) {
8311  res = ast_say_counted_noun(chan, lastnum, "vm-message");
8312  }
8313  }
8314 
8315  return res;
8316 }
int oldmessages
#define AST_DIGIT_ANY
Definition: file.h:47
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
int ast_say_counted_noun(struct ast_channel *chan, int num, const char *noun)
int ast_say_counted_adjective(struct ast_channel *chan, int num, const char *adjective, const char *gender)
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_nl ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8827 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8828 {
8829  /* Introduce messages they have */
8830  int res;
8831  res = ast_play_and_wait(chan, "vm-youhave");
8832  if (!res) {
8833  if (vms->newmessages) {
8834  res = say_and_wait(chan, vms->newmessages, chan->language);
8835  if (!res) {
8836  if (vms->newmessages == 1)
8837  res = ast_play_and_wait(chan, "vm-INBOXs");
8838  else
8839  res = ast_play_and_wait(chan, "vm-INBOX");
8840  }
8841  if (vms->oldmessages && !res)
8842  res = ast_play_and_wait(chan, "vm-and");
8843  else if (!res) {
8844  if ((vms->newmessages == 1))
8845  res = ast_play_and_wait(chan, "vm-message");
8846  else
8847  res = ast_play_and_wait(chan, "vm-messages");
8848  }
8849 
8850  }
8851  if (!res && vms->oldmessages) {
8852  res = say_and_wait(chan, vms->oldmessages, chan->language);
8853  if (!res) {
8854  if (vms->oldmessages == 1)
8855  res = ast_play_and_wait(chan, "vm-Olds");
8856  else
8857  res = ast_play_and_wait(chan, "vm-Old");
8858  }
8859  if (!res) {
8860  if (vms->oldmessages == 1)
8861  res = ast_play_and_wait(chan, "vm-message");
8862  else
8863  res = ast_play_and_wait(chan, "vm-messages");
8864  }
8865  }
8866  if (!res) {
8867  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8868  res = ast_play_and_wait(chan, "vm-no");
8869  if (!res)
8870  res = ast_play_and_wait(chan, "vm-messages");
8871  }
8872  }
8873  }
8874  return res;
8875 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_no ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8593 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8594 {
8595  /* Introduce messages they have */
8596  int res;
8597 
8598  res = ast_play_and_wait(chan, "vm-youhave");
8599  if (res)
8600  return res;
8601 
8602  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8603  res = ast_play_and_wait(chan, "vm-no");
8604  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8605  return res;
8606  }
8607 
8608  if (vms->newmessages) {
8609  if ((vms->newmessages == 1)) {
8610  res = ast_play_and_wait(chan, "digits/1");
8611  res = res ? res : ast_play_and_wait(chan, "vm-ny");
8612  res = res ? res : ast_play_and_wait(chan, "vm-message");
8613  } else {
8614  res = say_and_wait(chan, vms->newmessages, chan->language);
8615  res = res ? res : ast_play_and_wait(chan, "vm-nye");
8616  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8617  }
8618  if (!res && vms->oldmessages)
8619  res = ast_play_and_wait(chan, "vm-and");
8620  }
8621  if (!res && vms->oldmessages) {
8622  if (vms->oldmessages == 1) {
8623  res = ast_play_and_wait(chan, "digits/1");
8624  res = res ? res : ast_play_and_wait(chan, "vm-gamel");
8625  res = res ? res : ast_play_and_wait(chan, "vm-message");
8626  } else {
8627  res = say_and_wait(chan, vms->oldmessages, chan->language);
8628  res = res ? res : ast_play_and_wait(chan, "vm-gamle");
8629  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8630  }
8631  }
8632 
8633  return res;
8634 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_pl ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8478 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

8479 {
8480  /* Introduce messages they have */
8481  int res;
8482  div_t num;
8483 
8484  if (!vms->oldmessages && !vms->newmessages) {
8485  res = ast_play_and_wait(chan, "vm-no");
8486  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8487  return res;
8488  } else {
8489  res = ast_play_and_wait(chan, "vm-youhave");
8490  }
8491 
8492  if (vms->newmessages) {
8493  num = div(vms->newmessages, 10);
8494  if (vms->newmessages == 1) {
8495  res = ast_play_and_wait(chan, "digits/1-a");
8496  res = res ? res : ast_play_and_wait(chan, "vm-new-a");
8497  res = res ? res : ast_play_and_wait(chan, "vm-message");
8498  } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
8499  if (num.rem == 2) {
8500  if (!num.quot) {
8501  res = ast_play_and_wait(chan, "digits/2-ie");
8502  } else {
8503  res = say_and_wait(chan, vms->newmessages - 2 , chan->language);
8504  res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
8505  }
8506  } else {
8507  res = say_and_wait(chan, vms->newmessages, chan->language);
8508  }
8509  res = res ? res : ast_play_and_wait(chan, "vm-new-e");
8510  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8511  } else {
8512  res = say_and_wait(chan, vms->newmessages, chan->language);
8513  res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
8514  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8515  }
8516  if (!res && vms->oldmessages)
8517  res = ast_play_and_wait(chan, "vm-and");
8518  }
8519  if (!res && vms->oldmessages) {
8520  num = div(vms->oldmessages, 10);
8521  if (vms->oldmessages == 1) {
8522  res = ast_play_and_wait(chan, "digits/1-a");
8523  res = res ? res : ast_play_and_wait(chan, "vm-old-a");
8524  res = res ? res : ast_play_and_wait(chan, "vm-message");
8525  } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
8526  if (num.rem == 2) {
8527  if (!num.quot) {
8528  res = ast_play_and_wait(chan, "digits/2-ie");
8529  } else {
8530  res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
8531  res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
8532  }
8533  } else {
8534  res = say_and_wait(chan, vms->oldmessages, chan->language);
8535  }
8536  res = res ? res : ast_play_and_wait(chan, "vm-old-e");
8537  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8538  } else {
8539  res = say_and_wait(chan, vms->oldmessages, chan->language);
8540  res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
8541  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8542  }
8543  }
8544 
8545  return res;
8546 }
int oldmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_pt ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8878 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.

Referenced by vm_intro().

8879 {
8880  /* Introduce messages they have */
8881  int res;
8882  res = ast_play_and_wait(chan, "vm-youhave");
8883  if (!res) {
8884  if (vms->newmessages) {
8885  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
8886  if (!res) {
8887  if ((vms->newmessages == 1)) {
8888  res = ast_play_and_wait(chan, "vm-message");
8889  if (!res)
8890  res = ast_play_and_wait(chan, "vm-INBOXs");
8891  } else {
8892  res = ast_play_and_wait(chan, "vm-messages");
8893  if (!res)
8894  res = ast_play_and_wait(chan, "vm-INBOX");
8895  }
8896  }
8897  if (vms->oldmessages && !res)
8898  res = ast_play_and_wait(chan, "vm-and");
8899  }
8900  if (!res && vms->oldmessages) {
8901  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8902  if (!res) {
8903  if (vms->oldmessages == 1) {
8904  res = ast_play_and_wait(chan, "vm-message");
8905  if (!res)
8906  res = ast_play_and_wait(chan, "vm-Olds");
8907  } else {
8908  res = ast_play_and_wait(chan, "vm-messages");
8909  if (!res)
8910  res = ast_play_and_wait(chan, "vm-Old");
8911  }
8912  }
8913  }
8914  if (!res) {
8915  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8916  res = ast_play_and_wait(chan, "vm-no");
8917  if (!res)
8918  res = ast_play_and_wait(chan, "vm-messages");
8919  }
8920  }
8921  }
8922  return res;
8923 }
int oldmessages
#define AST_DIGIT_ANY
Definition: file.h:47
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_pt_BR ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8739 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and vm_state::urgentmessages.

Referenced by vm_intro().

8739  {
8740  /* Introduce messages they have */
8741  int res;
8742  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8743  res = ast_play_and_wait(chan, "vm-nomessages");
8744  return res;
8745  } else {
8746  res = ast_play_and_wait(chan, "vm-youhave");
8747  }
8748  if (vms->newmessages) {
8749  if (!res)
8750  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
8751  if ((vms->newmessages == 1)) {
8752  if (!res)
8753  res = ast_play_and_wait(chan, "vm-message");
8754  if (!res)
8755  res = ast_play_and_wait(chan, "vm-INBOXs");
8756  } else {
8757  if (!res)
8758  res = ast_play_and_wait(chan, "vm-messages");
8759  if (!res)
8760  res = ast_play_and_wait(chan, "vm-INBOX");
8761  }
8762  if (vms->oldmessages && !res)
8763  res = ast_play_and_wait(chan, "vm-and");
8764  }
8765  if (vms->oldmessages) {
8766  if (!res)
8767  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8768  if (vms->oldmessages == 1) {
8769  if (!res)
8770  res = ast_play_and_wait(chan, "vm-message");
8771  if (!res)
8772  res = ast_play_and_wait(chan, "vm-Olds");
8773  } else {
8774  if (!res)
8775  res = ast_play_and_wait(chan, "vm-messages");
8776  if (!res)
8777  res = ast_play_and_wait(chan, "vm-Old");
8778  }
8779  }
8780  return res;
8781 }
int oldmessages
#define AST_DIGIT_ANY
Definition: file.h:47
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8397
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_se ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8549 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, say_and_wait(), and vm_state::urgentmessages.

Referenced by vm_intro().

8550 {
8551  /* Introduce messages they have */
8552  int res;
8553 
8554  res = ast_play_and_wait(chan, "vm-youhave");
8555  if (res)
8556  return res;
8557 
8558  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8559  res = ast_play_and_wait(chan, "vm-no");
8560  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8561  return res;
8562  }
8563 
8564  if (vms->newmessages) {
8565  if ((vms->newmessages == 1)) {
8566  res = ast_play_and_wait(chan, "digits/ett");
8567  res = res ? res : ast_play_and_wait(chan, "vm-nytt");
8568  res = res ? res : ast_play_and_wait(chan, "vm-message");
8569  } else {
8570  res = say_and_wait(chan, vms->newmessages, chan->language);
8571  res = res ? res : ast_play_and_wait(chan, "vm-nya");
8572  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8573  }
8574  if (!res && vms->oldmessages)
8575  res = ast_play_and_wait(chan, "vm-and");
8576  }
8577  if (!res && vms->oldmessages) {
8578  if (vms->oldmessages == 1) {
8579  res = ast_play_and_wait(chan, "digits/ett");
8580  res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
8581  res = res ? res : ast_play_and_wait(chan, "vm-message");
8582  } else {
8583  res = say_and_wait(chan, vms->oldmessages, chan->language);
8584  res = res ? res : ast_play_and_wait(chan, "vm-gamla");
8585  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8586  }
8587  }
8588 
8589  return res;
8590 }
int oldmessages
int urgentmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_vi ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 9041 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

9042 {
9043  int res;
9044 
9045  /* Introduce messages they have */
9046  res = ast_play_and_wait(chan, "vm-youhave");
9047  if (!res) {
9048  if (vms->newmessages) {
9049  res = say_and_wait(chan, vms->newmessages, chan->language);
9050  if (!res)
9051  res = ast_play_and_wait(chan, "vm-INBOX");
9052  if (vms->oldmessages && !res)
9053  res = ast_play_and_wait(chan, "vm-and");
9054  }
9055  if (!res && vms->oldmessages) {
9056  res = say_and_wait(chan, vms->oldmessages, chan->language);
9057  if (!res)
9058  res = ast_play_and_wait(chan, "vm-Old");
9059  }
9060  if (!res) {
9061  if (!vms->oldmessages && !vms->newmessages) {
9062  res = ast_play_and_wait(chan, "vm-no");
9063  if (!res)
9064  res = ast_play_and_wait(chan, "vm-message");
9065  }
9066  }
9067  }
9068  return res;
9069 }
int oldmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_intro_zh ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 9002 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().

Referenced by vm_intro().

9003 {
9004  int res;
9005  /* Introduce messages they have */
9006  res = ast_play_and_wait(chan, "vm-you");
9007 
9008  if (!res && vms->newmessages) {
9009  res = ast_play_and_wait(chan, "vm-have");
9010  if (!res)
9011  res = say_and_wait(chan, vms->newmessages, chan->language);
9012  if (!res)
9013  res = ast_play_and_wait(chan, "vm-tong");
9014  if (!res)
9015  res = ast_play_and_wait(chan, "vm-INBOX");
9016  if (vms->oldmessages && !res)
9017  res = ast_play_and_wait(chan, "vm-and");
9018  else if (!res)
9019  res = ast_play_and_wait(chan, "vm-messages");
9020  }
9021  if (!res && vms->oldmessages) {
9022  res = ast_play_and_wait(chan, "vm-have");
9023  if (!res)
9024  res = say_and_wait(chan, vms->oldmessages, chan->language);
9025  if (!res)
9026  res = ast_play_and_wait(chan, "vm-tong");
9027  if (!res)
9028  res = ast_play_and_wait(chan, "vm-Old");
9029  if (!res)
9030  res = ast_play_and_wait(chan, "vm-messages");
9031  }
9032  if (!res && !vms->oldmessages && !vms->newmessages) {
9033  res = ast_play_and_wait(chan, "vm-haveno");
9034  if (!res)
9035  res = ast_play_and_wait(chan, "vm-messages");
9036  }
9037  return res;
9038 }
int oldmessages
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
int newmessages
const ast_string_field language
Definition: channel.h:787
static int vm_lock_path ( const char *  path)
static

Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason.

Definition at line 3285 of file app_voicemail_odbcstorage.c.

References ast_lock_path(), and AST_LOCK_TIMEOUT.

Referenced by close_mailbox(), copy_message(), count_messages(), leave_voicemail(), open_mailbox(), resequence_mailbox(), and save_to_folder().

3286 {
3287  switch (ast_lock_path(path)) {
3288  case AST_LOCK_TIMEOUT:
3289  return -1;
3290  default:
3291  return 0;
3292  }
3293 }
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Definition: app.c:1652
static FILE* vm_mkftemp ( char *  template)
static

Definition at line 1656 of file app_voicemail_odbcstorage.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

1657 {
1658  FILE *p = NULL;
1659  int pfd = mkstemp(template);
1660  chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
1661  if (pfd > -1) {
1662  p = fdopen(pfd, "w+");
1663  if (!p) {
1664  close(pfd);
1665  pfd = -1;
1666  }
1667  }
1668  return p;
1669 }
static int my_umask
#define VOICEMAIL_FILE_MODE
static int vm_newuser ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
)
static

Definition at line 9255 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, check_password(), ast_vm_user::context, play_record_review(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, and VM_FORCENAME.

Referenced by vm_execmain().

9256 {
9257  int cmd = 0;
9258  int duration = 0;
9259  int tries = 0;
9260  char newpassword[80] = "";
9261  char newpassword2[80] = "";
9262  char prefile[PATH_MAX] = "";
9263  unsigned char buf[256];
9264  int bytes = 0;
9265 
9266  ast_test_suite_event_notify("NEWUSER", "Message: entering new user state");
9267  if (ast_adsi_available(chan)) {
9268  bytes += adsi_logo(buf + bytes);
9269  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
9270  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
9271  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
9272  bytes += ast_adsi_voice_mode(buf + bytes, 0);
9273  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
9274  }
9275 
9276  /* If forcename is set, have the user record their name */
9277  if (ast_test_flag(vmu, VM_FORCENAME)) {
9278  snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
9279  if (ast_fileexists(prefile, NULL, NULL) < 1) {
9280  cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9281  if (cmd < 0 || cmd == 't' || cmd == '#')
9282  return cmd;
9283  }
9284  }
9285 
9286  /* If forcegreetings is set, have the user record their greetings */
9287  if (ast_test_flag(vmu, VM_FORCEGREET)) {
9288  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
9289  if (ast_fileexists(prefile, NULL, NULL) < 1) {
9290  cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9291  if (cmd < 0 || cmd == 't' || cmd == '#')
9292  return cmd;
9293  }
9294 
9295  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
9296  if (ast_fileexists(prefile, NULL, NULL) < 1) {
9297  cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9298  if (cmd < 0 || cmd == 't' || cmd == '#')
9299  return cmd;
9300  }
9301  }
9302 
9303  /*
9304  * Change the password last since new users will be able to skip over any steps this one comes before
9305  * by hanging up and calling back to voicemail main since the password is used to verify new user status.
9306  */
9307  for (;;) {
9308  newpassword[1] = '\0';
9309  newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword);
9310  if (cmd == '#')
9311  newpassword[0] = '\0';
9312  if (cmd < 0 || cmd == 't' || cmd == '#')
9313  return cmd;
9314  cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#");
9315  if (cmd < 0 || cmd == 't' || cmd == '#')
9316  return cmd;
9317  cmd = check_password(vmu, newpassword); /* perform password validation */
9318  if (cmd != 0) {
9319  ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword);
9321  } else {
9322  newpassword2[1] = '\0';
9323  newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword);
9324  if (cmd == '#')
9325  newpassword2[0] = '\0';
9326  if (cmd < 0 || cmd == 't' || cmd == '#')
9327  return cmd;
9328  cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#");
9329  if (cmd < 0 || cmd == 't' || cmd == '#')
9330  return cmd;
9331  if (!strcmp(newpassword, newpassword2))
9332  break;
9333  ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
9334  cmd = ast_play_and_wait(chan, vm_mismatch);
9335  }
9336  if (++tries == 3)
9337  return -1;
9338  if (cmd != 0) {
9339  cmd = ast_play_and_wait(chan, vm_pls_try_again);
9340  }
9341  }
9343  vm_change_password(vmu, newpassword);
9345  vm_change_password_shell(vmu, newpassword);
9346 
9347  ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword));
9348  cmd = ast_play_and_wait(chan, vm_passchanged);
9349 
9350  return cmd;
9351 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
static char vm_passchanged[80]
#define PWDCHANGE_EXTERNAL
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag)
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
static int check_password(struct ast_vm_user *vmu, char *password)
Check that password meets minimum required length.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define VM_FORCEGREET
static int adsi_logo(unsigned char *buf)
static char vm_reenterpassword[80]
#define ADSI_COMM_PAGE
Definition: adsi.h:107
#define PWDCHANGE_INTERNAL
#define AST_LOG_NOTICE
Definition: logger.h:138
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
The handler for the change password option.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char ext_pass_cmd[128]
char username[80]
char context[AST_MAX_CONTEXT]
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
static int pwdchange
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char vm_pls_try_again[80]
static char vm_mismatch[80]
static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static char vm_newpassword[80]
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
static char vm_invalid_password[80]
#define ADSI_JUST_CENT
Definition: adsi.h:114
#define VM_FORCENAME
static int maxgreet
static int vm_options ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
)
static

Definition at line 9353 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_debug, ast_fileexists(), ast_log(), AST_LOG_NOTICE, ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_waitfordigit(), check_password(), ast_vm_user::context, DISPOSE, ast_vm_user::mailbox, ast_vm_user::password, play_record_review(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), and vm_tempgreeting().

Referenced by vm_execmain().

9354 {
9355  int cmd = 0;
9356  int retries = 0;
9357  int duration = 0;
9358  char newpassword[80] = "";
9359  char newpassword2[80] = "";
9360  char prefile[PATH_MAX] = "";
9361  unsigned char buf[256];
9362  int bytes = 0;
9363 
9364  ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options");
9365  if (ast_adsi_available(chan)) {
9366  bytes += adsi_logo(buf + bytes);
9367  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
9368  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
9369  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
9370  bytes += ast_adsi_voice_mode(buf + bytes, 0);
9371  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
9372  }
9373  while ((cmd >= 0) && (cmd != 't')) {
9374  if (cmd)
9375  retries = 0;
9376  switch (cmd) {
9377  case '1': /* Record your unavailable message */
9378  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
9379  cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9380  break;
9381  case '2': /* Record your busy message */
9382  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
9383  cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9384  break;
9385  case '3': /* Record greeting */
9386  snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
9387  cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9388  break;
9389  case '4': /* manage the temporary greeting */
9390  cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
9391  break;
9392  case '5': /* change password */
9393  if (vmu->password[0] == '-') {
9394  cmd = ast_play_and_wait(chan, "vm-no");
9395  break;
9396  }
9397  newpassword[1] = '\0';
9398  newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword);
9399  if (cmd == '#')
9400  newpassword[0] = '\0';
9401  else {
9402  if (cmd < 0)
9403  break;
9404  if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) {
9405  break;
9406  }
9407  }
9408  cmd = check_password(vmu, newpassword); /* perform password validation */
9409  if (cmd != 0) {
9410  ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword);
9412  if (!cmd) {
9413  cmd = ast_play_and_wait(chan, vm_pls_try_again);
9414  }
9415  break;
9416  }
9417  newpassword2[1] = '\0';
9418  newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword);
9419  if (cmd == '#')
9420  newpassword2[0] = '\0';
9421  else {
9422  if (cmd < 0)
9423  break;
9424 
9425  if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) {
9426  break;
9427  }
9428  }
9429  if (strcmp(newpassword, newpassword2)) {
9430  ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
9431  cmd = ast_play_and_wait(chan, vm_mismatch);
9432  if (!cmd) {
9433  cmd = ast_play_and_wait(chan, vm_pls_try_again);
9434  }
9435  break;
9436  }
9437 
9438  if (pwdchange & PWDCHANGE_INTERNAL) {
9439  vm_change_password(vmu, newpassword);
9440  }
9442  vm_change_password_shell(vmu, newpassword);
9443  }
9444 
9445  ast_debug(1, "User %s set password to %s of length %d\n",
9446  vms->username, newpassword, (int) strlen(newpassword));
9447  cmd = ast_play_and_wait(chan, vm_passchanged);
9448  break;
9449  case '*':
9450  cmd = 't';
9451  break;
9452  default:
9453  cmd = 0;
9454  snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
9455  RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
9456  if (ast_fileexists(prefile, NULL, NULL)) {
9457  cmd = ast_play_and_wait(chan, "vm-tmpexists");
9458  }
9459  DISPOSE(prefile, -1);
9460  if (!cmd) {
9461  cmd = ast_play_and_wait(chan, "vm-options");
9462  }
9463  if (!cmd) {
9464  cmd = ast_waitfordigit(chan, 6000);
9465  }
9466  if (!cmd) {
9467  retries++;
9468  }
9469  if (retries > 3) {
9470  cmd = 't';
9471  }
9472  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
9473  }
9474  }
9475  if (cmd == 't')
9476  cmd = 0;
9477  return cmd;
9478 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
static char vm_passchanged[80]
#define PWDCHANGE_EXTERNAL
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag)
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
static int check_password(struct ast_vm_user *vmu, char *password)
Check that password meets minimum required length.
static int adsi_logo(unsigned char *buf)
static char vm_reenterpassword[80]
#define ADSI_COMM_PAGE
Definition: adsi.h:107
#define PWDCHANGE_INTERNAL
#define RETRIEVE(a, b, c, d)
#define AST_LOG_NOTICE
Definition: logger.h:138
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
The handler for the change password option.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char ext_pass_cmd[128]
char mailbox[AST_MAX_EXTENSION]
char username[80]
char context[AST_MAX_CONTEXT]
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
static int pwdchange
static char VM_SPOOL_DIR[PATH_MAX]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char vm_pls_try_again[80]
static char vm_mismatch[80]
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
#define DISPOSE(a, b)
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static char vm_newpassword[80]
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
static int vm_tempgreeting(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain)
The handler for &#39;record a temporary greeting&#39;.
static char vm_invalid_password[80]
#define ADSI_JUST_CENT
Definition: adsi.h:114
static int maxgreet
char password[80]
static int vm_play_folder_name ( struct ast_channel chan,
char *  mbox 
)
static

Definition at line 8148 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait(), ast_channel::language, vm_play_folder_name_gr(), vm_play_folder_name_pl(), and vm_play_folder_name_ua().

Referenced by get_folder(), vm_execmain(), vm_instructions_en(), and vm_instructions_zh().

8149 {
8150  int cmd;
8151 
8152  if ( !strncasecmp(chan->language, "it", 2) ||
8153  !strncasecmp(chan->language, "es", 2) ||
8154  !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */
8155  cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
8156  return cmd ? cmd : ast_play_and_wait(chan, box);
8157  } else if (!strncasecmp(chan->language, "gr", 2)) {
8158  return vm_play_folder_name_gr(chan, box);
8159  } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */
8160  return ast_play_and_wait(chan, box);
8161  } else if (!strncasecmp(chan->language, "pl", 2)) {
8162  return vm_play_folder_name_pl(chan, box);
8163  } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */
8164  return vm_play_folder_name_ua(chan, box);
8165  } else if (!strncasecmp(chan->language, "vi", 2)) {
8166  return ast_play_and_wait(chan, box);
8167  } else { /* Default English */
8168  cmd = ast_play_and_wait(chan, box);
8169  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
8170  }
8171 }
static int vm_play_folder_name_pl(struct ast_channel *chan, char *box)
static int vm_play_folder_name_ua(struct ast_channel *chan, char *box)
static int vm_play_folder_name_gr(struct ast_channel *chan, char *box)
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
const ast_string_field language
Definition: channel.h:787
static int vm_play_folder_name_gr ( struct ast_channel chan,
char *  box 
)
static

Definition at line 8101 of file app_voicemail_odbcstorage.c.

References ast_alloca, and ast_play_and_wait().

Referenced by vm_play_folder_name().

8102 {
8103  int cmd;
8104  char *buf;
8105 
8106  buf = ast_alloca(strlen(box) + 2);
8107  strcpy(buf, box);
8108  strcat(buf, "s");
8109 
8110  if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){
8111  cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
8112  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
8113  } else {
8114  cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
8115  return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
8116  }
8117 }
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_play_folder_name_pl ( struct ast_channel chan,
char *  box 
)
static

Definition at line 8119 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

8120 {
8121  int cmd;
8122 
8123  if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) {
8124  if (!strcasecmp(box, "vm-INBOX"))
8125  cmd = ast_play_and_wait(chan, "vm-new-e");
8126  else
8127  cmd = ast_play_and_wait(chan, "vm-old-e");
8128  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
8129  } else {
8130  cmd = ast_play_and_wait(chan, "vm-messages");
8131  return cmd ? cmd : ast_play_and_wait(chan, box);
8132  }
8133 }
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_play_folder_name_ua ( struct ast_channel chan,
char *  box 
)
static

Definition at line 8135 of file app_voicemail_odbcstorage.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

8136 {
8137  int cmd;
8138 
8139  if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){
8140  cmd = ast_play_and_wait(chan, "vm-messages");
8141  return cmd ? cmd : ast_play_and_wait(chan, box);
8142  } else {
8143  cmd = ast_play_and_wait(chan, box);
8144  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
8145  }
8146 }
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static int vm_tempgreeting ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms,
char *  fmtc,
signed char  record_gain 
)
static

The handler for 'record a temporary greeting'.

Parameters
chan
vmu
vms
fmtc
record_gainThis is option 4 from the mailbox options menu. This function manages the following promptings: 1: play / record / review the temporary greeting. : invokes play_record_review(). 2: remove (delete) the temporary greeting. *: return to the main menu.
Returns
zero on success, -1 on error.

Definition at line 9496 of file app_voicemail_odbcstorage.c.

References ADSI_COMM_PAGE, ADSI_JUST_CENT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), ast_fileexists(), ast_play_and_wait(), ast_test_suite_event_notify, ast_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.

Referenced by vm_options().

9497 {
9498  int cmd = 0;
9499  int retries = 0;
9500  int duration = 0;
9501  char prefile[PATH_MAX] = "";
9502  unsigned char buf[256];
9503  int bytes = 0;
9504 
9505  if (ast_adsi_available(chan)) {
9506  bytes += adsi_logo(buf + bytes);
9507  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
9508  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
9509  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
9510  bytes += ast_adsi_voice_mode(buf + bytes, 0);
9511  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
9512  }
9513 
9514  ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options");
9515  snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
9516  while ((cmd >= 0) && (cmd != 't')) {
9517  if (cmd)
9518  retries = 0;
9519  RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
9520  if (ast_fileexists(prefile, NULL, NULL) <= 0) {
9521  cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9522  if (cmd == -1) {
9523  break;
9524  }
9525  cmd = 't';
9526  } else {
9527  switch (cmd) {
9528  case '1':
9529  cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9530  break;
9531  case '2':
9532  DELETE(prefile, -1, prefile, vmu);
9533  ast_play_and_wait(chan, "vm-tempremoved");
9534  cmd = 't';
9535  break;
9536  case '*':
9537  cmd = 't';
9538  break;
9539  default:
9540  cmd = ast_play_and_wait(chan,
9541  ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
9542  "vm-tempgreeting2" : "vm-tempgreeting");
9543  if (!cmd) {
9544  cmd = ast_waitfordigit(chan, 6000);
9545  }
9546  if (!cmd) {
9547  retries++;
9548  }
9549  if (retries > 3) {
9550  cmd = 't';
9551  }
9552  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
9553  }
9554  }
9555  DISPOSE(prefile, -1);
9556  }
9557  if (cmd == 't')
9558  cmd = 0;
9559  return cmd;
9560 }
int ast_adsi_voice_mode(unsigned char *buf, int when)
Puts CPE in voice mode.
Definition: adsi.c:252
static int play_record_review(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag)
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define DELETE(a, b, c, d)
static int adsi_logo(unsigned char *buf)
#define ADSI_COMM_PAGE
Definition: adsi.h:107
#define RETRIEVE(a, b, c, d)
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
char mailbox[AST_MAX_EXTENSION]
char username[80]
char context[AST_MAX_CONTEXT]
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
static char VM_SPOOL_DIR[PATH_MAX]
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
#define DISPOSE(a, b)
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
#define ADSI_JUST_CENT
Definition: adsi.h:114
static int maxgreet
static int vm_users_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
)
static

Definition at line 11365 of file app_voicemail_odbcstorage.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, user, and vm_users_data_provider_get_helper().

11367 {
11368  struct ast_vm_user *user;
11369 
11370  AST_LIST_LOCK(&users);
11371  AST_LIST_TRAVERSE(&users, user, list) {
11372  vm_users_data_provider_get_helper(search, data_root, user);
11373  }
11375 
11376  return 0;
11377 }
static char user[512]
#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
list of users found in the config file
struct ast_vm_user::@65 list
static int vm_users_data_provider_get_helper(const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int vm_users_data_provider_get_helper ( const struct ast_data_search search,
struct ast_data data_root,
struct ast_vm_user user 
)
static

Definition at line 11318 of file app_voicemail_odbcstorage.c.

References ast_data_add_int(), ast_data_add_node(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::context, inboxcount2(), ast_vm_user::mailbox, vm_zone::name, and ast_vm_user::zonetag.

Referenced by vm_users_data_provider_get().

11320 {
11321  struct ast_data *data_user, *data_zone;
11322  struct ast_data *data_state;
11323  struct vm_zone *zone = NULL;
11324  int urgentmsg = 0, newmsg = 0, oldmsg = 0;
11325  char ext_context[256] = "";
11326 
11327  data_user = ast_data_add_node(data_root, "user");
11328  if (!data_user) {
11329  return -1;
11330  }
11331 
11332  ast_data_add_structure(ast_vm_user, data_user, user);
11333 
11334  AST_LIST_LOCK(&zones);
11335  AST_LIST_TRAVERSE(&zones, zone, list) {
11336  if (!strcmp(zone->name, user->zonetag)) {
11337  break;
11338  }
11339  }
11341 
11342  /* state */
11343  data_state = ast_data_add_node(data_user, "state");
11344  if (!data_state) {
11345  return -1;
11346  }
11347  snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context);
11348  inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg);
11349  ast_data_add_int(data_state, "urgentmsg", urgentmsg);
11350  ast_data_add_int(data_state, "newmsg", newmsg);
11351  ast_data_add_int(data_state, "oldmsg", oldmsg);
11352 
11353  if (zone) {
11354  data_zone = ast_data_add_node(data_user, "zone");
11355  ast_data_add_structure(vm_zone, data_zone, zone);
11356  }
11357 
11358  if (!ast_data_search_match(search, data_user)) {
11359  ast_data_remove_node(data_root, data_user);
11360  }
11361 
11362  return 0;
11363 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
The data tree to be returned by the callbacks and managed by functions local to this file...
Definition: data.c:85
char name[80]
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_data * ast_data_add_node(struct ast_data *root, const char *childname)
Add a container child.
Definition: data.c:2317
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
char zonetag[80]
#define ast_data_add_structure(structure_name, root, structure)
Definition: data.h:620
void ast_data_remove_node(struct ast_data *root, struct ast_data *child)
Remove a node that was added using ast_data_add_.
Definition: data.c:2486
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_data * ast_data_add_int(struct ast_data *root, const char *childname, int value)
Add an integer node type.
Definition: data.c:2322
int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data)
Check the current generated node to know if it matches the search condition.
Definition: data.c:1458
struct vm_zone::@66 list
static int vmauthenticate ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 11004 of file app_voicemail_odbcstorage.c.

References ast_copy_string(), ast_goto_if_exists(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, ast_channel::context, pbx_builtin_setvar_helper(), strsep(), user, and vm_authenticate().

Referenced by load_module().

11005 {
11006  char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = "";
11007  struct ast_vm_user vmus;
11008  char *options = NULL;
11009  int silent = 0, skipuser = 0;
11010  int res = -1;
11011 
11012  if (data) {
11013  s = ast_strdupa(data);
11014  user = strsep(&s, ",");
11015  options = strsep(&s, ",");
11016  if (user) {
11017  s = user;
11018  user = strsep(&s, "@");
11019  context = strsep(&s, "");
11020  if (!ast_strlen_zero(user))
11021  skipuser++;
11022  ast_copy_string(mailbox, user, sizeof(mailbox));
11023  }
11024  }
11025 
11026  if (options) {
11027  silent = (strchr(options, 's')) != NULL;
11028  }
11029 
11030  if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
11031  pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
11032  pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
11033  ast_play_and_wait(chan, "auth-thankyou");
11034  res = 0;
11035  } else if (mailbox[0] == '*') {
11036  /* user entered '*' */
11037  if (!ast_goto_if_exists(chan, chan->context, "a", 1)) {
11038  res = 0; /* prevent hangup */
11039  }
11040  }
11041 
11042  return res;
11043 }
static char user[512]
char * strsep(char **str, const char *delims)
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
int ast_play_and_wait(struct ast_channel *chan, const char *fn)
Play a stream and wait for a digit, returning the digit that was pressed.
Definition: app.c:822
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:11261
static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent)
structure to hold users read from users.conf
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int vmsayname_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 12544 of file app_voicemail_odbcstorage.c.

References ast_debug, AST_DIGIT_ANY, ast_log(), ast_say_character_str(), ast_strdupa, ast_stream_and_wait(), ast_strlen_zero(), context, ast_channel::language, LOG_WARNING, and sayname().

Referenced by load_module().

12545 {
12546  char *context;
12547  char *args_copy;
12548  int res;
12549 
12550  if (ast_strlen_zero(data)) {
12551  ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n");
12552  return -1;
12553  }
12554 
12555  args_copy = ast_strdupa(data);
12556  if ((context = strchr(args_copy, '@'))) {
12557  *context++ = '\0';
12558  } else {
12559  context = "default";
12560  }
12561 
12562  if ((res = sayname(chan, args_copy, context) < 0)) {
12563  ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context);
12564  res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
12565  if (!res) {
12566  res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language);
12567  }
12568  }
12569 
12570  return res;
12571 }
#define AST_DIGIT_ANY
Definition: file.h:47
#define LOG_WARNING
Definition: logger.h:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int sayname(struct ast_channel *chan, const char *mailbox, const char *context)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
Definition: channel.c:8421
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
static struct ast_tm* vmu_tm ( const struct ast_vm_user vmu,
struct ast_tm tm 
)
static

fill in *tm for current time according to the proper timezone, if any.

Returns
tm so it can be used as a function argument.

Definition at line 4442 of file app_voicemail_odbcstorage.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_strlen_zero(), ast_tvnow(), vm_zone::name, vm_zone::timezone, and ast_vm_user::zonetag.

Referenced by make_email_file(), and sendpage().

4443 {
4444  const struct vm_zone *z = NULL;
4445  struct timeval t = ast_tvnow();
4446 
4447  /* Does this user have a timezone specified? */
4448  if (!ast_strlen_zero(vmu->zonetag)) {
4449  /* Find the zone in the list */
4450  AST_LIST_LOCK(&zones);
4451  AST_LIST_TRAVERSE(&zones, z, list) {
4452  if (!strcmp(z->name, vmu->zonetag))
4453  break;
4454  }
4456  }
4457  ast_localtime(&t, tm, z ? z->timezone : NULL);
4458  return tm;
4459 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char name[80]
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char timezone[80]
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char zonetag[80]
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static int wait_file ( struct ast_channel chan,
struct vm_state vms,
char *  file 
)
static

Definition at line 7497 of file app_voicemail_odbcstorage.c.

References ast_control_streamfile(), and ast_test_suite_event_notify.

Referenced by advanced_options(), and play_message().

7498 {
7499  ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file);
7501 }
static char listen_control_restart_key[12]
static char listen_control_forward_key[12]
int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms, long *offsetms)
Stream a file with fast forward, pause, reverse, restart.
Definition: app.c:683
static char listen_control_pause_key[12]
static int skipms
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static char listen_control_stop_key[12]
static char listen_control_reverse_key[12]
static int wait_file2 ( struct ast_channel chan,
struct vm_state vms,
char *  file 
)
static

Definition at line 7489 of file app_voicemail_odbcstorage.c.

References AST_DIGIT_ANY, ast_log(), AST_LOG_WARNING, and ast_stream_and_wait().

Referenced by play_message(), play_message_callerid(), and play_message_duration().

7490 {
7491  int res;
7492  if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0)
7493  ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file);
7494  return res;
7495 }
#define AST_DIGIT_ANY
Definition: file.h:47
#define AST_LOG_WARNING
Definition: logger.h:149
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1370
static int write_password_to_file ( const char *  secretfn,
const char *  password 
)
static

Definition at line 12511 of file app_voicemail_odbcstorage.c.

References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.

Referenced by vm_change_password().

12511  {
12512  struct ast_config *conf;
12513  struct ast_category *cat;
12514  struct ast_variable *var;
12515  int res = -1;
12516 
12517  if (!(conf = ast_config_new())) {
12518  ast_log(LOG_ERROR, "Error creating new config structure\n");
12519  return res;
12520  }
12521  if (!(cat = ast_category_new("general", "", 1))) {
12522  ast_log(LOG_ERROR, "Error creating new category structure\n");
12523  ast_config_destroy(conf);
12524  return res;
12525  }
12526  if (!(var = ast_variable_new("password", password, ""))) {
12527  ast_log(LOG_ERROR, "Error creating new variable structure\n");
12528  ast_config_destroy(conf);
12529  ast_category_destroy(cat);
12530  return res;
12531  }
12532  ast_category_append(conf, cat);
12533  ast_variable_append(cat, var);
12534  if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) {
12535  res = 0;
12536  } else {
12537  ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn);
12538  }
12539 
12540  ast_config_destroy(conf);
12541  return res;
12542 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
Definition: config.c:1977
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
Definition: config.c:673
void ast_category_destroy(struct ast_category *cat)
Definition: config.c:762
#define LOG_ERROR
Definition: logger.h:155
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: config.c:888
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Definition: config.c:719
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", }
static

Definition at line 13624 of file app_voicemail_odbcstorage.c.

char* addesc = "Comedian Mail"
static

Definition at line 750 of file app_voicemail_odbcstorage.c.

unsigned char adsifdn[4] = "\x00\x00\x00\x0F"
static

Definition at line 877 of file app_voicemail_odbcstorage.c.

unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC"
static

Definition at line 878 of file app_voicemail_odbcstorage.c.

int adsiver = 1
static

Definition at line 879 of file app_voicemail_odbcstorage.c.

char* app = "VoiceMail"
static

Definition at line 753 of file app_voicemail_odbcstorage.c.

char* app2 = "VoiceMailMain"
static

Definition at line 756 of file app_voicemail_odbcstorage.c.

char* app3 = "MailboxExists"
static

Definition at line 758 of file app_voicemail_odbcstorage.c.

char* app4 = "VMAuthenticate"
static

Definition at line 759 of file app_voicemail_odbcstorage.c.

Definition at line 13624 of file app_voicemail_odbcstorage.c.

char callcontext[AST_MAX_CONTEXT] = ""
static

Definition at line 863 of file app_voicemail_odbcstorage.c.

char charset[32] = "ISO-8859-1"
static

Definition at line 875 of file app_voicemail_odbcstorage.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64]
static

Definition at line 866 of file app_voicemail_odbcstorage.c.

struct ast_cli_entry cli_voicemail[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_voicemail_show_users, "List defined voicemail boxes"),
AST_CLI_DEFINE(handle_voicemail_show_zones, "List zone message formats"),
AST_CLI_DEFINE(handle_voicemail_reload, "Reload voicemail configuration"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_voicemail_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Reload voicemail configuration from the CLI.
static char * handle_voicemail_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of voicemail users in the CLI.
static char * handle_voicemail_show_zones(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of voicemail zones in the CLI.

Definition at line 11243 of file app_voicemail_odbcstorage.c.

char dialcontext[AST_MAX_CONTEXT] = ""
static

Definition at line 862 of file app_voicemail_odbcstorage.c.

char* emailbody = NULL
static

Definition at line 869 of file app_voicemail_odbcstorage.c.

Referenced by make_email_file().

char emaildateformat[32] = "%A, %B %d, %Y at %r"
static

Definition at line 880 of file app_voicemail_odbcstorage.c.

char* emailsubject = NULL
static

Definition at line 870 of file app_voicemail_odbcstorage.c.

Referenced by make_email_file().

char exitcontext[AST_MAX_CONTEXT] = ""
static

Definition at line 864 of file app_voicemail_odbcstorage.c.

char ext_pass_check_cmd[128]
static

Definition at line 730 of file app_voicemail_odbcstorage.c.

char ext_pass_cmd[128]
static

Definition at line 729 of file app_voicemail_odbcstorage.c.

char externnotify[160]
static

Definition at line 773 of file app_voicemail_odbcstorage.c.

char fromstring[100]
static

Definition at line 873 of file app_voicemail_odbcstorage.c.

struct ast_flags globalflags = {0}
static

Definition at line 858 of file app_voicemail_odbcstorage.c.

struct ao2_container* inprocess_container

Definition at line 902 of file app_voicemail_odbcstorage.c.

char listen_control_forward_key[12]
static

Definition at line 831 of file app_voicemail_odbcstorage.c.

char listen_control_pause_key[12]
static

Definition at line 833 of file app_voicemail_odbcstorage.c.

char listen_control_restart_key[12]
static

Definition at line 834 of file app_voicemail_odbcstorage.c.

char listen_control_reverse_key[12]
static

Definition at line 832 of file app_voicemail_odbcstorage.c.

char listen_control_stop_key[12]
static

Definition at line 835 of file app_voicemail_odbcstorage.c.

char locale[20]
static

Definition at line 766 of file app_voicemail_odbcstorage.c.

struct ast_custom_function mailbox_exists_acf
static
Initial value:
= {
.name = "MAILBOX_EXISTS",
}
static int acf_mailbox_exists(struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len)

Definition at line 10999 of file app_voicemail_odbcstorage.c.

const char* const mailbox_folders[]
static

Definition at line 1692 of file app_voicemail_odbcstorage.c.

char mailcmd[160]
static

Definition at line 772 of file app_voicemail_odbcstorage.c.

int maxdeletedmsg
static

Definition at line 769 of file app_voicemail_odbcstorage.c.

Referenced by populate_defaults().

int maxgreet
static

Definition at line 779 of file app_voicemail_odbcstorage.c.

int maxlogins
static

Definition at line 781 of file app_voicemail_odbcstorage.c.

int maxmsg
static

Definition at line 768 of file app_voicemail_odbcstorage.c.

Referenced by populate_defaults().

int maxsilence
static

Definition at line 767 of file app_voicemail_odbcstorage.c.

int minpassword
static

Definition at line 782 of file app_voicemail_odbcstorage.c.

struct ast_event_sub* mwi_sub_sub
static

Subscription to ... MWI event subscriptions

Definition at line 800 of file app_voicemail_odbcstorage.c.

struct mwi_subs mwi_subs = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct ast_taskprocessor* mwi_subscription_tps
static

Definition at line 826 of file app_voicemail_odbcstorage.c.

struct ast_event_sub* mwi_unsub_sub
static

Subscription to ... MWI event un-subscriptions

Definition at line 802 of file app_voicemail_odbcstorage.c.

int my_umask
static

Definition at line 732 of file app_voicemail_odbcstorage.c.

char* pagerbody = NULL
static

Definition at line 871 of file app_voicemail_odbcstorage.c.

char pagerdateformat[32] = "%A, %B %d, %Y at %r"
static

Definition at line 881 of file app_voicemail_odbcstorage.c.

char pagerfromstring[100]
static

Definition at line 874 of file app_voicemail_odbcstorage.c.

char* pagersubject = NULL
static

Definition at line 872 of file app_voicemail_odbcstorage.c.

int passwordlocation
static

Definition at line 783 of file app_voicemail_odbcstorage.c.

Referenced by populate_defaults().

ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER
static

Definition at line 795 of file app_voicemail_odbcstorage.c.

unsigned int poll_freq
static

Polling frequency

Definition at line 790 of file app_voicemail_odbcstorage.c.

ast_mutex_t poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 794 of file app_voicemail_odbcstorage.c.

Referenced by mb_poll_thread(), and stop_poll_thread().

unsigned int poll_mailboxes
static

Poll mailboxes for changes since there is something external to app_voicemail that may change them.

Definition at line 787 of file app_voicemail_odbcstorage.c.

pthread_t poll_thread = AST_PTHREADT_NULL
static

Definition at line 796 of file app_voicemail_odbcstorage.c.

unsigned char poll_thread_run
static

Definition at line 797 of file app_voicemail_odbcstorage.c.

int pwdchange = PWDCHANGE_INTERNAL
static

Definition at line 736 of file app_voicemail_odbcstorage.c.

int saydurationminfo
static

Definition at line 860 of file app_voicemail_odbcstorage.c.

Referenced by populate_defaults().

char* sayname_app = "VMSayName"
static

Definition at line 761 of file app_voicemail_odbcstorage.c.

char serveremail[80]
static

Definition at line 771 of file app_voicemail_odbcstorage.c.

Referenced by forward_message(), and notify_new_message().

int silencethreshold = 128
static

Definition at line 770 of file app_voicemail_odbcstorage.c.

int skipms
static

Definition at line 780 of file app_voicemail_odbcstorage.c.

struct ast_smdi_interface* smdi_iface = NULL
static

Definition at line 774 of file app_voicemail_odbcstorage.c.

struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
char userscontext[AST_MAX_EXTENSION] = "default"
static

Definition at line 748 of file app_voicemail_odbcstorage.c.

struct ast_app_option vm_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 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY } }
static

Definition at line 513 of file app_voicemail_odbcstorage.c.

Referenced by vm_exec(), and vm_execmain().

struct ast_data_entry vm_data_providers[]
static
Initial value:
= {
}

Definition at line 11384 of file app_voicemail_odbcstorage.c.

char vm_invalid_password[80] = "vm-invalid-password"
static

Definition at line 843 of file app_voicemail_odbcstorage.c.

char vm_mismatch[80] = "vm-mismatch"
static

Definition at line 842 of file app_voicemail_odbcstorage.c.

char vm_newpassword[80] = "vm-newpassword"
static

Definition at line 839 of file app_voicemail_odbcstorage.c.

char vm_passchanged[80] = "vm-passchanged"
static

Definition at line 840 of file app_voicemail_odbcstorage.c.

char vm_password[80] = "vm-password"
static

Definition at line 838 of file app_voicemail_odbcstorage.c.

char vm_pls_try_again[80] = "vm-pls-try-again"
static

Definition at line 844 of file app_voicemail_odbcstorage.c.

char vm_prepend_timeout[80] = "vm-then-pound"
static

Definition at line 856 of file app_voicemail_odbcstorage.c.

char vm_reenterpassword[80] = "vm-reenterpassword"
static

Definition at line 841 of file app_voicemail_odbcstorage.c.

char VM_SPOOL_DIR[PATH_MAX]
static

Definition at line 727 of file app_voicemail_odbcstorage.c.

struct ast_data_handler vm_users_data_provider
static
Initial value:
= {
}
static int vm_users_data_provider_get(const struct ast_data_search *search, struct ast_data *data_root)
#define AST_DATA_HANDLER_VERSION
The Data API structures version.
Definition: data.h:204

Definition at line 11379 of file app_voicemail_odbcstorage.c.

char vmfmts[80]
static

Definition at line 775 of file app_voicemail_odbcstorage.c.

int vmmaxsecs
static

Definition at line 778 of file app_voicemail_odbcstorage.c.

Referenced by apply_option(), and populate_defaults().

int vmminsecs
static

Definition at line 777 of file app_voicemail_odbcstorage.c.

Referenced by apply_option(), and populate_defaults().

double volgain
static

Definition at line 776 of file app_voicemail_odbcstorage.c.

Referenced by populate_defaults().

struct zones zones = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
char zonetag[80]
static

Definition at line 765 of file app_voicemail_odbcstorage.c.