Wed Jan 8 2020 09:49:56

Asterisk developer's documentation


app_voicemail_imapstorage.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_imapstorage.c.

Macro Definition Documentation

#define ASTERISK_USERNAME   "asterisk"

Definition at line 438 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define BASELINELEN   72

Definition at line 461 of file app_voicemail_imapstorage.c.

Referenced by ochar().

#define BASEMAXINLINE   256

Definition at line 462 of file app_voicemail_imapstorage.c.

Referenced by base_encode(), and inbuf().

#define CHUNKSIZE   65536

Definition at line 435 of file app_voicemail_imapstorage.c.

#define COMMAND_TIMEOUT   5000

Definition at line 431 of file app_voicemail_imapstorage.c.

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

Definition at line 749 of file app_voicemail_imapstorage.c.

Referenced by copy_message(), and save_to_folder().

#define DATA_EXPORT_VM_USERS (   USER)

Definition at line 11304 of file app_voicemail_imapstorage.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 11331 of file app_voicemail_imapstorage.c.

#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY   "#"

Definition at line 443 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY   "0"

Definition at line 445 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_RESTART_KEY   "2"

Definition at line 446 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY   "*"

Definition at line 444 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define DEFAULT_LISTEN_CONTROL_STOP_KEY   "13456789"

Definition at line 447 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define DEFAULT_POLL_FREQ   30

By default, poll every 30 seconds

Definition at line 819 of file app_voicemail_imapstorage.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 469 of file app_voicemail_imapstorage.c.

#define MAX_NUM_CID_CONTEXTS   10

Definition at line 470 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config(), and play_message_callerid().

#define MAXMSG   100

Definition at line 456 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config(), and apply_option().

#define MAXMSGLIMIT   9999
#define MINPASSWORD   0

Default minimum mailbox password length

Definition at line 459 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define OPERATOR_EXIT   300

Definition at line 492 of file app_voicemail_imapstorage.c.

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

#define PWDCHANGE_EXTERNAL   (1 << 2)

Definition at line 762 of file app_voicemail_imapstorage.c.

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

#define PWDCHANGE_INTERNAL   (1 << 1)

Definition at line 761 of file app_voicemail_imapstorage.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 452 of file app_voicemail_imapstorage.c.

Referenced by actual_load_config().

#define SMDI_MWI_WAIT_TIMEOUT   1000 /* 1 second */

Definition at line 429 of file app_voicemail_imapstorage.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 771 of file app_voicemail_imapstorage.c.

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

Definition at line 448 of file app_voicemail_imapstorage.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 485 of file app_voicemail_imapstorage.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 483 of file app_voicemail_imapstorage.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 484 of file app_voicemail_imapstorage.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 482 of file app_voicemail_imapstorage.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 476 of file app_voicemail_imapstorage.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 480 of file app_voicemail_imapstorage.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 479 of file app_voicemail_imapstorage.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 490 of file app_voicemail_imapstorage.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 489 of file app_voicemail_imapstorage.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 488 of file app_voicemail_imapstorage.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 473 of file app_voicemail_imapstorage.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 481 of file app_voicemail_imapstorage.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 472 of file app_voicemail_imapstorage.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 474 of file app_voicemail_imapstorage.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 477 of file app_voicemail_imapstorage.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 486 of file app_voicemail_imapstorage.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 478 of file app_voicemail_imapstorage.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 475 of file app_voicemail_imapstorage.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 487 of file app_voicemail_imapstorage.c.

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

#define VMSTATE_MAX_MSG_ARRAY   256

Definition at line 685 of file app_voicemail_imapstorage.c.

#define VOICEMAIL_CONFIG   "voicemail.conf"

Definition at line 437 of file app_voicemail_imapstorage.c.

Referenced by load_config(), and vm_change_password().

#define VOICEMAIL_DIR_MODE   0777

Definition at line 433 of file app_voicemail_imapstorage.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 495 of file app_voicemail_imapstorage.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 516 of file app_voicemail_imapstorage.c.

516  {
517  OPT_ARG_RECORDGAIN = 0,
518  OPT_ARG_PLAYFOLDER = 1,
519  OPT_ARG_DTMFEXIT = 2,
520  /* This *must* be the last value in this enum! */
521  OPT_ARG_ARRAY_SIZE = 3,
522 };
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 504 of file app_voicemail_imapstorage.c.

504  {
505  OPT_SILENT = (1 << 0),
506  OPT_BUSY_GREETING = (1 << 1),
507  OPT_UNAVAIL_GREETING = (1 << 2),
508  OPT_RECORDGAIN = (1 << 3),
509  OPT_PREPEND_MAILBOX = (1 << 4),
510  OPT_AUTOPLAY = (1 << 6),
511  OPT_DTMFEXIT = (1 << 7),
512  OPT_MESSAGE_Urgent = (1 << 8),
513  OPT_MESSAGE_PRIORITY = (1 << 9)
514 };
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 524 of file app_voicemail_imapstorage.c.

Function Documentation

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

Definition at line 5430 of file app_voicemail_imapstorage.c.

References ast_strlen_zero().

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

5431 {
5432  DIR *dir;
5433  struct dirent *de;
5434  char fn[256];
5435  int ret = 0;
5436 
5437  /* If no mailbox, return immediately */
5438  if (ast_strlen_zero(mailbox))
5439  return 0;
5440 
5441  if (ast_strlen_zero(folder))
5442  folder = "INBOX";
5443  if (ast_strlen_zero(context))
5444  context = "default";
5445 
5446  snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
5447 
5448  if (!(dir = opendir(fn)))
5449  return 0;
5450 
5451  while ((de = readdir(dir))) {
5452  if (!strncasecmp(de->d_name, "msg", 3)) {
5453  if (shortcircuit) {
5454  ret = 1;
5455  break;
5456  } else if (!strncasecmp(de->d_name + 8, "txt", 3)) {
5457  ret++;
5458  }
5459  }
5460  }
5461 
5462  closedir(dir);
5463 
5464  return ret;
5465 }
static char VM_SPOOL_DIR[PATH_MAX]
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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 13651 of file app_voicemail_imapstorage.c.

static void __unreg_module ( void  )
static

Definition at line 13651 of file app_voicemail_imapstorage.c.

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

Definition at line 11007 of file app_voicemail_imapstorage.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().

11008 {
11009  struct ast_vm_user svm;
11011  AST_APP_ARG(mbox);
11013  );
11014 
11015  AST_NONSTANDARD_APP_ARGS(arg, args, '@');
11016 
11017  if (ast_strlen_zero(arg.mbox)) {
11018  ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n");
11019  return -1;
11020  }
11021 
11022  ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len);
11023  return 0;
11024 }
#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
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 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
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 const char * mbox(struct ast_vm_user *vmu, int id)
static int actual_load_config ( int  reload,
struct ast_config cfg,
struct ast_config ucfg 
)
static

Definition at line 11841 of file app_voicemail_imapstorage.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().

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

4845 {
4846  char tmpdir[256], newtmp[256];
4847  char fname[256];
4848  char tmpcmd[256];
4849  int tmpfd = -1;
4850  int soxstatus = 0;
4851 
4852  /* Eww. We want formats to tell us their own MIME type */
4853  char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-";
4854 
4855  if (vmu->volgain < -.001 || vmu->volgain > .001) {
4856  create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp");
4857  snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir);
4858  tmpfd = mkstemp(newtmp);
4859  chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask);
4860  ast_debug(3, "newtmp: %s\n", newtmp);
4861  if (tmpfd > -1) {
4862  snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format);
4863  if ((soxstatus = ast_safe_system(tmpcmd)) == 0) {
4864  attach = newtmp;
4865  ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox);
4866  } else {
4867  ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format,
4868  soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing");
4869  ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n");
4870  }
4871  }
4872  }
4873  fprintf(p, "--%s" ENDL, bound);
4874  if (msgnum > -1)
4875  fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename);
4876  else
4877  fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format);
4878  fprintf(p, "Content-Transfer-Encoding: base64" ENDL);
4879  fprintf(p, "Content-Description: Voicemail sound attachment." ENDL);
4880  if (msgnum > -1)
4881  fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename);
4882  else
4883  fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format);
4884  snprintf(fname, sizeof(fname), "%s.%s", attach, format);
4885  base_encode(fname, p);
4886  if (last)
4887  fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound);
4888  if (tmpfd > -1) {
4889  if (soxstatus == 0) {
4890  unlink(fname);
4891  }
4892  close(tmpfd);
4893  unlink(newtmp);
4894  }
4895  return 0;
4896 }
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
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int my_umask
struct sla_ringing_trunk * last
Definition: app_meetme.c:965
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#define VOICEMAIL_FILE_MODE
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 create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
static int base_encode(char *filename, FILE *so)
Performs a base 64 encode algorithm on the contents of a File.
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define ENDL
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static void adsi_begin ( struct ast_channel chan,
int *  useadsi 
)
static

Definition at line 6453 of file app_voicemail_imapstorage.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().

6454 {
6455  int x;
6456  if (!ast_adsi_available(chan))
6457  return;
6458  x = ast_adsi_load_session(chan, adsifdn, adsiver, 1);
6459  if (x < 0)
6460  return;
6461  if (!x) {
6462  if (adsi_load_vmail(chan, useadsi)) {
6463  ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n");
6464  return;
6465  }
6466  } else
6467  *useadsi = 1;
6468 }
#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
static int adsiver
static unsigned char adsifdn[4]
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 void adsi_delete ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 6648 of file app_voicemail_imapstorage.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().

6649 {
6650  int bytes = 0;
6651  unsigned char buf[256];
6652  unsigned char keys[8];
6653 
6654  int x;
6655 
6656  if (!ast_adsi_available(chan))
6657  return;
6658 
6659  /* New meaning for keys */
6660  for (x = 0; x < 5; x++)
6661  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
6662 
6663  keys[6] = 0x0;
6664  keys[7] = 0x0;
6665 
6666  if (!vms->curmsg) {
6667  /* No prev key, provide "Folder" instead */
6668  keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6669  }
6670  if (vms->curmsg >= vms->lastmsg) {
6671  /* If last message ... */
6672  if (vms->curmsg) {
6673  /* but not only message, provide "Folder" instead */
6674  keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6675  } else {
6676  /* Otherwise if only message, leave blank */
6677  keys[3] = 1;
6678  }
6679  }
6680 
6681  /* If deleted, show "undeleted" */
6682 #ifdef IMAP_STORAGE
6683  ast_mutex_lock(&vms->lock);
6684 #endif
6685  if (vms->deleted[vms->curmsg]) {
6686  keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
6687  }
6688 #ifdef IMAP_STORAGE
6689  ast_mutex_unlock(&vms->lock);
6690 #endif
6691 
6692  /* Except "Exit" */
6693  keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
6694  bytes += ast_adsi_set_keys(buf + bytes, keys);
6695  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6696 
6697  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6698 }
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 6518 of file app_voicemail_imapstorage.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().

6519 {
6520  unsigned char buf[256];
6521  int bytes = 0;
6522  unsigned char keys[8];
6523  int x, y;
6524 
6525  if (!ast_adsi_available(chan))
6526  return;
6527 
6528  for (x = 0; x < 5; x++) {
6529  y = ADSI_KEY_APPS + 12 + start + x;
6530  if (y > ADSI_KEY_APPS + 12 + 4)
6531  y = 0;
6532  keys[x] = ADSI_KEY_SKT | y;
6533  }
6534  keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17);
6535  keys[6] = 0;
6536  keys[7] = 0;
6537 
6538  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, "");
6539  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", "");
6540  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6541  bytes += ast_adsi_set_keys(buf + bytes, keys);
6542  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6543 
6544  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6545 }
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 6803 of file app_voicemail_imapstorage.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().

6804 {
6805  unsigned char buf[256];
6806  int bytes = 0;
6807 
6808  if (!ast_adsi_available(chan))
6809  return;
6810  bytes += adsi_logo(buf + bytes);
6811  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", "");
6812  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", "");
6813  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6814  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6815 
6816  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6817 }
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
#define ADSI_COMM_PAGE
Definition: adsi.h:107
static int adsi_logo(unsigned char *buf)
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 6324 of file app_voicemail_imapstorage.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().

6325 {
6326  unsigned char buf[256];
6327  int bytes = 0;
6328  int x;
6329  char num[5];
6330 
6331  *useadsi = 0;
6332  bytes += ast_adsi_data_mode(buf + bytes);
6333  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6334 
6335  bytes = 0;
6336  bytes += adsi_logo(buf);
6337  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
6338 #ifdef DISPLAY
6339  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", "");
6340 #endif
6341  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6342  bytes += ast_adsi_data_mode(buf + bytes);
6343  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6344 
6346  bytes = 0;
6347  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", "");
6348  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
6349  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6350  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6351  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6352  return 0;
6353  }
6354 
6355 #ifdef DISPLAY
6356  /* Add a dot */
6357  bytes = 0;
6358  bytes += ast_adsi_logo(buf);
6359  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", "");
6360  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", "");
6361  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6362  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6363 #endif
6364  bytes = 0;
6365  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1);
6366  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1);
6367  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1);
6368  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1);
6369  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1);
6370  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1);
6371  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6372 
6373 #ifdef DISPLAY
6374  /* Add another dot */
6375  bytes = 0;
6376  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", "");
6377  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6378 
6379  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6380  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6381 #endif
6382 
6383  bytes = 0;
6384  /* These buttons we load but don't use yet */
6385  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1);
6386  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1);
6387  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1);
6388  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1);
6389  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1);
6390  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1);
6391  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6392 
6393 #ifdef DISPLAY
6394  /* Add another dot */
6395  bytes = 0;
6396  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", "");
6397  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6398  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6399 #endif
6400 
6401  bytes = 0;
6402  for (x = 0; x < 5; x++) {
6403  snprintf(num, sizeof(num), "%d", x);
6404  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1);
6405  }
6406  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1);
6407  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6408 
6409 #ifdef DISPLAY
6410  /* Add another dot */
6411  bytes = 0;
6412  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", "");
6413  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6414  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6415 #endif
6416 
6417  if (ast_adsi_end_download(chan)) {
6418  bytes = 0;
6419  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", "");
6420  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", "");
6421  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6422  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6423  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6424  return 0;
6425  }
6426  bytes = 0;
6427  bytes += ast_adsi_download_disconnect(buf + bytes);
6428  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6429  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD);
6430 
6431  ast_debug(1, "Done downloading scripts...\n");
6432 
6433 #ifdef DISPLAY
6434  /* Add last dot */
6435  bytes = 0;
6436  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", "");
6437  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6438 #endif
6439  ast_debug(1, "Restarting session...\n");
6440 
6441  bytes = 0;
6442  /* Load the session now */
6443  if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) {
6444  *useadsi = 1;
6445  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", "");
6446  } else
6447  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", "");
6448 
6449  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6450  return 0;
6451 }
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 adsisec[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
static int adsiver
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ADSI_COMM_PAGE
Definition: adsi.h:107
static int adsi_logo(unsigned char *buf)
#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 unsigned char adsifdn[4]
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
static char * addesc
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
#define ADSI_JUST_CENT
Definition: adsi.h:114
#define ADSI_KEY_APPS
Definition: adsi.h:109
static const char * mbox(struct ast_vm_user *vmu, int id)
static void adsi_login ( struct ast_channel chan)
static

Definition at line 6470 of file app_voicemail_imapstorage.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().

6471 {
6472  unsigned char buf[256];
6473  int bytes = 0;
6474  unsigned char keys[8];
6475  int x;
6476  if (!ast_adsi_available(chan))
6477  return;
6478 
6479  for (x = 0; x < 8; x++)
6480  keys[x] = 0;
6481  /* Set one key for next */
6482  keys[3] = ADSI_KEY_APPS + 3;
6483 
6484  bytes += adsi_logo(buf + bytes);
6485  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", "");
6486  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", "");
6487  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6488  bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", "");
6489  bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT);
6490  bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1);
6491  bytes += ast_adsi_set_keys(buf + bytes, keys);
6492  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6493  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6494 }
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
static int adsi_logo(unsigned char *buf)
#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 6316 of file app_voicemail_imapstorage.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().

6317 {
6318  int bytes = 0;
6319  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", "");
6320  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", "");
6321  return bytes;
6322 }
#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 6547 of file app_voicemail_imapstorage.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().

6548 {
6549  int bytes = 0;
6550  unsigned char buf[256];
6551  char buf1[256], buf2[256];
6552  char fn2[PATH_MAX];
6553 
6554  char cid[256] = "";
6555  char *val;
6556  char *name, *num;
6557  char datetime[21] = "";
6558  FILE *f;
6559 
6560  unsigned char keys[8];
6561 
6562  int x;
6563 
6564  if (!ast_adsi_available(chan))
6565  return;
6566 
6567  /* Retrieve important info */
6568  snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn);
6569  f = fopen(fn2, "r");
6570  if (f) {
6571  while (!feof(f)) {
6572  if (!fgets((char *) buf, sizeof(buf), f)) {
6573  continue;
6574  }
6575  if (!feof(f)) {
6576  char *stringp = NULL;
6577  stringp = (char *) buf;
6578  strsep(&stringp, "=");
6579  val = strsep(&stringp, "=");
6580  if (!ast_strlen_zero(val)) {
6581  if (!strcmp((char *) buf, "callerid"))
6582  ast_copy_string(cid, val, sizeof(cid));
6583  if (!strcmp((char *) buf, "origdate"))
6584  ast_copy_string(datetime, val, sizeof(datetime));
6585  }
6586  }
6587  }
6588  fclose(f);
6589  }
6590  /* New meaning for keys */
6591  for (x = 0; x < 5; x++)
6592  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x);
6593  keys[6] = 0x0;
6594  keys[7] = 0x0;
6595 
6596  if (!vms->curmsg) {
6597  /* No prev key, provide "Folder" instead */
6598  keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6599  }
6600  if (vms->curmsg >= vms->lastmsg) {
6601  /* If last message ... */
6602  if (vms->curmsg) {
6603  /* but not only message, provide "Folder" instead */
6604  keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1);
6605  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6606 
6607  } else {
6608  /* Otherwise if only message, leave blank */
6609  keys[3] = 1;
6610  }
6611  }
6612 
6613  if (!ast_strlen_zero(cid)) {
6614  ast_callerid_parse(cid, &name, &num);
6615  if (!name)
6616  name = num;
6617  } else
6618  name = "Unknown Caller";
6619 
6620  /* If deleted, show "undeleted" */
6621 #ifdef IMAP_STORAGE
6622  ast_mutex_lock(&vms->lock);
6623 #endif
6624  if (vms->deleted[vms->curmsg]) {
6625  keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11);
6626  }
6627 #ifdef IMAP_STORAGE
6628  ast_mutex_unlock(&vms->lock);
6629 #endif
6630 
6631  /* Except "Exit" */
6632  keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5);
6633  snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox,
6634  strcasecmp(vms->curbox, "INBOX") ? " Messages" : "");
6635  snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1);
6636 
6637  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
6638  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
6639  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, "");
6640  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, "");
6641  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6642  bytes += ast_adsi_set_keys(buf + bytes, keys);
6643  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6644 
6645  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6646 }
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 6496 of file app_voicemail_imapstorage.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().

6497 {
6498  unsigned char buf[256];
6499  int bytes = 0;
6500  unsigned char keys[8];
6501  int x;
6502  if (!ast_adsi_available(chan))
6503  return;
6504 
6505  for (x = 0; x < 8; x++)
6506  keys[x] = 0;
6507  /* Set one key for next */
6508  keys[3] = ADSI_KEY_APPS + 3;
6509 
6510  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6511  bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", "");
6512  bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT);
6513  bytes += ast_adsi_set_keys(buf + bytes, keys);
6514  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6515  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6516 }
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 6700 of file app_voicemail_imapstorage.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().

6701 {
6702  unsigned char buf[256] = "";
6703  char buf1[256] = "", buf2[256] = "";
6704  int bytes = 0;
6705  unsigned char keys[8];
6706  int x;
6707 
6708  char *newm = (vms->newmessages == 1) ? "message" : "messages";
6709  char *oldm = (vms->oldmessages == 1) ? "message" : "messages";
6710  if (!ast_adsi_available(chan))
6711  return;
6712  if (vms->newmessages) {
6713  snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages);
6714  if (vms->oldmessages) {
6715  strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1);
6716  snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm);
6717  } else {
6718  snprintf(buf2, sizeof(buf2), "%s.", newm);
6719  }
6720  } else if (vms->oldmessages) {
6721  snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages);
6722  snprintf(buf2, sizeof(buf2), "%s.", oldm);
6723  } else {
6724  strcpy(buf1, "You have no messages.");
6725  buf2[0] = ' ';
6726  buf2[1] = '\0';
6727  }
6728  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
6729  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
6730  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6731 
6732  for (x = 0; x < 6; x++)
6733  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
6734  keys[6] = 0;
6735  keys[7] = 0;
6736 
6737  /* Don't let them listen if there are none */
6738  if (vms->lastmsg < 0)
6739  keys[0] = 1;
6740  bytes += ast_adsi_set_keys(buf + bytes, keys);
6741 
6742  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6743 
6744  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6745 }
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 6747 of file app_voicemail_imapstorage.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().

6748 {
6749  unsigned char buf[256] = "";
6750  char buf1[256] = "", buf2[256] = "";
6751  int bytes = 0;
6752  unsigned char keys[8];
6753  int x;
6754 
6755  char *mess = (vms->lastmsg == 0) ? "message" : "messages";
6756 
6757  if (!ast_adsi_available(chan))
6758  return;
6759 
6760  /* Original command keys */
6761  for (x = 0; x < 6; x++)
6762  keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x);
6763 
6764  keys[6] = 0;
6765  keys[7] = 0;
6766 
6767  if ((vms->lastmsg + 1) < 1)
6768  keys[0] = 0;
6769 
6770  snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox,
6771  strcasecmp(vms->curbox, "INBOX") ? " folder" : "");
6772 
6773  if (vms->lastmsg + 1)
6774  snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess);
6775  else
6776  strcpy(buf2, "no messages.");
6777  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, "");
6778  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, "");
6779  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", "");
6780  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
6781  bytes += ast_adsi_set_keys(buf + bytes, keys);
6782 
6783  bytes += ast_adsi_voice_mode(buf + bytes, 0);
6784 
6785  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
6786 
6787 }
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 13213 of file app_voicemail_imapstorage.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().

13214 {
13215  int res = 0;
13216  char filename[PATH_MAX];
13217  struct ast_config *msg_cfg = NULL;
13218  const char *origtime, *context;
13219  char *name, *num;
13220  int retries = 0;
13221  char *cid;
13222  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, };
13223 
13224  vms->starting = 0;
13225 
13226  make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
13227 
13228  /* Retrieve info from VM attribute file */
13229  snprintf(filename, sizeof(filename), "%s.txt", vms->fn);
13230  RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
13231  msg_cfg = ast_config_load(filename, config_flags);
13232  DISPOSE(vms->curdir, vms->curmsg);
13233  if (!valid_config(msg_cfg)) {
13234  ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
13235  return 0;
13236  }
13237 
13238  if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
13239  ast_config_destroy(msg_cfg);
13240  return 0;
13241  }
13242 
13243  cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
13244 
13245  context = ast_variable_retrieve(msg_cfg, "message", "context");
13246  if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
13247  context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
13248  switch (option) {
13249  case 3: /* Play message envelope */
13250  if (!res)
13251  res = play_message_datetime(chan, vmu, origtime, filename);
13252  if (!res)
13253  res = play_message_callerid(chan, vms, cid, context, 0);
13254 
13255  res = 't';
13256  break;
13257 
13258  case 2: /* Call back */
13259 
13260  if (ast_strlen_zero(cid))
13261  break;
13262 
13263  ast_callerid_parse(cid, &name, &num);
13264  while ((res > -1) && (res != 't')) {
13265  switch (res) {
13266  case '1':
13267  if (num) {
13268  /* Dial the CID number */
13269  res = dialout(chan, vmu, num, vmu->callback);
13270  if (res) {
13271  ast_config_destroy(msg_cfg);
13272  return 9;
13273  }
13274  } else {
13275  res = '2';
13276  }
13277  break;
13278 
13279  case '2':
13280  /* Want to enter a different number, can only do this if there's a dialout context for this user */
13281  if (!ast_strlen_zero(vmu->dialout)) {
13282  res = dialout(chan, vmu, NULL, vmu->dialout);
13283  if (res) {
13284  ast_config_destroy(msg_cfg);
13285  return 9;
13286  }
13287  } else {
13288  ast_verb(3, "Caller can not specify callback number - no dialout context available\n");
13289  res = ast_play_and_wait(chan, "vm-sorry");
13290  }
13291  ast_config_destroy(msg_cfg);
13292  return res;
13293  case '*':
13294  res = 't';
13295  break;
13296  case '3':
13297  case '4':
13298  case '5':
13299  case '6':
13300  case '7':
13301  case '8':
13302  case '9':
13303  case '0':
13304 
13305  res = ast_play_and_wait(chan, "vm-sorry");
13306  retries++;
13307  break;
13308  default:
13309  if (num) {
13310  ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num);
13311  res = ast_play_and_wait(chan, "vm-num-i-have");
13312  if (!res)
13313  res = play_message_callerid(chan, vms, num, vmu->context, 1);
13314  if (!res)
13315  res = ast_play_and_wait(chan, "vm-tocallnum");
13316  /* Only prompt for a caller-specified number if there is a dialout context specified */
13317  if (!ast_strlen_zero(vmu->dialout)) {
13318  if (!res)
13319  res = ast_play_and_wait(chan, "vm-calldiffnum");
13320  }
13321  } else {
13322  res = ast_play_and_wait(chan, "vm-nonumber");
13323  if (!ast_strlen_zero(vmu->dialout)) {
13324  if (!res)
13325  res = ast_play_and_wait(chan, "vm-toenternumber");
13326  }
13327  }
13328  if (!res) {
13329  res = ast_play_and_wait(chan, "vm-star-cancel");
13330  }
13331  if (!res) {
13332  res = ast_waitfordigit(chan, 6000);
13333  }
13334  if (!res) {
13335  retries++;
13336  if (retries > 3) {
13337  res = 't';
13338  }
13339  }
13340  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
13341  break;
13342 
13343  }
13344  if (res == 't')
13345  res = 0;
13346  else if (res == '*')
13347  res = -1;
13348  }
13349  break;
13350 
13351  case 1: /* Reply */
13352  /* Send reply directly to sender */
13353  if (ast_strlen_zero(cid))
13354  break;
13355 
13356  ast_callerid_parse(cid, &name, &num);
13357  if (!num) {
13358  ast_verb(3, "No CID number available, no reply sent\n");
13359  if (!res)
13360  res = ast_play_and_wait(chan, "vm-nonumber");
13361  ast_config_destroy(msg_cfg);
13362  return res;
13363  } else {
13364  struct ast_vm_user vmu2;
13365  if (find_user(&vmu2, vmu->context, num)) {
13366  struct leave_vm_options leave_options;
13367  char mailbox[AST_MAX_EXTENSION * 2 + 2];
13368  snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context);
13369 
13370  ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context);
13371 
13372  memset(&leave_options, 0, sizeof(leave_options));
13373  leave_options.record_gain = record_gain;
13374  res = leave_voicemail(chan, mailbox, &leave_options);
13375  if (!res)
13376  res = 't';
13377  ast_config_destroy(msg_cfg);
13378  return res;
13379  } else {
13380  /* Sender has no mailbox, can't reply */
13381  ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context);
13382  ast_play_and_wait(chan, "vm-nobox");
13383  res = 't';
13384  ast_config_destroy(msg_cfg);
13385  return res;
13386  }
13387  }
13388  res = 0;
13389 
13390  break;
13391  }
13392 
13393  ast_config_destroy(msg_cfg);
13394 
13395 #ifndef IMAP_STORAGE
13396  if (!res) {
13397  make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg);
13398  vms->heard[msg] = 1;
13399  res = wait_file(chan, vms, vms->fn);
13400  }
13401 #endif
13402  return res;
13403 }
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 play_message_datetime(struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
#define RETRIEVE(a, b, c, d)
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...
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char fn[PATH_MAX]
#define AST_LOG_WARNING
Definition: logger.h:149
char curdir[PATH_MAX]
static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file)
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
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 play_message_callerid(struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
#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
char mailbox[AST_MAX_EXTENSION]
#define AST_MAX_EXTENSION
Definition: channel.h:135
char context[AST_MAX_CONTEXT]
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.
int * heard
#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 dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context)
static const char name[]
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
char dialout[80]
char callback[80]
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
#define DISPOSE(a, b)
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 10734 of file app_voicemail_imapstorage.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().

10735 {
10736  /* Assumes lock is already held */
10737  char *tmp;
10738  char *stringp;
10739  char *s;
10740  struct ast_vm_user *vmu;
10741  char *mailbox_full;
10742  int new = 0, old = 0, urgent = 0;
10743  char secretfn[PATH_MAX] = "";
10744 
10745  tmp = ast_strdupa(data);
10746 
10747  if (!(vmu = find_or_create(context, box)))
10748  return -1;
10749 
10750  populate_defaults(vmu);
10751 
10752  stringp = tmp;
10753  if ((s = strsep(&stringp, ","))) {
10754  if (!ast_strlen_zero(s) && s[0] == '*') {
10755  ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password"
10756  "\n\tmust be reset in voicemail.conf.\n", box);
10757  }
10758  /* assign password regardless of validity to prevent NULL password from being assigned */
10759  ast_copy_string(vmu->password, s, sizeof(vmu->password));
10760  }
10761  if (stringp && (s = strsep(&stringp, ","))) {
10762  ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
10763  }
10764  if (stringp && (s = strsep(&stringp, ","))) {
10765  ast_copy_string(vmu->email, s, sizeof(vmu->email));
10766  }
10767  if (stringp && (s = strsep(&stringp, ","))) {
10768  ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
10769  }
10770  if (stringp && (s = strsep(&stringp, ","))) {
10771  apply_options(vmu, s);
10772  }
10773 
10774  switch (vmu->passwordlocation) {
10775  case OPT_PWLOC_SPOOLDIR:
10776  snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
10777  read_password_from_file(secretfn, vmu->password, sizeof(vmu->password));
10778  }
10779 
10780  mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1);
10781  strcpy(mailbox_full, box);
10782  strcat(mailbox_full, "@");
10783  strcat(mailbox_full, context);
10784 
10785  inboxcount2(mailbox_full, &urgent, &new, &old);
10786  queue_mwi_event(mailbox_full, urgent, new, old);
10787 
10788  return 0;
10789 }
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
char fullname[80]
char * strsep(char **str, const char *delims)
static void queue_mwi_event(const char *box, int urgent, int new, int old)
#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 char VM_SPOOL_DIR[PATH_MAX]
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
int passwordlocation
char context[AST_MAX_CONTEXT]
static void apply_options(struct ast_vm_user *vmu, const char *options)
Destructively Parse options and apply.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
char pager[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
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 void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
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 1064 of file app_voicemail_imapstorage.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().

1065 {
1066  int x;
1067  if (!strcasecmp(var, "attach")) {
1069  } else if (!strcasecmp(var, "attachfmt")) {
1070  ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt));
1071  } else if (!strcasecmp(var, "serveremail")) {
1072  ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail));
1073  } else if (!strcasecmp(var, "emailbody")) {
1075  } else if (!strcasecmp(var, "emailsubject")) {
1077  } else if (!strcasecmp(var, "language")) {
1078  ast_copy_string(vmu->language, value, sizeof(vmu->language));
1079  } else if (!strcasecmp(var, "tz")) {
1080  ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag));
1081  } else if (!strcasecmp(var, "locale")) {
1082  ast_copy_string(vmu->locale, value, sizeof(vmu->locale));
1083 #ifdef IMAP_STORAGE
1084  } else if (!strcasecmp(var, "imapuser")) {
1085  ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser));
1086  vmu->imapversion = imapversion;
1087  } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) {
1088  ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword));
1089  vmu->imapversion = imapversion;
1090  } else if (!strcasecmp(var, "imapfolder")) {
1091  ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder));
1092  } else if (!strcasecmp(var, "imapvmshareid")) {
1093  ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid));
1094  vmu->imapversion = imapversion;
1095 #endif
1096  } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) {
1098  } else if (!strcasecmp(var, "saycid")){
1100  } else if (!strcasecmp(var, "sendvoicemail")){
1102  } else if (!strcasecmp(var, "review")){
1104  } else if (!strcasecmp(var, "tempgreetwarn")){
1106  } else if (!strcasecmp(var, "messagewrap")){
1108  } else if (!strcasecmp(var, "operator")) {
1110  } else if (!strcasecmp(var, "envelope")){
1112  } else if (!strcasecmp(var, "moveheard")){
1114  } else if (!strcasecmp(var, "sayduration")){
1116  } else if (!strcasecmp(var, "saydurationm")){
1117  if (sscanf(value, "%30d", &x) == 1) {
1118  vmu->saydurationm = x;
1119  } else {
1120  ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n");
1121  }
1122  } else if (!strcasecmp(var, "forcename")){
1124  } else if (!strcasecmp(var, "forcegreetings")){
1126  } else if (!strcasecmp(var, "callback")) {
1127  ast_copy_string(vmu->callback, value, sizeof(vmu->callback));
1128  } else if (!strcasecmp(var, "dialout")) {
1129  ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout));
1130  } else if (!strcasecmp(var, "exitcontext")) {
1131  ast_copy_string(vmu->exit, value, sizeof(vmu->exit));
1132  } else if (!strcasecmp(var, "minsecs")) {
1133  if (sscanf(value, "%30d", &x) == 1 && x >= 0) {
1134  vmu->minsecs = x;
1135  } else {
1136  ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs);
1137  vmu->minsecs = vmminsecs;
1138  }
1139  } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) {
1140  vmu->maxsecs = atoi(value);
1141  if (vmu->maxsecs <= 0) {
1142  ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs);
1143  vmu->maxsecs = vmmaxsecs;
1144  } else {
1145  vmu->maxsecs = atoi(value);
1146  }
1147  if (!strcasecmp(var, "maxmessage"))
1148  ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n");
1149  } else if (!strcasecmp(var, "maxmsg")) {
1150  vmu->maxmsg = atoi(value);
1151  /* Accept maxmsg=0 (Greetings only voicemail) */
1152  if (vmu->maxmsg < 0) {
1153  ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG);
1154  vmu->maxmsg = MAXMSG;
1155  } else if (vmu->maxmsg > MAXMSGLIMIT) {
1156  ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value);
1157  vmu->maxmsg = MAXMSGLIMIT;
1158  }
1159  } else if (!strcasecmp(var, "nextaftercmd")) {
1161  } else if (!strcasecmp(var, "backupdeleted")) {
1162  if (sscanf(value, "%30d", &x) == 1)
1163  vmu->maxdeletedmsg = x;
1164  else if (ast_true(value))
1165  vmu->maxdeletedmsg = MAXMSG;
1166  else
1167  vmu->maxdeletedmsg = 0;
1168 
1169  if (vmu->maxdeletedmsg < 0) {
1170  ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG);
1171  vmu->maxdeletedmsg = MAXMSG;
1172  } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) {
1173  ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value);
1174  vmu->maxdeletedmsg = MAXMSGLIMIT;
1175  }
1176  } else if (!strcasecmp(var, "volgain")) {
1177  sscanf(value, "%30lf", &vmu->volgain);
1178  } else if (!strcasecmp(var, "passwordlocation")) {
1179  if (!strcasecmp(value, "spooldir")) {
1181  } else {
1183  }
1184  } else if (!strcasecmp(var, "options")) {
1185  apply_options(vmu, value);
1186  }
1187 }
double volgain
#define VM_OPERATOR
#define MAXMSGLIMIT
#define VM_ATTACH
#define ast_strdup(a)
Definition: astmm.h:109
char attachfmt[20]
#define VM_FORCEGREET
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define LOG_WARNING
Definition: logger.h:144
static const char * substitute_escapes(const char *value)
#define AST_LOG_WARNING
Definition: logger.h:149
#define var
Definition: ast_expr2f.c:606
#define VM_TEMPGREETWARN
int value
Definition: syslog.c:39
#define VM_SVMAIL
char locale[20]
#define VM_FORCENAME
char * emailsubject
#define VM_SAYDURATION
int passwordlocation
#define VM_REVIEW
char zonetag[80]
static void apply_options(struct ast_vm_user *vmu, const char *options)
Destructively Parse options and apply.
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 int vmminsecs
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_ENVELOPE
#define MAXMSG
#define VM_SKIPAFTERCMD
char language[MAX_LANGUAGE]
#define VM_SAYCID
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]
#define VM_MOVEHEARD
char callback[80]
static int vmmaxsecs
char serveremail[80]
#define VM_MESSAGEWRAP
#define VM_DELETE
static void apply_options ( struct ast_vm_user vmu,
const char *  options 
)
static

Destructively Parse options and apply.

Definition at line 1305 of file app_voicemail_imapstorage.c.

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

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

1306 {
1307  char *stringp;
1308  char *s;
1309  char *var, *value;
1310  stringp = ast_strdupa(options);
1311  while ((s = strsep(&stringp, "|"))) {
1312  value = s;
1313  if ((var = strsep(&value, "=")) && value) {
1314  apply_option(vmu, var, value);
1315  }
1316  }
1317 }
char * strsep(char **str, const char *delims)
#define var
Definition: ast_expr2f.c:606
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_option(struct ast_vm_user *vmu, const char *var, const char *value)
Sets a a specific property value.
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 1324 of file app_voicemail_imapstorage.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().

1325 {
1326  for (; var; var = var->next) {
1327  if (!strcasecmp(var->name, "vmsecret")) {
1328  ast_copy_string(retval->password, var->value, sizeof(retval->password));
1329  } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */
1330  if (ast_strlen_zero(retval->password)) {
1331  if (!ast_strlen_zero(var->value) && var->value[0] == '*') {
1332  ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password"
1333  "\n\tmust be reset in voicemail.conf.\n", retval->mailbox);
1334  } else {
1335  ast_copy_string(retval->password, var->value, sizeof(retval->password));
1336  }
1337  }
1338  } else if (!strcasecmp(var->name, "uniqueid")) {
1339  ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid));
1340  } else if (!strcasecmp(var->name, "pager")) {
1341  ast_copy_string(retval->pager, var->value, sizeof(retval->pager));
1342  } else if (!strcasecmp(var->name, "email")) {
1343  ast_copy_string(retval->email, var->value, sizeof(retval->email));
1344  } else if (!strcasecmp(var->name, "fullname")) {
1345  ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname));
1346  } else if (!strcasecmp(var->name, "context")) {
1347  ast_copy_string(retval->context, var->value, sizeof(retval->context));
1348  } else if (!strcasecmp(var->name, "emailsubject")) {
1349  ast_free(retval->emailsubject);
1351  } else if (!strcasecmp(var->name, "emailbody")) {
1352  ast_free(retval->emailbody);
1353  retval->emailbody = ast_strdup(substitute_escapes(var->value));
1354 #ifdef IMAP_STORAGE
1355  } else if (!strcasecmp(var->name, "imapuser")) {
1356  ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser));
1357  retval->imapversion = imapversion;
1358  } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) {
1359  ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword));
1360  retval->imapversion = imapversion;
1361  } else if (!strcasecmp(var->name, "imapfolder")) {
1362  ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder));
1363  } else if (!strcasecmp(var->name, "imapvmshareid")) {
1364  ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid));
1365  retval->imapversion = imapversion;
1366 #endif
1367  } else
1368  apply_option(retval, var->name, var->value);
1369  }
1370 }
char uniqueid[80]
char fullname[80]
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
static const char * substitute_escapes(const char *value)
#define var
Definition: ast_expr2f.c:606
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
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
static void apply_option(struct ast_vm_user *vmu, const char *var, const char *value)
Sets a a specific property value.
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 4519 of file app_voicemail_imapstorage.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().

4520 {
4521  struct ast_str *tmp = ast_str_alloca(80);
4522  int first_section = 1;
4523 
4524  ast_str_reset(*end);
4525  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
4526  for (; *start; start++) {
4527  int need_encoding = 0;
4528  if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) {
4529  need_encoding = 1;
4530  }
4531  if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) ||
4532  (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) ||
4533  (!first_section && need_encoding && ast_str_strlen(tmp) > 70) ||
4534  (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) {
4535  /* Start new line */
4536  ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp));
4537  ast_str_set(&tmp, -1, "=?%s?Q?", charset);
4538  first_section = 0;
4539  }
4540  if (need_encoding && *start == ' ') {
4541  ast_str_append(&tmp, -1, "_");
4542  } else if (need_encoding) {
4543  ast_str_append(&tmp, -1, "=%hhX", *start);
4544  } else {
4545  ast_str_append(&tmp, -1, "%c", *start);
4546  }
4547  }
4548  ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : "");
4549  return ast_str_buffer(*end);
4550 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
#define ast_str_alloca(init_len)
Definition: strings.h:608
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:874
static char charset[32]
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 4447 of file app_voicemail_imapstorage.c.

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

Referenced by make_email_file(), and sendpage().

4448 {
4449  const char *ptr;
4450 
4451  /* We're only ever passing 0 to maxlen, so short output isn't possible */
4452  ast_str_set(buf, maxlen, "\"");
4453  for (ptr = from; *ptr; ptr++) {
4454  if (*ptr == '"' || *ptr == '\\') {
4455  ast_str_append(buf, maxlen, "\\%c", *ptr);
4456  } else {
4457  ast_str_append(buf, maxlen, "%c", *ptr);
4458  }
4459  }
4460  ast_str_append(buf, maxlen, "\"");
4461 
4462  return ast_str_buffer(*buf);
4463 }
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 10791 of file app_voicemail_imapstorage.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.

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

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

Referenced by add_email_attachment().

4324 {
4325  static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
4326  'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
4327  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
4328  '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
4329  int i, hiteof = 0;
4330  FILE *fi;
4331  struct baseio bio;
4332 
4333  memset(&bio, 0, sizeof(bio));
4334  bio.iocp = BASEMAXINLINE;
4335 
4336  if (!(fi = fopen(filename, "rb"))) {
4337  ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno));
4338  return -1;
4339  }
4340 
4341  while (!hiteof){
4342  unsigned char igroup[3], ogroup[4];
4343  int c, n;
4344 
4345  memset(igroup, 0, sizeof(igroup));
4346 
4347  for (n = 0; n < 3; n++) {
4348  if ((c = inchar(&bio, fi)) == EOF) {
4349  hiteof = 1;
4350  break;
4351  }
4352 
4353  igroup[n] = (unsigned char) c;
4354  }
4355 
4356  if (n > 0) {
4357  ogroup[0]= dtable[igroup[0] >> 2];
4358  ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
4359  ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
4360  ogroup[3]= dtable[igroup[2] & 0x3F];
4361 
4362  if (n < 3) {
4363  ogroup[3] = '=';
4364 
4365  if (n < 2)
4366  ogroup[2] = '=';
4367  }
4368 
4369  for (i = 0; i < 4; i++)
4370  ochar(&bio, ogroup[i], so);
4371  }
4372  }
4373 
4374  fclose(fi);
4375 
4376  if (fputs(ENDL, so) == EOF) {
4377  return 0;
4378  }
4379 
4380  return 1;
4381 }
#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()
static int inchar(struct baseio *bio, FILE *fi)
utility used by base_encode()
#define BASEMAXINLINE
#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 1283 of file app_voicemail_imapstorage.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().

1284 {
1285  int res = -1;
1286  if (!strcmp(vmu->password, password)) {
1287  /* No change (but an update would return 0 rows updated, so we opt out here) */
1288  return 0;
1289  }
1290 
1291  if (strlen(password) > 10) {
1292  ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL);
1293  }
1294  if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) {
1295  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime");
1296  ast_copy_string(vmu->password, password, sizeof(vmu->password));
1297  res = 0;
1298  }
1299  return res;
1300 }
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 4492 of file app_voicemail_imapstorage.c.

References str.

Referenced by make_email_file(), and sendpage().

4493 {
4494  for (; *str; str++) {
4495  if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) {
4496  return 1;
4497  }
4498  }
4499  return 0;
4500 }
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 1242 of file app_voicemail_imapstorage.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().

1243 {
1244  /* check minimum length */
1245  if (strlen(password) < minpassword)
1246  return 1;
1247  /* check that password does not contain '*' character */
1248  if (!ast_strlen_zero(password) && password[0] == '*')
1249  return 1;
1251  char cmd[255], buf[255];
1252 
1253  ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password);
1254 
1255  snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password);
1256  if (vm_check_password_shell(cmd, buf, sizeof(buf))) {
1257  ast_debug(5, "Result: %s\n", buf);
1258  if (!strncasecmp(buf, "VALID", 5)) {
1259  ast_debug(3, "Passed password check: '%s'\n", buf);
1260  return 0;
1261  } else if (!strncasecmp(buf, "FAILURE", 7)) {
1262  ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf);
1263  return 0;
1264  } else {
1265  ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password);
1266  return 1;
1267  }
1268  }
1269  }
1270  return 0;
1271 }
#define AST_LOG_WARNING
Definition: logger.h:149
static int minpassword
#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]
static char ext_pass_check_cmd[128]
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_LOG_DEBUG
Definition: logger.h:127
static char * vm_check_password_shell(char *command, char *buf, size_t len)
char password[80]
static int close_mailbox ( struct vm_state vms,
struct ast_vm_user vmu 
)
static

Definition at line 8012 of file app_voicemail_imapstorage.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().

8013 {
8014  int x = 0;
8015  int last_msg_idx = 0;
8016 
8017 #ifndef IMAP_STORAGE
8018  int res = 0, nummsg;
8019  char fn2[PATH_MAX];
8020 #endif
8021 
8022  if (vms->lastmsg <= -1) {
8023  goto done;
8024  }
8025 
8026  vms->curmsg = -1;
8027 #ifndef IMAP_STORAGE
8028  /* Get the deleted messages fixed */
8029  if (vm_lock_path(vms->curdir)) {
8030  return ERROR_LOCK_PATH;
8031  }
8032 
8033  /* update count as message may have arrived while we've got mailbox open */
8034  last_msg_idx = last_message_index(vmu, vms->curdir);
8035  if (last_msg_idx != vms->lastmsg) {
8036  ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg);
8037  }
8038 
8039  /* must check up to last detected message, just in case it is erroneously greater than maxmsg */
8040  for (x = 0; x < last_msg_idx + 1; x++) {
8041  if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) {
8042  /* Save this message. It's not in INBOX or hasn't been heard */
8043  make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
8044  if (!EXISTS(vms->curdir, x, vms->fn, NULL)) {
8045  break;
8046  }
8047  vms->curmsg++;
8048  make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg);
8049  if (strcmp(vms->fn, fn2)) {
8050  RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2);
8051  }
8052  } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) {
8053  /* Move to old folder before deleting */
8054  res = save_to_folder(vmu, vms, x, 1);
8055  if (res == ERROR_LOCK_PATH) {
8056  /* If save failed do not delete the message */
8057  ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full");
8058  vms->deleted[x] = 0;
8059  vms->heard[x] = 0;
8060  --x;
8061  }
8062  } else if (vms->deleted[x] && vmu->maxdeletedmsg) {
8063  /* Move to deleted folder */
8064  res = save_to_folder(vmu, vms, x, 10);
8065  if (res == ERROR_LOCK_PATH) {
8066  /* If save failed do not delete the message */
8067  vms->deleted[x] = 0;
8068  vms->heard[x] = 0;
8069  --x;
8070  }
8071  } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) {
8072  /* If realtime storage enabled - we should explicitly delete this message,
8073  cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */
8074  make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
8075  if (EXISTS(vms->curdir, x, vms->fn, NULL)) {
8076  DELETE(vms->curdir, x, vms->fn, vmu);
8077  }
8078  }
8079  }
8080 
8081  /* Delete ALL remaining messages */
8082  nummsg = x - 1;
8083  for (x = vms->curmsg + 1; x <= nummsg; x++) {
8084  make_file(vms->fn, sizeof(vms->fn), vms->curdir, x);
8085  if (EXISTS(vms->curdir, x, vms->fn, NULL)) {
8086  DELETE(vms->curdir, x, vms->fn, vmu);
8087  }
8088  }
8089  ast_unlock_path(vms->curdir);
8090 #else /* defined(IMAP_STORAGE) */
8091  ast_mutex_lock(&vms->lock);
8092  if (vms->deleted) {
8093  /* Since we now expunge after each delete, deleting in reverse order
8094  * ensures that no reordering occurs between each step. */
8095  last_msg_idx = vms->dh_arraysize;
8096  for (x = last_msg_idx - 1; x >= 0; x--) {
8097  if (vms->deleted[x]) {
8098  ast_debug(3, "IMAP delete of %d\n", x);
8099  DELETE(vms->curdir, x, vms->fn, vmu);
8100  }
8101  }
8102  }
8103 #endif
8104 
8105 done:
8106  if (vms->deleted) {
8107  ast_free(vms->deleted);
8108  vms->deleted = NULL;
8109  }
8110  if (vms->heard) {
8111  ast_free(vms->heard);
8112  vms->heard = NULL;
8113  }
8114  vms->dh_arraysize = 0;
8115 #ifdef IMAP_STORAGE
8116  ast_mutex_unlock(&vms->lock);
8117 #endif
8118 
8119  return 0;
8120 }
#define EXISTS(a, b, c, d)
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_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]
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 ast_mutex_lock(a)
Definition: lock.h:155
static int save_to_folder(struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box)
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
#define ERROR_LOCK_PATH
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
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...
#define VM_MOVEHEARD
char curbox[80]
#define RENAME(a, b, c, d, e, f, g, h)
#define DELETE(a, b, c, d)
#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 11111 of file app_voicemail_imapstorage.c.

References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.

Referenced by handle_voicemail_show_users().

11112 {
11113  int which = 0;
11114  int wordlen;
11115  struct ast_vm_user *vmu;
11116  const char *context = "";
11117 
11118  /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */
11119  if (pos > 4)
11120  return NULL;
11121  if (pos == 3)
11122  return (state == 0) ? ast_strdup("for") : NULL;
11123  wordlen = strlen(word);
11124  AST_LIST_TRAVERSE(&users, vmu, list) {
11125  if (!strncasecmp(word, vmu->context, wordlen)) {
11126  if (context && strcmp(context, vmu->context) && ++which > state)
11127  return ast_strdup(vmu->context);
11128  /* ignore repeated contexts ? */
11129  context = vmu->context;
11130  }
11131  }
11132  return NULL;
11133 }
#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 4128 of file app_voicemail_imapstorage.c.

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

Referenced by copy_plain_file(), and vm_forwardoptions().

4129 {
4130  int ifd;
4131  int ofd;
4132  int res;
4133  int len;
4134  char buf[4096];
4135 
4136 #ifdef HARDLINK_WHEN_POSSIBLE
4137  /* Hard link if possible; saves disk space & is faster */
4138  if (link(infile, outfile)) {
4139 #endif
4140  if ((ifd = open(infile, O_RDONLY)) < 0) {
4141  ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno));
4142  return -1;
4143  }
4144  if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) {
4145  ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno));
4146  close(ifd);
4147  return -1;
4148  }
4149  do {
4150  len = read(ifd, buf, sizeof(buf));
4151  if (len < 0) {
4152  ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
4153  close(ifd);
4154  close(ofd);
4155  unlink(outfile);
4156  } else if (len) {
4157  res = write(ofd, buf, len);
4158  if (errno == ENOMEM || errno == ENOSPC || res != len) {
4159  ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
4160  close(ifd);
4161  close(ofd);
4162  unlink(outfile);
4163  }
4164  }
4165  } while (len);
4166  close(ifd);
4167  close(ofd);
4168  return 0;
4169 #ifdef HARDLINK_WHEN_POSSIBLE
4170  } else {
4171  /* Hard link succeeded */
4172  return 0;
4173  }
4174 #endif
4175 }
#define AST_LOG_WARNING
Definition: logger.h:149
#define VOICEMAIL_FILE_MODE
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
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 5364 of file app_voicemail_imapstorage.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().

5365 {
5366  char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX];
5367  const char *frombox = mbox(vmu, imbox);
5368  const char *userfolder;
5369  int recipmsgnum;
5370  int res = 0;
5371 
5372  ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context);
5373 
5374  if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */
5375  userfolder = "Urgent";
5376  } else {
5377  userfolder = "INBOX";
5378  }
5379 
5380  create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder);
5381 
5382  if (!dir)
5383  make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
5384  else
5385  ast_copy_string(fromdir, dir, sizeof(fromdir));
5386 
5387  make_file(frompath, sizeof(frompath), fromdir, msgnum);
5388  make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder);
5389 
5390  if (vm_lock_path(todir))
5391  return ERROR_LOCK_PATH;
5392 
5393  recipmsgnum = last_message_index(recip, todir) + 1;
5394  if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) {
5395  make_file(topath, sizeof(topath), todir, recipmsgnum);
5396 #ifndef ODBC_STORAGE
5397  if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
5398  COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath);
5399  } else {
5400 #endif
5401  /* If we are prepending a message for ODBC, then the message already
5402  * exists in the database, but we want to force copying from the
5403  * filesystem (since only the FS contains the prepend). */
5404  copy_plain_file(frompath, topath);
5405  STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL);
5406  vm_delete(topath);
5407 #ifndef ODBC_STORAGE
5408  }
5409 #endif
5410  } else {
5411  ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
5412  res = -1;
5413  }
5414  ast_unlock_path(todir);
5415  notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt,
5416  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
5417  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
5418  flag);
5419 
5420  return res;
5421 }
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 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...
#define EXISTS(a, b, c, d)
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...
static void copy_plain_file(char *frompath, char *topath)
Copies a voicemail information (envelope) 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
char * str
Subscriber name (Malloced)
Definition: channel.h:214
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. ...
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
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]
#define ERROR_LOCK_PATH
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 COPY(a, b, c, d, e, f, g, h)
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 inprocess_count(const char *context, const char *mailbox, int delta)
static int maxmsg
#define STORE(a, b, c, d, e, f, g, h, i, j)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
static int vm_delete(char *file)
Removes the voicemail sound and information file.
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
const ast_string_field language
Definition: channel.h:787
static const char * mbox(struct ast_vm_user *vmu, int id)
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.
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 4186 of file app_voicemail_imapstorage.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().

4187 {
4188  char frompath2[PATH_MAX], topath2[PATH_MAX];
4189  struct ast_variable *tmp,*var = NULL;
4190  const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL;
4191  ast_filecopy(frompath, topath, NULL);
4192  snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath);
4193  snprintf(topath2, sizeof(topath2), "%s.txt", topath);
4194  if (ast_check_realtime("voicemail_data")) {
4195  var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL);
4196  /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */
4197  for (tmp = var; tmp; tmp = tmp->next) {
4198  if (!strcasecmp(tmp->name, "origmailbox")) {
4199  origmailbox = tmp->value;
4200  } else if (!strcasecmp(tmp->name, "context")) {
4201  context = tmp->value;
4202  } else if (!strcasecmp(tmp->name, "macrocontext")) {
4203  macrocontext = tmp->value;
4204  } else if (!strcasecmp(tmp->name, "exten")) {
4205  exten = tmp->value;
4206  } else if (!strcasecmp(tmp->name, "priority")) {
4207  priority = tmp->value;
4208  } else if (!strcasecmp(tmp->name, "callerchan")) {
4209  callerchan = tmp->value;
4210  } else if (!strcasecmp(tmp->name, "callerid")) {
4211  callerid = tmp->value;
4212  } else if (!strcasecmp(tmp->name, "origdate")) {
4213  origdate = tmp->value;
4214  } else if (!strcasecmp(tmp->name, "origtime")) {
4215  origtime = tmp->value;
4216  } else if (!strcasecmp(tmp->name, "category")) {
4217  category = tmp->value;
4218  } else if (!strcasecmp(tmp->name, "duration")) {
4219  duration = tmp->value;
4220  }
4221  }
4222  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);
4223  }
4224  copy(frompath2, topath2);
4225  ast_variables_destroy(var);
4226 }
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
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define SENTINEL
Definition: compiler.h:75
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
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 4023 of file app_voicemail_imapstorage.c.

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

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

4024 {
4025 
4026  int vmcount = 0;
4027  DIR *vmdir = NULL;
4028  struct dirent *vment = NULL;
4029 
4030  if (vm_lock_path(dir))
4031  return ERROR_LOCK_PATH;
4032 
4033  if ((vmdir = opendir(dir))) {
4034  while ((vment = readdir(vmdir))) {
4035  if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) {
4036  vmcount++;
4037  }
4038  }
4039  closedir(vmdir);
4040  }
4041  ast_unlock_path(dir);
4042 
4043  return vmcount;
4044 }
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 1706 of file app_voicemail_imapstorage.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().

1707 {
1708  mode_t mode = VOICEMAIL_DIR_MODE;
1709  int res;
1710 
1711  make_dir(dest, len, context, ext, folder);
1712  if ((res = ast_mkdir(dest, mode))) {
1713  ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res));
1714  return -1;
1715  }
1716  return 0;
1717 }
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...
#define AST_LOG_WARNING
Definition: logger.h:149
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
#define VOICEMAIL_DIR_MODE
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
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 13140 of file app_voicemail_imapstorage.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().

13141 {
13142  int cmd = 0;
13143  char destination[80] = "";
13144  int retries = 0;
13145 
13146  if (!num) {
13147  ast_verb(3, "Destination number will be entered manually\n");
13148  while (retries < 3 && cmd != 't') {
13149  destination[1] = '\0';
13150  destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call");
13151  if (!cmd)
13152  destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound");
13153  if (!cmd)
13154  destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel");
13155  if (!cmd) {
13156  cmd = ast_waitfordigit(chan, 6000);
13157  if (cmd)
13158  destination[0] = cmd;
13159  }
13160  if (!cmd) {
13161  retries++;
13162  } else {
13163 
13164  if (cmd < 0)
13165  return 0;
13166  if (cmd == '*') {
13167  ast_verb(3, "User hit '*' to cancel outgoing call\n");
13168  return 0;
13169  }
13170  if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0)
13171  retries++;
13172  else
13173  cmd = 't';
13174  }
13175  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
13176  }
13177  if (retries >= 3) {
13178  return 0;
13179  }
13180 
13181  } else {
13182  if (option_verbose > 2)
13183  ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num);
13184  ast_copy_string(destination, num, sizeof(destination));
13185  }
13186 
13187  if (!ast_strlen_zero(destination)) {
13188  if (destination[strlen(destination) -1 ] == '*')
13189  return 0;
13190  if (option_verbose > 2)
13191  ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context);
13192  ast_copy_string(chan->exten, destination, sizeof(chan->exten));
13193  ast_copy_string(chan->context, outgoing_context, sizeof(chan->context));
13194  chan->priority = 0;
13195  return 9;
13196  }
13197  return 0;
13198 }
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 10694 of file app_voicemail_imapstorage.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().

10695 {
10696  struct ast_vm_user *vmu;
10697 
10698  if (!ast_strlen_zero(box) && box[0] == '*') {
10699  ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character,"
10700  "\n\twhen it is the first character in a mailbox or password, is used to jump to a"
10701  "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid"
10702  "\n\tand will be ignored.\n", box, context);
10703  return NULL;
10704  }
10705 
10706  AST_LIST_TRAVERSE(&users, vmu, list) {
10707  if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) {
10708  if (strcasecmp(vmu->context, context)) {
10709  ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\
10710  \n\tcontexts and that you have the 'searchcontexts' option on. This type of\
10711  \n\tconfiguration creates an ambiguity that you likely do not want. Please\
10712  \n\tamend your voicemail.conf file to avoid this situation.\n", box);
10713  }
10714  ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box);
10715  return NULL;
10716  }
10717  if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) {
10718  ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context);
10719  return NULL;
10720  }
10721  }
10722 
10723  if (!(vmu = ast_calloc(1, sizeof(*vmu))))
10724  return NULL;
10725 
10726  ast_copy_string(vmu->context, context, sizeof(vmu->context));
10727  ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox));
10728 
10730 
10731  return vmu;
10732 }
#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
#define VM_SEARCH
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
static struct ast_flags globalflags
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static 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 1445 of file app_voicemail_imapstorage.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().

1446 {
1447  /* This function could be made to generate one from a database, too */
1448  struct ast_vm_user *vmu = NULL, *cur;
1449  AST_LIST_LOCK(&users);
1450 
1452  context = "default";
1453 
1454  AST_LIST_TRAVERSE(&users, cur, list) {
1455 #ifdef IMAP_STORAGE
1456  if (cur->imapversion != imapversion) {
1457  continue;
1458  }
1459 #endif
1460  if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox))
1461  break;
1462  if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox)))
1463  break;
1464  }
1465  if (cur) {
1466  /* Make a copy, so that on a reload, we have no race */
1467  if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) {
1468  *vmu = *cur;
1469  if (!ivm) {
1470  vmu->emailbody = ast_strdup(cur->emailbody);
1471  vmu->emailsubject = ast_strdup(cur->emailsubject);
1472  }
1473  ast_set2_flag(vmu, !ivm, VM_ALLOCED);
1474  AST_LIST_NEXT(vmu, list) = NULL;
1475  }
1476  } else
1477  vmu = find_user_realtime(ivm, context, mailbox);
1479  return vmu;
1480 }
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_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#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
#define VM_SEARCH
char * emailsubject
struct ast_vm_user::@65 list
char * emailbody
#define VM_ALLOCED
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static struct ast_flags globalflags
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 1404 of file app_voicemail_imapstorage.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().

1405 {
1406  struct ast_variable *var;
1407  struct ast_vm_user *retval;
1408 
1409  if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) {
1410  if (ivm) {
1411  memset(retval, 0, sizeof(*retval));
1412  }
1413  populate_defaults(retval);
1414  if (!ivm) {
1415  ast_set_flag(retval, VM_ALLOCED);
1416  }
1417  if (mailbox) {
1418  ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox));
1419  }
1420  if (!context && ast_test_flag((&globalflags), VM_SEARCH)) {
1421  var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL);
1422  } else {
1423  var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL);
1424  }
1425  if (var) {
1426  apply_options_full(retval, var);
1427  ast_variables_destroy(var);
1428  } else {
1429  if (!ivm)
1430  free_user(retval);
1431  retval = NULL;
1432  }
1433  }
1434  return retval;
1435 }
static void free_user(struct ast_vm_user *vmu)
#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 VM_SEARCH
#define SENTINEL
Definition: compiler.h:75
char mailbox[AST_MAX_EXTENSION]
static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *var)
Loads the options specific to a voicemail user.
#define VM_ALLOCED
static struct ast_flags globalflags
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static void populate_defaults(struct ast_vm_user *vmu)
Sets default voicemail system options to a voicemail user.
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
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 7214 of file app_voicemail_imapstorage.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().

7215 {
7216 #ifdef IMAP_STORAGE
7217  int todircount = 0;
7218  struct vm_state *dstvms;
7219 #endif
7220  char username[70]="";
7221  char fn[PATH_MAX]; /* for playback of name greeting */
7222  char ecodes[16] = "#";
7223  int res = 0, cmd = 0;
7224  struct ast_vm_user *receiver = NULL, *vmtmp;
7226  char *stringp;
7227  const char *s;
7228  int saved_messages = 0;
7229  int valid_extensions = 0;
7230  char *dir;
7231  int curmsg;
7232  char urgent_str[7] = "";
7233  int prompt_played = 0;
7234 #ifndef IMAP_STORAGE
7235  char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX];
7236 #endif
7238  ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str));
7239  }
7240 
7241  if (vms == NULL) return -1;
7242  dir = vms->curdir;
7243  curmsg = vms->curmsg;
7244 
7245  ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu");
7246  while (!res && !valid_extensions) {
7247  int use_directory = 0;
7249  int done = 0;
7250  int retries = 0;
7251  cmd = 0;
7252  while ((cmd >= 0) && !done ){
7253  if (cmd)
7254  retries = 0;
7255  switch (cmd) {
7256  case '1':
7257  use_directory = 0;
7258  done = 1;
7259  break;
7260  case '2':
7261  use_directory = 1;
7262  done = 1;
7263  break;
7264  case '*':
7265  cmd = 't';
7266  done = 1;
7267  break;
7268  default:
7269  /* Press 1 to enter an extension press 2 to use the directory */
7270  cmd = ast_play_and_wait(chan, "vm-forward");
7271  if (!cmd) {
7272  cmd = ast_waitfordigit(chan, 3000);
7273  }
7274  if (!cmd) {
7275  retries++;
7276  }
7277  if (retries > 3) {
7278  cmd = 't';
7279  done = 1;
7280  }
7281  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
7282  }
7283  }
7284  if (cmd < 0 || cmd == 't')
7285  break;
7286  }
7287 
7288  if (use_directory) {
7289  /* use app_directory */
7290 
7291  char old_context[sizeof(chan->context)];
7292  char old_exten[sizeof(chan->exten)];
7293  int old_priority;
7294  struct ast_app* directory_app;
7295 
7296  directory_app = pbx_findapp("Directory");
7297  if (directory_app) {
7298  char vmcontext[256];
7299  /* make backup copies */
7300  memcpy(old_context, chan->context, sizeof(chan->context));
7301  memcpy(old_exten, chan->exten, sizeof(chan->exten));
7302  old_priority = chan->priority;
7303 
7304  /* call the the Directory, changes the channel */
7305  snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default");
7306  res = pbx_exec(chan, directory_app, vmcontext);
7307 
7308  ast_copy_string(username, chan->exten, sizeof(username));
7309 
7310  /* restore the old context, exten, and priority */
7311  memcpy(chan->context, old_context, sizeof(chan->context));
7312  memcpy(chan->exten, old_exten, sizeof(chan->exten));
7313  chan->priority = old_priority;
7314  } else {
7315  ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n");
7317  }
7318  } else {
7319  /* Ask for an extension */
7320  res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */
7321  prompt_played++;
7322  if (res || prompt_played > 4)
7323  break;
7324  if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0))
7325  break;
7326  }
7327 
7328  /* start all over if no username */
7329  if (ast_strlen_zero(username))
7330  continue;
7331  stringp = username;
7332  s = strsep(&stringp, "*");
7333  /* start optimistic */
7334  valid_extensions = 1;
7335  while (s) {
7336  if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) {
7337  int oldmsgs;
7338  int newmsgs;
7339  int capacity;
7340  if (inboxcount(s, &newmsgs, &oldmsgs)) {
7341  ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s);
7342  /* Shouldn't happen, but allow trying another extension if it does */
7343  res = ast_play_and_wait(chan, "pbx-invalid");
7344  valid_extensions = 0;
7345  break;
7346  }
7347  capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1);
7348  if ((newmsgs + oldmsgs) >= capacity) {
7349  ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity);
7350  res = ast_play_and_wait(chan, "vm-mailboxfull");
7351  valid_extensions = 0;
7352  while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
7353  inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
7354  free_user(vmtmp);
7355  }
7356  inprocess_count(receiver->mailbox, receiver->context, -1);
7357  break;
7358  }
7359  AST_LIST_INSERT_HEAD(&extensions, receiver, list);
7360  } else {
7361  /* XXX Optimization for the future. When we encounter a single bad extension,
7362  * bailing out on all of the extensions may not be the way to go. We should
7363  * probably just bail on that single extension, then allow the user to enter
7364  * several more. XXX
7365  */
7366  while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) {
7367  free_user(receiver);
7368  }
7369  ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s);
7370  /* "I am sorry, that's not a valid extension. Please try again." */
7371  res = ast_play_and_wait(chan, "pbx-invalid");
7372  valid_extensions = 0;
7373  break;
7374  }
7375 
7376  /* play name if available, else play extension number */
7377  snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s);
7378  RETRIEVE(fn, -1, s, receiver->context);
7379  if (ast_fileexists(fn, NULL, NULL) > 0) {
7380  res = ast_stream_and_wait(chan, fn, ecodes);
7381  if (res) {
7382  DISPOSE(fn, -1);
7383  return res;
7384  }
7385  } else {
7386  res = ast_say_digit_str(chan, s, ecodes, chan->language);
7387  }
7388  DISPOSE(fn, -1);
7389 
7390  s = strsep(&stringp, "*");
7391  }
7392  /* break from the loop of reading the extensions */
7393  if (valid_extensions)
7394  break;
7395  }
7396  /* check if we're clear to proceed */
7397  if (AST_LIST_EMPTY(&extensions) || !valid_extensions)
7398  return res;
7399  if (is_new_message == 1) {
7400  struct leave_vm_options leave_options;
7401  char mailbox[AST_MAX_EXTENSION * 2 + 2];
7402  snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context);
7403 
7404  /* Send VoiceMail */
7405  memset(&leave_options, 0, sizeof(leave_options));
7406  leave_options.record_gain = record_gain;
7407  cmd = leave_voicemail(chan, mailbox, &leave_options);
7408  } else {
7409  /* Forward VoiceMail */
7410  long duration = 0;
7411  struct vm_state vmstmp;
7412  int copy_msg_result = 0;
7413  memcpy(&vmstmp, vms, sizeof(vmstmp));
7414 
7415  RETRIEVE(dir, curmsg, sender->mailbox, sender->context);
7416 
7417  cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str);
7418  if (!cmd) {
7419  AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) {
7420 #ifdef IMAP_STORAGE
7421  int attach_user_voicemail;
7422  char *myserveremail = serveremail;
7423 
7424  /* get destination mailbox */
7425  dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0);
7426  if (!dstvms) {
7427  dstvms = create_vm_state_from_user(vmtmp);
7428  }
7429  if (dstvms) {
7430  init_mailstream(dstvms, 0);
7431  if (!dstvms->mailstream) {
7432  ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox);
7433  } else {
7434  copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str);
7435  run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str);
7436  }
7437  } else {
7438  ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox);
7439  }
7440  if (!ast_strlen_zero(vmtmp->serveremail))
7441  myserveremail = vmtmp->serveremail;
7442  attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH);
7443  /* NULL category for IMAP storage */
7444  sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox,
7445  dstvms->curbox,
7446  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
7447  S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
7448  vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan,
7449  NULL, urgent_str);
7450 #else
7451  copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str);
7452 #endif
7453  saved_messages++;
7455  inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
7456  free_user(vmtmp);
7457  if (res)
7458  break;
7459  }
7461  if (saved_messages > 0 && !copy_msg_result) {
7462  /* give confirmation that the message was saved */
7463  /* commented out since we can't forward batches yet
7464  if (saved_messages == 1)
7465  res = ast_play_and_wait(chan, "vm-message");
7466  else
7467  res = ast_play_and_wait(chan, "vm-messages");
7468  if (!res)
7469  res = ast_play_and_wait(chan, "vm-saved"); */
7470 #ifdef IMAP_STORAGE
7471  /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */
7472  if (ast_strlen_zero(vmstmp.introfn))
7473 #endif
7474  res = ast_play_and_wait(chan, "vm-msgsaved");
7475  }
7476 #ifndef IMAP_STORAGE
7477  else {
7478  /* with IMAP, mailbox full warning played by imap_check_limits */
7479  res = ast_play_and_wait(chan, "vm-mailboxfull");
7480  }
7481  /* Restore original message without prepended message if backup exists */
7482  make_file(msgfile, sizeof(msgfile), dir, curmsg);
7483  strcpy(textfile, msgfile);
7484  strcpy(backup, msgfile);
7485  strcpy(backup_textfile, msgfile);
7486  strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
7487  strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
7488  strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
7489  if (ast_fileexists(backup, NULL, NULL) > 0) {
7490  ast_filerename(backup, msgfile, NULL);
7491  rename(backup_textfile, textfile);
7492  }
7493 #endif
7494  }
7495  DISPOSE(dir, curmsg);
7496 #ifndef IMAP_STORAGE
7497  if (cmd) { /* assuming hangup, cleanup backup file */
7498  make_file(msgfile, sizeof(msgfile), dir, curmsg);
7499  strcpy(textfile, msgfile);
7500  strcpy(backup_textfile, msgfile);
7501  strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
7502  strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
7503  rename(backup_textfile, textfile);
7504  }
7505 #endif
7506  }
7507 
7508  /* If anything failed above, we still have this list to free */
7509  while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) {
7510  inprocess_count(vmtmp->mailbox, vmtmp->context, -1);
7511  free_user(vmtmp);
7512  }
7513  return res ? res : cmd;
7514 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
static void free_user(struct ast_vm_user *vmu)
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
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
static void run_externnotify(char *context, char *extension, const char *flag)
#define VM_ATTACH
#define RETRIEVE(a, b, c, d)
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...
static char vmfmts[80]
#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
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 char VM_SPOOL_DIR[PATH_MAX]
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.
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
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
char mailbox[AST_MAX_EXTENSION]
char username[80]
#define AST_MAX_EXTENSION
Definition: channel.h:135
#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]
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_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
#define VM_DIRECFORWARD
#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
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 VM_FWDURGAUTO
#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 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 struct ast_flags globalflags
static int inprocess_count(const char *context, const char *mailbox, int delta)
#define ast_clear_flag(p, flag)
Definition: utils.h:77
Options for leaving voicemail with the voicemail() application.
Definition: app_minivm.c:635
static char serveremail[80]
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 STORE(a, b, c, d, e, f, g, h, i, j)
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
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 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.
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
#define DISPOSE(a, b)
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 1761 of file app_voicemail_imapstorage.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().

1762 {
1763  if (ast_test_flag(vmu, VM_ALLOCED)) {
1764 
1765  ast_free(vmu->emailbody);
1766  vmu->emailbody = NULL;
1767 
1768  ast_free(vmu->emailsubject);
1769  vmu->emailsubject = NULL;
1770 
1771  ast_free(vmu);
1772  }
1773 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
char * emailsubject
char * emailbody
#define VM_ALLOCED
#define ast_free(a)
Definition: astmm.h:97
static void free_vm_users ( void  )
static

Free the users structure.

Definition at line 11723 of file app_voicemail_imapstorage.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().

11724 {
11725  struct ast_vm_user *current;
11726  AST_LIST_LOCK(&users);
11727  while ((current = AST_LIST_REMOVE_HEAD(&users, list))) {
11728  ast_set_flag(current, VM_ALLOCED);
11729  free_user(current);
11730  }
11732 }
static void free_user(struct ast_vm_user *vmu)
#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
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
#define VM_ALLOCED
static void free_vm_zones ( void  )
static

Free the zones structure.

Definition at line 11735 of file app_voicemail_imapstorage.c.

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

Referenced by actual_load_config(), and unload_module().

11736 {
11737  struct vm_zone *zcur;
11738  AST_LIST_LOCK(&zones);
11739  while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list)))
11740  free_zone(zcur);
11742 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
static void free_zone(struct vm_zone *z)
struct vm_zone::@66 list
static void free_zone ( struct vm_zone z)
static

Definition at line 5132 of file app_voicemail_imapstorage.c.

References ast_free.

Referenced by free_vm_zones().

5133 {
5134  ast_free(z);
5135 }
#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 5088 of file app_voicemail_imapstorage.c.

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

Referenced by leave_voicemail().

5089 {
5090  struct ast_tm tm;
5091  struct timeval t = ast_tvnow();
5092 
5093  ast_localtime(&t, &tm, "UTC");
5094 
5095  return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm);
5096 }
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 6823 of file app_voicemail_imapstorage.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().

6824 {
6825  int x;
6826  int d;
6827  char fn[PATH_MAX];
6828  d = ast_play_and_wait(chan, "vm-press"); /* "Press" */
6829  if (d)
6830  return d;
6831  for (x = start; x < 5; x++) { /* For all folders */
6832  if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL)))
6833  return d;
6834  d = ast_play_and_wait(chan, "vm-for"); /* "for" */
6835  if (d)
6836  return d;
6837  snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */
6838 
6839  /* The inbox folder can have its name changed under certain conditions
6840  * so this checks if the sound file exists for the inbox folder name and
6841  * if it doesn't, plays the default name instead. */
6842  if (x == 0) {
6843  if (ast_fileexists(fn, NULL, NULL)) {
6844  d = vm_play_folder_name(chan, fn);
6845  } else {
6846  ast_verb(1, "failed to find %s\n", fn);
6847  d = vm_play_folder_name(chan, "vm-INBOX");
6848  }
6849  } else {
6850  ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn);
6851  d = vm_play_folder_name(chan, fn);
6852  }
6853 
6854  if (d)
6855  return d;
6856  d = ast_waitfordigit(chan, 500);
6857  if (d)
6858  return d;
6859  }
6860 
6861  d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
6862  if (d)
6863  return d;
6864  d = ast_waitfordigit(chan, 4000);
6865  return d;
6866 }
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
#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
#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
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 const char * mbox(struct ast_vm_user *vmu, int id)
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 6880 of file app_voicemail_imapstorage.c.

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

Referenced by vm_execmain().

6881 {
6882  int res = 0;
6883  int loops = 0;
6884 
6885  res = ast_play_and_wait(chan, fn); /* Folder name */
6886  while (((res < '0') || (res > '9')) &&
6887  (res != '#') && (res >= 0) &&
6888  loops < 4) {
6889  res = get_folder(chan, 0);
6890  loops++;
6891  }
6892  if (loops == 4) { /* give up */
6893  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#');
6894  return '#';
6895  }
6896  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
6897  return res;
6898 }
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 1748 of file app_voicemail_imapstorage.c.

References ARRAY_LEN.

Referenced by vm_execmain().

1749 {
1750  size_t i;
1751 
1752  for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) {
1753  if (strcasecmp(name, mailbox_folders[i]) == 0) {
1754  return i;
1755  }
1756  }
1757 
1758  return -1;
1759 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const char *const mailbox_folders[]
static const char name[]
static int handle_subscribe ( void *  datap)
static

Definition at line 11493 of file app_voicemail_imapstorage.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().

11494 {
11495  unsigned int len;
11496  struct mwi_sub *mwi_sub;
11497  struct mwi_sub_task *p = datap;
11498 
11499  len = sizeof(*mwi_sub);
11500  if (!ast_strlen_zero(p->mailbox))
11501  len += strlen(p->mailbox);
11502 
11503  if (!ast_strlen_zero(p->context))
11504  len += strlen(p->context) + 1; /* Allow for seperator */
11505 
11506  if (!(mwi_sub = ast_calloc(1, len)))
11507  return -1;
11508 
11509  mwi_sub->uniqueid = p->uniqueid;
11510  if (!ast_strlen_zero(p->mailbox))
11511  strcpy(mwi_sub->mailbox, p->mailbox);
11512 
11513  if (!ast_strlen_zero(p->context)) {
11514  strcat(mwi_sub->mailbox, "@");
11515  strcat(mwi_sub->mailbox, p->context);
11516  }
11517 
11519  AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry);
11521  ast_free((void *) p->mailbox);
11522  ast_free((void *) p->context);
11523  ast_free(p);
11524  poll_subscribed_mailbox(mwi_sub);
11525  return 0;
11526 }
#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
static void poll_subscribed_mailbox(struct mwi_sub *mwi_sub)
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
#define ast_calloc(a, b)
Definition: astmm.h:82
static int handle_unsubscribe ( void *  datap)
static

Definition at line 11471 of file app_voicemail_imapstorage.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().

11472 {
11473  struct mwi_sub *mwi_sub;
11474  uint32_t *uniqueid = datap;
11475 
11477  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) {
11478  if (mwi_sub->uniqueid == *uniqueid) {
11479  AST_LIST_REMOVE_CURRENT(entry);
11480  break;
11481  }
11482  }
11485 
11486  if (mwi_sub)
11487  mwi_sub_destroy(mwi_sub);
11488 
11489  ast_free(uniqueid);
11490  return 0;
11491 }
#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 11248 of file app_voicemail_imapstorage.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.

11249 {
11250  switch (cmd) {
11251  case CLI_INIT:
11252  e->command = "voicemail reload";
11253  e->usage =
11254  "Usage: voicemail reload\n"
11255  " Reload voicemail configuration\n";
11256  return NULL;
11257  case CLI_GENERATE:
11258  return NULL;
11259  }
11260 
11261  if (a->argc != 2)
11262  return CLI_SHOWUSAGE;
11263 
11264  ast_cli(a->fd, "Reloading voicemail configuration...\n");
11265  load_config(1);
11266 
11267  return CLI_SUCCESS;
11268 }
static int load_config(int reload)
const int argc
Definition: cli.h:154
Definition: cli.h:146
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
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 11136 of file app_voicemail_imapstorage.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.

11137 {
11138  struct ast_vm_user *vmu;
11139 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n"
11140  const char *context = NULL;
11141  int users_counter = 0;
11142 
11143  switch (cmd) {
11144  case CLI_INIT:
11145  e->command = "voicemail show users";
11146  e->usage =
11147  "Usage: voicemail show users [for <context>]\n"
11148  " Lists all mailboxes currently set up\n";
11149  return NULL;
11150  case CLI_GENERATE:
11151  return complete_voicemail_show_users(a->line, a->word, a->pos, a->n);
11152  }
11153 
11154  if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4))
11155  return CLI_SHOWUSAGE;
11156  if (a->argc == 5) {
11157  if (strcmp(a->argv[3],"for"))
11158  return CLI_SHOWUSAGE;
11159  context = a->argv[4];
11160  }
11161 
11162  if (ast_check_realtime("voicemail")) {
11163  if (!context) {
11164  ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n");
11165  return CLI_SHOWUSAGE;
11166  }
11167  return show_users_realtime(a->fd, context);
11168  }
11169 
11170  AST_LIST_LOCK(&users);
11171  if (AST_LIST_EMPTY(&users)) {
11172  ast_cli(a->fd, "There are no voicemail users currently defined\n");
11174  return CLI_FAILURE;
11175  }
11176  if (!context) {
11177  ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg");
11178  } else {
11179  int count = 0;
11180  AST_LIST_TRAVERSE(&users, vmu, list) {
11181  if (!strcmp(context, vmu->context)) {
11182  count++;
11183  break;
11184  }
11185  }
11186  if (count) {
11187  ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg");
11188  } else {
11189  ast_cli(a->fd, "No such voicemail context \"%s\"\n", context);
11191  return CLI_FAILURE;
11192  }
11193  }
11194  AST_LIST_TRAVERSE(&users, vmu, list) {
11195  int newmsgs = 0, oldmsgs = 0;
11196  char count[12], tmp[256] = "";
11197 
11198  if (!context || !strcmp(context, vmu->context)) {
11199  snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context);
11200  inboxcount(tmp, &newmsgs, &oldmsgs);
11201  snprintf(count, sizeof(count), "%d", newmsgs);
11202  ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count);
11203  users_counter++;
11204  }
11205  }
11207  ast_cli(a->fd, "%d voicemail users configured.\n", users_counter);
11208  return CLI_SUCCESS;
11209 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
char fullname[80]
#define HVSU_OUTPUT_FORMAT
static char * complete_voicemail_show_users(const char *line, const char *word, int pos, int state)
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
static char * show_users_realtime(int fd, const char *context)
#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
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]
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
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
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 11212 of file app_voicemail_imapstorage.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.

11213 {
11214  struct vm_zone *zone;
11215 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n"
11216  char *res = CLI_SUCCESS;
11217 
11218  switch (cmd) {
11219  case CLI_INIT:
11220  e->command = "voicemail show zones";
11221  e->usage =
11222  "Usage: voicemail show zones\n"
11223  " Lists zone message formats\n";
11224  return NULL;
11225  case CLI_GENERATE:
11226  return NULL;
11227  }
11228 
11229  if (a->argc != 3)
11230  return CLI_SHOWUSAGE;
11231 
11232  AST_LIST_LOCK(&zones);
11233  if (!AST_LIST_EMPTY(&zones)) {
11234  ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format");
11235  AST_LIST_TRAVERSE(&zones, zone, list) {
11236  ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format);
11237  }
11238  } else {
11239  ast_cli(a->fd, "There are no voicemail zones currently defined\n");
11240  res = CLI_FAILURE;
11241  }
11243 
11244  return res;
11245 }
#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 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
#define HVSZ_OUTPUT_FORMAT
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 5476 of file app_voicemail_imapstorage.c.

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

Referenced by load_module(), and vm_execmain().

5477 {
5478  char tmp[256], *tmp2 = tmp, *box, *context;
5479  ast_copy_string(tmp, mailbox, sizeof(tmp));
5480  if (ast_strlen_zero(folder)) {
5481  folder = "INBOX";
5482  }
5483  while ((box = strsep(&tmp2, ",&"))) {
5484  if ((context = strchr(box, '@')))
5485  *context++ = '\0';
5486  else
5487  context = "default";
5488  if (__has_voicemail(context, box, folder, 1))
5489  return 1;
5490  /* If we are checking INBOX, we should check Urgent as well */
5491  if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) {
5492  return 1;
5493  }
5494  }
5495  return 0;
5496 }
char * strsep(char **str, const char *delims)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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 int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
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 5558 of file app_voicemail_imapstorage.c.

References inboxcount2().

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

5559 {
5560  int urgentmsgs = 0;
5561  int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs);
5562  if (newmsgs) {
5563  *newmsgs += urgentmsgs;
5564  }
5565  return res;
5566 }
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 5499 of file app_voicemail_imapstorage.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().

5500 {
5501  char tmp[256];
5502  char *context;
5503 
5504  /* If no mailbox, return immediately */
5505  if (ast_strlen_zero(mailbox))
5506  return 0;
5507 
5508  if (newmsgs)
5509  *newmsgs = 0;
5510  if (oldmsgs)
5511  *oldmsgs = 0;
5512  if (urgentmsgs)
5513  *urgentmsgs = 0;
5514 
5515  if (strchr(mailbox, ',')) {
5516  int tmpnew, tmpold, tmpurgent;
5517  char *mb, *cur;
5518 
5519  ast_copy_string(tmp, mailbox, sizeof(tmp));
5520  mb = tmp;
5521  while ((cur = strsep(&mb, ", "))) {
5522  if (!ast_strlen_zero(cur)) {
5523  if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL))
5524  return -1;
5525  else {
5526  if (newmsgs)
5527  *newmsgs += tmpnew;
5528  if (oldmsgs)
5529  *oldmsgs += tmpold;
5530  if (urgentmsgs)
5531  *urgentmsgs += tmpurgent;
5532  }
5533  }
5534  }
5535  return 0;
5536  }
5537 
5538  ast_copy_string(tmp, mailbox, sizeof(tmp));
5539 
5540  if ((context = strchr(tmp, '@')))
5541  *context++ = '\0';
5542  else
5543  context = "default";
5544 
5545  if (newmsgs)
5546  *newmsgs = __has_voicemail(context, tmp, "INBOX", 0);
5547  if (oldmsgs)
5548  *oldmsgs = __has_voicemail(context, tmp, "Old", 0);
5549  if (urgentmsgs)
5550  *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0);
5551 
5552  return 0;
5553 }
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
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 int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
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 4258 of file app_voicemail_imapstorage.c.

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

Referenced by inchar().

4259 {
4260  int l;
4261 
4262  if (bio->ateof)
4263  return 0;
4264 
4265  if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) {
4266  if (ferror(fi))
4267  return -1;
4268 
4269  bio->ateof = 1;
4270  return 0;
4271  }
4272 
4273  bio->iolen = l;
4274  bio->iocp = 0;
4275 
4276  return 1;
4277 }
unsigned char iobuf[BASEMAXINLINE]
#define BASEMAXINLINE
static int inchar ( struct baseio bio,
FILE *  fi 
)
static

utility used by base_encode()

Definition at line 4282 of file app_voicemail_imapstorage.c.

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

Referenced by base_encode().

4283 {
4284  if (bio->iocp>=bio->iolen) {
4285  if (!inbuf(bio, fi))
4286  return EOF;
4287  }
4288 
4289  return bio->iobuf[bio->iocp++];
4290 }
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 943 of file app_voicemail_imapstorage.c.

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

Referenced by load_module().

944 {
945  struct inprocess *i = obj, *j = arg;
946  if (strcmp(i->mailbox, j->mailbox)) {
947  return 0;
948  }
949  return !strcmp(i->context, j->context) ? CMP_MATCH : 0;
950 }
char * context
char mailbox[0]
static int inprocess_count ( const char *  context,
const char *  mailbox,
int  delta 
)
static

Definition at line 952 of file app_voicemail_imapstorage.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().

953 {
954  struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2);
955  arg->context = arg->mailbox + strlen(mailbox) + 1;
956  strcpy(arg->mailbox, mailbox); /* SAFE */
957  strcpy(arg->context, context); /* SAFE */
959  if ((i = ao2_find(inprocess_container, arg, 0))) {
960  int ret = ast_atomic_fetchadd_int(&i->count, delta);
962  ao2_ref(i, -1);
963  return ret;
964  }
965  if (delta < 0) {
966  ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n");
967  }
968  if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) {
970  return 0;
971  }
972  i->context = i->mailbox + strlen(mailbox) + 1;
973  strcpy(i->mailbox, mailbox); /* SAFE */
974  strcpy(i->context, context); /* SAFE */
975  i->count = delta;
978  ao2_ref(i, -1);
979  return 0;
980 }
#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 937 of file app_voicemail_imapstorage.c.

References inprocess::mailbox.

Referenced by load_module().

938 {
939  const struct inprocess *i = obj;
940  return atoi(i->mailbox);
941 }
char mailbox[0]
static int invent_message ( struct ast_channel chan,
char *  context,
char *  ext,
int  busy,
char *  ecodes 
)
static

Definition at line 5098 of file app_voicemail_imapstorage.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().

5099 {
5100  int res;
5101  char fn[PATH_MAX];
5102  char dest[PATH_MAX];
5103 
5104  snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext);
5105 
5106  if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) {
5107  ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn);
5108  return -1;
5109  }
5110 
5111  RETRIEVE(fn, -1, ext, context);
5112  if (ast_fileexists(fn, NULL, NULL) > 0) {
5113  res = ast_stream_and_wait(chan, fn, ecodes);
5114  if (res) {
5115  DISPOSE(fn, -1);
5116  return res;
5117  }
5118  } else {
5119  /* Dispose just in case */
5120  DISPOSE(fn, -1);
5121  res = ast_stream_and_wait(chan, "vm-theperson", ecodes);
5122  if (res)
5123  return res;
5124  res = ast_say_digit_str(chan, ext, ecodes, chan->language);
5125  if (res)
5126  return res;
5127  }
5128  res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes);
5129  return res;
5130 }
#define RETRIEVE(a, b, c, d)
#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
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
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 create_dirpath(char *dest, int len, const char *context, const char *ext, const char *folder)
basically mkdir -p $dest/$context/$ext/$folder
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
const ast_string_field language
Definition: channel.h:787
#define DISPOSE(a, b)
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 1379 of file app_voicemail_imapstorage.c.

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

Referenced by actual_load_config().

1380 {
1381  int i;
1382  char *local_key = ast_strdupa(key);
1383 
1384  for (i = 0; i < strlen(key); ++i) {
1385  if (!strchr(VALID_DTMF, *local_key)) {
1386  ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key);
1387  return 0;
1388  }
1389  local_key++;
1390  }
1391  return 1;
1392 }
#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
#define VALID_DTMF
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 4077 of file app_voicemail_imapstorage.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().

4078 {
4079  int x;
4080  unsigned char map[MAXMSGLIMIT] = "";
4081  DIR *msgdir;
4082  struct dirent *msgdirent;
4083  int msgdirint;
4084  char extension[4];
4085  int stopcount = 0;
4086 
4087  /* Reading the entire directory into a file map scales better than
4088  * doing a stat repeatedly on a predicted sequence. I suspect this
4089  * is partially due to stat(2) internally doing a readdir(2) itself to
4090  * find each file. */
4091  if (!(msgdir = opendir(dir))) {
4092  return -1;
4093  }
4094 
4095  while ((msgdirent = readdir(msgdir))) {
4096  if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) {
4097  map[msgdirint] = 1;
4098  stopcount++;
4099  ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount);
4100  }
4101  }
4102  closedir(msgdir);
4103 
4104  for (x = 0; x < vmu->maxmsg; x++) {
4105  if (map[x] == 1) {
4106  stopcount--;
4107  } else if (map[x] == 0 && !stopcount) {
4108  break;
4109  }
4110  }
4111 
4112  return x - 1;
4113 }
#define MAXMSGLIMIT
static int * map
Definition: misdn_config.c:434
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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 5634 of file app_voicemail_imapstorage.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().

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

11792 {
11793  struct ast_config *cfg, *ucfg;
11794  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
11795  int res;
11796 
11797  ast_unload_realtime("voicemail");
11798  ast_unload_realtime("voicemail_data");
11799 
11800  if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
11801  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
11802  return 0;
11803  } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
11804  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n");
11805  ucfg = NULL;
11806  }
11807  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11808  if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) {
11809  ast_config_destroy(ucfg);
11810  ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
11811  return 0;
11812  }
11813  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
11814  ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n");
11815  return 0;
11816  } else {
11817  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11818  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
11819  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n");
11820  ucfg = NULL;
11821  }
11822  }
11823 
11824  res = actual_load_config(reload, cfg, ucfg);
11825 
11826  ast_config_destroy(cfg);
11827  ast_config_destroy(ucfg);
11828 
11829  return res;
11830 }
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
Definition: config.c:2630
static int actual_load_config(int reload, struct ast_config *cfg, struct ast_config *ucfg)
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
#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
Structure used to handle boolean flags.
Definition: utils.h:200
#define ast_clear_flag(p, flag)
Definition: utils.h:77
static int reload(void)
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define VOICEMAIL_CONFIG
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int load_module ( void  )
static

Definition at line 13092 of file app_voicemail_imapstorage.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().

13093 {
13094  int res;
13095  my_umask = umask(0);
13096  umask(my_umask);
13097 
13099  return AST_MODULE_LOAD_DECLINE;
13100  }
13101 
13102  /* compute the location of the voicemail spool directory */
13103  snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
13104 
13105  if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) {
13106  ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n");
13107  }
13108 
13109  if ((res = load_config(0)))
13110  return res;
13111 
13119 #ifdef TEST_FRAMEWORK
13120  res |= AST_TEST_REGISTER(test_voicemail_vmsayname);
13121  res |= AST_TEST_REGISTER(test_voicemail_msgcount);
13122  res |= AST_TEST_REGISTER(test_voicemail_vmuser);
13123  res |= AST_TEST_REGISTER(test_voicemail_notify_endl);
13124  res |= AST_TEST_REGISTER(test_voicemail_load_config);
13125 #endif
13126 
13127  if (res)
13128  return res;
13129 
13132 
13134  ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL);
13135  ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL);
13136 
13137  return res;
13138 }
static struct ast_cli_entry cli_voicemail[]
static int inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int load_config(int reload)
static struct ast_custom_function mailbox_exists_acf
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
static int messagecount(const char *context, const char *mailbox, const char *folder)
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static int manager_list_voicemail_users(struct mansession *s, const struct message *m)
Manager list voicemail users command.
static int inprocess_cmp_fn(void *obj, void *arg, int flags)
static struct ast_taskprocessor * mwi_subscription_tps
static char VM_SPOOL_DIR[PATH_MAX]
static struct ast_data_entry vm_data_providers[]
Definition: config.h:68
static int my_umask
#define SENTINEL
Definition: compiler.h:75
#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 vmsayname_exec(struct ast_channel *chan, const char *data)
static int vmauthenticate(struct ast_channel *chan, const char *data)
static int inprocess_hash_fn(const void *obj, const int flags)
#define ast_data_register_multiple(data_entries, entries)
Definition: data.h:377
static char * app3
static char * app2
static int vm_exec(struct ast_channel *chan, const char *data)
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 * sayname_app
static int vm_execmain(struct ast_channel *chan, const char *data)
const char * ast_config_AST_SPOOL_DIR
Definition: asterisk.c:259
static char * app
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
static int vm_box_exists(struct ast_channel *chan, const char *data)
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
static int has_voicemail(const char *mailbox, const char *folder)
Determines if the given folder has messages.
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static char * app4
#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
static int sayname(struct ast_channel *chan, const char *mailbox, const char *context)
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 1660 of file app_voicemail_imapstorage.c.

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

1661 {
1662  return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder);
1663 }
const char * ext
Definition: http.c:112
static char VM_SPOOL_DIR[PATH_MAX]
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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 4575 of file app_voicemail_imapstorage.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().

4576 {
4577  char date[256];
4578  char host[MAXHOSTNAMELEN] = "";
4579  char who[256];
4580  char bound[256];
4581  char dur[256];
4582  struct ast_tm tm;
4583  char enc_cidnum[256] = "", enc_cidname[256] = "";
4584  struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
4585  char *greeting_attachment;
4586  char filename[256];
4587 
4588  if (!str1 || !str2) {
4589  ast_free(str1);
4590  ast_free(str2);
4591  return;
4592  }
4593 
4594  if (cidnum) {
4595  strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum));
4596  }
4597  if (cidname) {
4598  strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
4599  }
4600  gethostname(host, sizeof(host) - 1);
4601 
4602  if (strchr(srcemail, '@')) {
4603  ast_copy_string(who, srcemail, sizeof(who));
4604  } else {
4605  snprintf(who, sizeof(who), "%s@%s", srcemail, host);
4606  }
4607 
4608  greeting_attachment = strrchr(ast_strdupa(attach), '/');
4609  if (greeting_attachment) {
4610  *greeting_attachment++ = '\0';
4611  }
4612 
4613  snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
4614  ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
4615  fprintf(p, "Date: %s" ENDL, date);
4616 
4617  /* Set date format for voicemail mail */
4618  ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL));
4619 
4620  if (!ast_strlen_zero(fromstring)) {
4621  struct ast_channel *ast;
4622  if ((ast = ast_dummy_channel_alloc())) {
4623  char *ptr;
4624  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag);
4625  ast_str_substitute_variables(&str1, 0, ast, fromstring);
4626 
4627  if (check_mime(ast_str_buffer(str1))) {
4628  int first_line = 1;
4629  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3);
4630  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4631  *ptr = '\0';
4632  fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2));
4633  first_line = 0;
4634  /* Substring is smaller, so this will never grow */
4635  ast_str_set(&str2, 0, "%s", ptr + 1);
4636  }
4637  fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who);
4638  } else {
4639  fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who);
4640  }
4641  ast = ast_channel_unref(ast);
4642  } else {
4643  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4644  }
4645  } else {
4646  fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
4647  }
4648 
4649  if (check_mime(vmu->fullname)) {
4650  int first_line = 1;
4651  char *ptr;
4652  ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3);
4653  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4654  *ptr = '\0';
4655  fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2));
4656  first_line = 0;
4657  /* Substring is smaller, so this will never grow */
4658  ast_str_set(&str2, 0, "%s", ptr + 1);
4659  }
4660  fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email);
4661  } else {
4662  fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email);
4663  }
4664 
4666  char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject;
4667  struct ast_channel *ast;
4668  if ((ast = ast_dummy_channel_alloc())) {
4669  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
4670  ast_str_substitute_variables(&str1, 0, ast, e_subj);
4671  if (check_mime(ast_str_buffer(str1))) {
4672  int first_line = 1;
4673  char *ptr;
4674  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0);
4675  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4676  *ptr = '\0';
4677  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
4678  first_line = 0;
4679  /* Substring is smaller, so this will never grow */
4680  ast_str_set(&str2, 0, "%s", ptr + 1);
4681  }
4682  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
4683  } else {
4684  fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1));
4685  }
4686  ast = ast_channel_unref(ast);
4687  } else {
4688  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4689  }
4690  } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) {
4691  if (ast_strlen_zero(flag)) {
4692  fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
4693  } else {
4694  fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox);
4695  }
4696  } else {
4697  if (ast_strlen_zero(flag)) {
4698  fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox);
4699  } else {
4700  fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox);
4701  }
4702  }
4703 
4704  fprintf(p, "Message-ID: <Asterisk-%d-%u-%s-%d@%s>" ENDL, msgnum + 1,
4705  (unsigned int) ast_random(), mailbox, (int) getpid(), host);
4706  if (imap) {
4707  /* additional information needed for IMAP searching */
4708  fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1);
4709  /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */
4710  fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring);
4711  fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context);
4712 #ifdef IMAP_STORAGE
4713  fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox));
4714 #else
4715  fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox);
4716 #endif
4717  /* flag added for Urgent */
4718  fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag);
4719  fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority);
4720  fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name);
4721  fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum);
4722  fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname);
4723  fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration);
4724  if (!ast_strlen_zero(category)) {
4725  fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category);
4726  } else {
4727  fprintf(p, "X-Asterisk-VM-Category: " ENDL);
4728  }
4729  fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment);
4730  fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date);
4731  fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL));
4732  }
4733  if (!ast_strlen_zero(cidnum)) {
4734  fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum);
4735  }
4736  if (!ast_strlen_zero(cidname)) {
4737  fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname);
4738  }
4739  fprintf(p, "MIME-Version: 1.0" ENDL);
4740  if (attach_user_voicemail) {
4741  /* Something unique. */
4742  snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%u", msgnum + 1, mailbox,
4743  (int) getpid(), (unsigned int) ast_random());
4744 
4745  fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound);
4746  fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL);
4747  fprintf(p, "--%s" ENDL, bound);
4748  }
4749  fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset);
4750  if (emailbody || vmu->emailbody) {
4751  char* e_body = vmu->emailbody ? vmu->emailbody : emailbody;
4752  struct ast_channel *ast;
4753  if ((ast = ast_dummy_channel_alloc())) {
4754  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
4755  ast_str_substitute_variables(&str1, 0, ast, e_body);
4756 #ifdef IMAP_STORAGE
4757  {
4758  /* Convert body to native line terminators for IMAP backend */
4759  char *line = ast_str_buffer(str1), *next;
4760  do {
4761  /* Terminate line before outputting it to the file */
4762  if ((next = strchr(line, '\n'))) {
4763  *next++ = '\0';
4764  }
4765  fprintf(p, "%s" ENDL, line);
4766  line = next;
4767  } while (!ast_strlen_zero(line));
4768  }
4769 #else
4770  fprintf(p, "%s" ENDL, ast_str_buffer(str1));
4771 #endif
4772  ast = ast_channel_unref(ast);
4773  } else {
4774  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
4775  }
4776  } else if (msgnum > -1) {
4777  if (strcmp(vmu->mailbox, mailbox)) {
4778  /* Forwarded type */
4779  struct ast_config *msg_cfg;
4780  const char *v;
4781  int inttime;
4782  char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = "";
4783  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
4784  /* Retrieve info from VM attribute file */
4785  make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
4786  make_file(fromfile, sizeof(fromfile), fromdir, msgnum);
4787  if (strlen(fromfile) < sizeof(fromfile) - 5) {
4788  strcat(fromfile, ".txt");
4789  }
4790  if ((msg_cfg = ast_config_load(fromfile, config_flags)) && valid_config(msg_cfg)) {
4791  if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
4792  ast_copy_string(origcallerid, v, sizeof(origcallerid));
4793  }
4794 
4795  /* You might be tempted to do origdate, except that a) it's in the wrong
4796  * format, and b) it's missing for IMAP recordings. */
4797  if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) {
4798  struct timeval tv = { inttime, };
4799  struct ast_tm tm;
4800  ast_localtime(&tv, &tm, NULL);
4801  ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL));
4802  }
4803  fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded"
4804  " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL
4805  "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a"
4806  " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur,
4807  msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")),
4808  date, origcallerid, origdate);
4809  ast_config_destroy(msg_cfg);
4810  } else {
4811  goto plain_message;
4812  }
4813  } else {
4814 plain_message:
4815  fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a "
4816  "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL
4817  "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk"
4818  ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox,
4819  (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date);
4820  }
4821  } else {
4822  fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL
4823  "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date);
4824  }
4825 
4826  if (imap || attach_user_voicemail) {
4827  if (!ast_strlen_zero(attach2)) {
4828  snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format);
4829  ast_debug(5, "creating second attachment filename %s\n", filename);
4830  add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum);
4831  snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format);
4832  ast_debug(5, "creating attachment filename %s\n", filename);
4833  add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum);
4834  } else {
4835  snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format);
4836  ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename);
4837  add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum);
4838  }
4839  }
4840  ast_free(str1);
4841  ast_free(str2);
4842 }
static char emaildateformat[32]
Main Channel structure associated with a channel.
Definition: channel.h:742
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
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 priority
Definition: channel.h:841
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_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
static char * emailsubject
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1570
#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]
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
char * emailsubject
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 charset[32]
#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
char mailbox[AST_MAX_EXTENSION]
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
static char * emailbody
#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
char * emailbody
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)
const ast_string_field name
Definition: channel.h:787
#define VM_PBXSKIP
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
static struct ast_flags globalflags
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
Structure used to handle boolean flags.
Definition: utils.h:200
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.
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
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.
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
static int check_mime(const char *str)
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail sof...
static snd_pcm_format_t format
Definition: chan_alsa.c:93
char email[80]
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 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 ENDL
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
yylloc first_line
Definition: ast_expr2.c:1857
static char fromstring[100]
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 ...
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 1677 of file app_voicemail_imapstorage.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().

1678 {
1679  return snprintf(dest, len, "%s/msg%04d", dir, num);
1680 }
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 11622 of file app_voicemail_imapstorage.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().

11623 {
11624  struct ast_vm_user *vmu = NULL;
11625  const char *id = astman_get_header(m, "ActionID");
11626  char actionid[128] = "";
11627 
11628  if (!ast_strlen_zero(id))
11629  snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id);
11630 
11631  AST_LIST_LOCK(&users);
11632 
11633  if (AST_LIST_EMPTY(&users)) {
11634  astman_send_ack(s, m, "There are no voicemail users currently defined.");
11636  return RESULT_SUCCESS;
11637  }
11638 
11639  astman_send_ack(s, m, "Voicemail user list will follow");
11640 
11641  AST_LIST_TRAVERSE(&users, vmu, list) {
11642  char dirname[256];
11643 
11644 #ifdef IMAP_STORAGE
11645  int new, old;
11646  inboxcount(vmu->mailbox, &new, &old);
11647 #endif
11648 
11649  make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX");
11650  astman_append(s,
11651  "%s"
11652  "Event: VoicemailUserEntry\r\n"
11653  "VMContext: %s\r\n"
11654  "VoiceMailbox: %s\r\n"
11655  "Fullname: %s\r\n"
11656  "Email: %s\r\n"
11657  "Pager: %s\r\n"
11658  "ServerEmail: %s\r\n"
11659  "MailCommand: %s\r\n"
11660  "Language: %s\r\n"
11661  "TimeZone: %s\r\n"
11662  "Callback: %s\r\n"
11663  "Dialout: %s\r\n"
11664  "UniqueID: %s\r\n"
11665  "ExitContext: %s\r\n"
11666  "SayDurationMinimum: %d\r\n"
11667  "SayEnvelope: %s\r\n"
11668  "SayCID: %s\r\n"
11669  "AttachMessage: %s\r\n"
11670  "AttachmentFormat: %s\r\n"
11671  "DeleteMessage: %s\r\n"
11672  "VolumeGain: %.2f\r\n"
11673  "CanReview: %s\r\n"
11674  "CallOperator: %s\r\n"
11675  "MaxMessageCount: %d\r\n"
11676  "MaxMessageLength: %d\r\n"
11677  "NewMessageCount: %d\r\n"
11678 #ifdef IMAP_STORAGE
11679  "OldMessageCount: %d\r\n"
11680  "IMAPUser: %s\r\n"
11681 #endif
11682  "\r\n",
11683  actionid,
11684  vmu->context,
11685  vmu->mailbox,
11686  vmu->fullname,
11687  vmu->email,
11688  vmu->pager,
11690  mailcmd,
11691  vmu->language,
11692  vmu->zonetag,
11693  vmu->callback,
11694  vmu->dialout,
11695  vmu->uniqueid,
11696  vmu->exit,
11697  vmu->saydurationm,
11698  ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No",
11699  ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No",
11700  ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No",
11701  vmu->attachfmt,
11702  ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No",
11703  vmu->volgain,
11704  ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No",
11705  ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No",
11706  vmu->maxmsg,
11707  vmu->maxsecs,
11708 #ifdef IMAP_STORAGE
11709  new, old, vmu->imapuser
11710 #else
11711  count_messages(vmu, dirname)
11712 #endif
11713  );
11714  }
11715  astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid);
11716 
11718 
11719  return RESULT_SUCCESS;
11720 }
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
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...
#define VM_ATTACH
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
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static int count_messages(struct ast_vm_user *vmu, char *dir)
Find all .txt files - even if they are not in sequence from 0000.
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_REVIEW
char zonetag[80]
char pager[80]
char exit[80]
#define VM_ENVELOPE
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static char mailcmd[160]
static char serveremail[80]
char language[MAX_LANGUAGE]
static int inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs)
#define VM_SAYCID
char dialout[80]
char callback[80]
char serveremail[80]
#define RESULT_SUCCESS
Definition: cli.h:39
char email[80]
#define VM_DELETE
static void* mb_poll_thread ( void *  data)
static

Definition at line 11443 of file app_voicemail_imapstorage.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().

11444 {
11445  while (poll_thread_run) {
11446  struct timespec ts = { 0, };
11447  struct timeval wait;
11448 
11449  wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1));
11450  ts.tv_sec = wait.tv_sec;
11451  ts.tv_nsec = wait.tv_usec * 1000;
11452 
11456 
11457  if (!poll_thread_run)
11458  break;
11459 
11461  }
11462 
11463  return NULL;
11464 }
static unsigned char poll_thread_run
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 void poll_subscribed_mailboxes(void)
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
static unsigned int poll_freq
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static ast_mutex_t poll_lock
#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 1738 of file app_voicemail_imapstorage.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().

1739 {
1740 #ifdef IMAP_STORAGE
1741  if (vmu && id == 0) {
1742  return vmu->imapfolder;
1743  }
1744 #endif
1745  return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown";
1746 }
#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 5425 of file app_voicemail_imapstorage.c.

References __has_voicemail().

Referenced by load_module().

5426 {
5427  return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0));
5428 }
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
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 11466 of file app_voicemail_imapstorage.c.

References ast_free.

Referenced by handle_unsubscribe().

11467 {
11468  ast_free(mwi_sub);
11469 }
#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 11554 of file app_voicemail_imapstorage.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().

11555 {
11556  struct mwi_sub_task *mwist;
11557 
11558  if (ast_event_get_type(event) != AST_EVENT_SUB)
11559  return;
11560 
11562  return;
11563 
11564  if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) {
11565  ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n");
11566  return;
11567  }
11571 
11573  ast_free(mwist);
11574  }
11575 }
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
static int handle_subscribe(void *datap)
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
static struct ast_taskprocessor * mwi_subscription_tps
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
#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
Mailbox name.
Definition: event_defs.h:83
static void mwi_unsub_event_cb ( const struct ast_event event,
void *  userdata 
)
static

Definition at line 11528 of file app_voicemail_imapstorage.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().

11529 {
11530  uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid));
11531 
11532  if (!uniqueid) {
11533  ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n");
11534  return;
11535  }
11536 
11537  if (ast_event_get_type(event) != AST_EVENT_UNSUB) {
11538  ast_free(uniqueid);
11539  return;
11540  }
11541 
11543  ast_free(uniqueid);
11544  return;
11545  }
11546 
11548  *uniqueid = u;
11550  ast_free(uniqueid);
11551  }
11552 }
static int handle_unsubscribe(void *datap)
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 struct ast_taskprocessor * mwi_subscription_tps
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 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 7111 of file app_voicemail_imapstorage.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().

7112 {
7113  char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp;
7114  int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;
7115  const char *category;
7116  char *myserveremail = serveremail;
7117 
7118  ast_channel_lock(chan);
7119  if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) {
7120  category = ast_strdupa(category);
7121  }
7122  ast_channel_unlock(chan);
7123 
7124 #ifndef IMAP_STORAGE
7125  make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX");
7126 #else
7127  snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR);
7128 #endif
7129  make_file(fn, sizeof(fn), todir, msgnum);
7130  snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context);
7131 
7132  if (!ast_strlen_zero(vmu->attachfmt)) {
7133  if (strstr(fmt, vmu->attachfmt))
7134  fmt = vmu->attachfmt;
7135  else
7136  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);
7137  }
7138 
7139  /* Attach only the first format */
7140  fmt = ast_strdupa(fmt);
7141  stringp = fmt;
7142  strsep(&stringp, "|");
7143 
7144  if (!ast_strlen_zero(vmu->serveremail))
7145  myserveremail = vmu->serveremail;
7146 
7147  if (!ast_strlen_zero(vmu->email)) {
7148  int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH);
7149 
7150  if (attach_user_voicemail)
7151  RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context);
7152 
7153  /* XXX possible imap issue, should category be NULL XXX */
7154  sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag);
7155 
7156  if (attach_user_voicemail)
7157  DISPOSE(todir, msgnum);
7158  }
7159 
7160  if (!ast_strlen_zero(vmu->pager)) {
7161  sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag);
7162  }
7163 
7164  if (ast_test_flag(vmu, VM_DELETE))
7165  DELETE(todir, msgnum, fn, vmu);
7166 
7167  /* Leave voicemail for someone */
7168  if (ast_app_has_voicemail(ext_context, NULL))
7169  ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs);
7170 
7171  queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs);
7172 
7173  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);
7174  run_externnotify(vmu->context, vmu->mailbox, flag);
7175 
7176 #ifdef IMAP_STORAGE
7177  vm_delete(fn); /* Delete the file, but not the IMAP message */
7178  if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */
7179  vm_imap_delete(NULL, vms->curmsg, vmu);
7180  vms->newmessages--; /* Fix new message count */
7181  }
7182 #endif
7183 
7184  return 0;
7185 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
char * strsep(char **str, const char *delims)
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 void queue_mwi_event(const char *box, int urgent, int new, int old)
static void run_externnotify(char *context, char *extension, const char *flag)
#define VM_ATTACH
char attachfmt[20]
#define RETRIEVE(a, b, c, d)
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_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 char VM_SPOOL_DIR[PATH_MAX]
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
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)
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]
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 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 serveremail[80]
static int vm_delete(char *file)
Removes the voicemail sound and information file.
char serveremail[80]
#define DELETE(a, b, c, d)
char email[80]
int newmessages
static const char * mbox(struct ast_vm_user *vmu, int id)
#define DISPOSE(a, b)
#define VM_DELETE
static int ochar ( struct baseio bio,
int  c,
FILE *  so 
)
static

utility used by base_encode()

Definition at line 4295 of file app_voicemail_imapstorage.c.

References BASELINELEN, ENDL, and baseio::linelength.

Referenced by base_encode().

4296 {
4297  if (bio->linelength >= BASELINELEN) {
4298  if (fputs(ENDL, so) == EOF) {
4299  return -1;
4300  }
4301 
4302  bio->linelength = 0;
4303  }
4304 
4305  if (putc(((unsigned char) c), so) == EOF) {
4306  return -1;
4307  }
4308 
4309  bio->linelength++;
4310 
4311  return 1;
4312 }
#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 7959 of file app_voicemail_imapstorage.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().

7960 {
7961  int count_msg, last_msg;
7962 
7963  ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox));
7964 
7965  /* Rename the member vmbox HERE so that we don't try to return before
7966  * we know what's going on.
7967  */
7968  snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox);
7969 
7970  /* Faster to make the directory than to check if it exists. */
7971  create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox);
7972 
7973  /* traverses directory using readdir (or select query for ODBC) */
7974  count_msg = count_messages(vmu, vms->curdir);
7975  if (count_msg < 0) {
7976  return count_msg;
7977  } else {
7978  vms->lastmsg = count_msg - 1;
7979  }
7980 
7981  if (vm_allocate_dh(vms, vmu, count_msg)) {
7982  return -1;
7983  }
7984 
7985  /*
7986  The following test is needed in case sequencing gets messed up.
7987  There appears to be more than one way to mess up sequence, so
7988  we will not try to find all of the root causes--just fix it when
7989  detected.
7990  */
7991 
7992  if (vm_lock_path(vms->curdir)) {
7993  ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir);
7994  return ERROR_LOCK_PATH;
7995  }
7996 
7997  /* for local storage, checks directory for messages up to maxmsg limit */
7998  last_msg = last_message_index(vmu, vms->curdir);
7999  ast_unlock_path(vms->curdir);
8000 
8001  if (last_msg < -1) {
8002  return last_msg;
8003  } else if (vms->lastmsg != last_msg) {
8004  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);
8005  resequence_mailbox(vmu, vms->curdir, count_msg);
8006  }
8007 
8008  return 0;
8009 }
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
static int resequence_mailbox(struct ast_vm_user *vmu, char *dir, int stopcount)
char curdir[PATH_MAX]
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. ...
char vmbox[PATH_MAX]
#define AST_LOG_ERROR
Definition: logger.h:160
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 username[80]
char context[AST_MAX_CONTEXT]
#define ERROR_LOCK_PATH
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 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 vm_allocate_dh(struct vm_state *vms, struct ast_vm_user *vmu, int count_msg)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
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 curbox[80]
static const char * mbox(struct ast_vm_user *vmu, int id)
static int play_message ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
)
static

Definition at line 7733 of file app_voicemail_imapstorage.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().

7734 {
7735  int res = 0;
7736  char filename[256], *cid;
7737  const char *origtime, *context, *category, *duration, *flag;
7738  struct ast_config *msg_cfg;
7739  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
7740 
7741  vms->starting = 0;
7742  make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
7743  adsi_message(chan, vms);
7744  if (!vms->curmsg) {
7745  res = wait_file2(chan, vms, "vm-first"); /* "First" */
7746  } else if (vms->curmsg == vms->lastmsg) {
7747  res = wait_file2(chan, vms, "vm-last"); /* "last" */
7748  }
7749 
7750  snprintf(filename, sizeof(filename), "%s.txt", vms->fn);
7751  RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context);
7752  msg_cfg = ast_config_load(filename, config_flags);
7753  if (!valid_config(msg_cfg)) {
7754  ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
7755  return 0;
7756  }
7757  flag = ast_variable_retrieve(msg_cfg, "message", "flag");
7758 
7759  /* Play the word urgent if we are listening to urgent messages */
7760  if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) {
7761  res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */
7762  }
7763 
7764  if (!res) {
7765  /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */
7766  /* POLISH syntax */
7767  if (!strncasecmp(chan->language, "pl", 2)) {
7768  if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
7769  int ten, one;
7770  char nextmsg[256];
7771  ten = (vms->curmsg + 1) / 10;
7772  one = (vms->curmsg + 1) % 10;
7773 
7774  if (vms->curmsg < 20) {
7775  snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1);
7776  res = wait_file2(chan, vms, nextmsg);
7777  } else {
7778  snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10);
7779  res = wait_file2(chan, vms, nextmsg);
7780  if (one > 0) {
7781  if (!res) {
7782  snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one);
7783  res = wait_file2(chan, vms, nextmsg);
7784  }
7785  }
7786  }
7787  }
7788  if (!res)
7789  res = wait_file2(chan, vms, "vm-message");
7790  /* HEBREW syntax */
7791  } else if (!strncasecmp(chan->language, "he", 2)) {
7792  if (!vms->curmsg) {
7793  res = wait_file2(chan, vms, "vm-message");
7794  res = wait_file2(chan, vms, "vm-first");
7795  } else if (vms->curmsg == vms->lastmsg) {
7796  res = wait_file2(chan, vms, "vm-message");
7797  res = wait_file2(chan, vms, "vm-last");
7798  } else {
7799  res = wait_file2(chan, vms, "vm-message");
7800  res = wait_file2(chan, vms, "vm-number");
7801  res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
7802  }
7803  /* VIETNAMESE syntax */
7804  } else if (!strncasecmp(chan->language, "vi", 2)) {
7805  if (!vms->curmsg) {
7806  res = wait_file2(chan, vms, "vm-message");
7807  res = wait_file2(chan, vms, "vm-first");
7808  } else if (vms->curmsg == vms->lastmsg) {
7809  res = wait_file2(chan, vms, "vm-message");
7810  res = wait_file2(chan, vms, "vm-last");
7811  } else {
7812  res = wait_file2(chan, vms, "vm-message");
7813  res = wait_file2(chan, vms, "vm-number");
7814  res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f");
7815  }
7816  } else {
7817  if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */
7818  res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */
7819  } else { /* DEFAULT syntax */
7820  res = wait_file2(chan, vms, "vm-message");
7821  }
7822  if (vms->curmsg && (vms->curmsg != vms->lastmsg)) {
7823  if (!res) {
7824  ast_test_suite_event_notify("PLAYBACK", "Message: message number");
7825  res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL);
7826  }
7827  }
7828  }
7829  }
7830 
7831  if (!valid_config(msg_cfg)) {
7832  ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
7833  return 0;
7834  }
7835 
7836  if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) {
7837  ast_log(AST_LOG_WARNING, "No origtime?!\n");
7838  DISPOSE(vms->curdir, vms->curmsg);
7839  ast_config_destroy(msg_cfg);
7840  return 0;
7841  }
7842 
7843  cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid"));
7844  duration = ast_variable_retrieve(msg_cfg, "message", "duration");
7845  category = ast_variable_retrieve(msg_cfg, "message", "category");
7846 
7847  context = ast_variable_retrieve(msg_cfg, "message", "context");
7848  if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */
7849  context = ast_variable_retrieve(msg_cfg, "message", "macrocontext");
7850  if (!res) {
7851  res = play_message_category(chan, category);
7852  }
7853  if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) {
7854  res = play_message_datetime(chan, vmu, origtime, filename);
7855  }
7856  if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) {
7857  res = play_message_callerid(chan, vms, cid, context, 0);
7858  }
7859  if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) {
7860  res = play_message_duration(chan, vms, duration, vmu->saydurationm);
7861  }
7862  /* Allow pressing '1' to skip envelope / callerid */
7863  if (res == '1') {
7864  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
7865  res = 0;
7866  }
7867  ast_config_destroy(msg_cfg);
7868 
7869  if (!res) {
7870  make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg);
7871 #ifdef IMAP_STORAGE
7872  ast_mutex_lock(&vms->lock);
7873 #endif
7874  vms->heard[vms->curmsg] = 1;
7875 #ifdef IMAP_STORAGE
7876  ast_mutex_unlock(&vms->lock);
7877  /*IMAP storage stores any prepended message from a forward
7878  * as a separate file from the rest of the message
7879  */
7880  if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) {
7881  wait_file(chan, vms, vms->introfn);
7882  }
7883 #endif
7884  if ((res = wait_file(chan, vms, vms->fn)) < 0) {
7885  ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn);
7886  res = 0;
7887  }
7888  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res);
7889  }
7890  DISPOSE(vms->curdir, vms->curmsg);
7891  return res;
7892 }
static int play_message_duration(struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration)
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 play_message_datetime(struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename)
#define RETRIEVE(a, b, c, d)
#define AST_DIGIT_ANY
Definition: file.h:47
static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
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_test_flag(p, flag)
Definition: utils.h:63
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
char fn[PATH_MAX]
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
char curdir[PATH_MAX]
static void adsi_message(struct ast_channel *chan, struct vm_state *vms)
static int wait_file(struct ast_channel *chan, struct vm_state *vms, char *file)
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define VM_SAYDURATION
static int play_message_callerid(struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback)
#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
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
int * heard
#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
#define VM_ENVELOPE
Structure used to handle boolean flags.
Definition: utils.h:200
#define VM_SAYCID
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 int play_message_category(struct ast_channel *chan, const char *category)
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
#define DISPOSE(a, b)
static int play_message_callerid ( struct ast_channel chan,
struct vm_state vms,
char *  cid,
const char *  context,
int  callback 
)
static

Definition at line 7619 of file app_voicemail_imapstorage.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().

7620 {
7621  int res = 0;
7622  int i;
7623  char *callerid, *name;
7624  char prefile[PATH_MAX] = "";
7625 
7626 
7627  /* If voicemail cid is not enabled, or we didn't get cid or context from
7628  * the attribute file, leave now.
7629  *
7630  * TODO Still need to change this so that if this function is called by the
7631  * message envelope (and someone is explicitly requesting to hear the CID),
7632  * it does not check to see if CID is enabled in the config file.
7633  */
7634  if ((cid == NULL)||(context == NULL))
7635  return res;
7636 
7637  /* Strip off caller ID number from name */
7638  ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context);
7639  ast_callerid_parse(cid, &name, &callerid);
7640  if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) {
7641  /* Check for internal contexts and only */
7642  /* say extension when the call didn't come from an internal context in the list */
7643  for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){
7644  ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]);
7645  if ((strcmp(cidinternalcontexts[i], context) == 0))
7646  break;
7647  }
7648  if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */
7649  if (!res) {
7650  snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid);
7651  if (!ast_strlen_zero(prefile)) {
7652  /* See if we can find a recorded name for this person instead of their extension number */
7653  if (ast_fileexists(prefile, NULL, NULL) > 0) {
7654  ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid);
7655  if (!callback)
7656  res = wait_file2(chan, vms, "vm-from");
7657  res = ast_stream_and_wait(chan, prefile, "");
7658  } else {
7659  ast_verb(3, "Playing envelope info: message from '%s'\n", callerid);
7660  /* Say "from extension" as one saying to sound smoother */
7661  if (!callback)
7662  res = wait_file2(chan, vms, "vm-from-extension");
7663  res = ast_say_digit_str(chan, callerid, "", chan->language);
7664  }
7665  }
7666  }
7667  } else if (!res) {
7668  ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid);
7669  /* Since this is all nicely figured out, why not say "from phone number" in this case? */
7670  if (!callback)
7671  res = wait_file2(chan, vms, "vm-from-phonenumber");
7672  res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language);
7673  }
7674  } else {
7675  /* Number unknown */
7676  ast_debug(1, "VM-CID: From an unknown number\n");
7677  /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */
7678  res = wait_file2(chan, vms, "vm-unknown-caller");
7679  }
7680  return res;
7681 }
#define AST_DIGIT_ANY
Definition: file.h:47
static int wait_file2(struct ast_channel *chan, struct vm_state *vms, char *file)
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
static char VM_SPOOL_DIR[PATH_MAX]
#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 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
#define MAX_NUM_CID_CONTEXTS
static int play_message_category ( struct ast_channel chan,
const char *  category 
)
static

Definition at line 7530 of file app_voicemail_imapstorage.c.

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

Referenced by play_message().

7531 {
7532  int res = 0;
7533 
7534  if (!ast_strlen_zero(category))
7535  res = ast_play_and_wait(chan, category);
7536 
7537  if (res) {
7538  ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category);
7539  res = 0;
7540  }
7541 
7542  return res;
7543 }
#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 7545 of file app_voicemail_imapstorage.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().

7546 {
7547  int res = 0;
7548  struct vm_zone *the_zone = NULL;
7549  time_t t;
7550 
7551  if (ast_get_time_t(origtime, &t, 0, NULL)) {
7552  ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename);
7553  return 0;
7554  }
7555 
7556  /* Does this user have a timezone specified? */
7557  if (!ast_strlen_zero(vmu->zonetag)) {
7558  /* Find the zone in the list */
7559  struct vm_zone *z;
7560  AST_LIST_LOCK(&zones);
7561  AST_LIST_TRAVERSE(&zones, z, list) {
7562  if (!strcmp(z->name, vmu->zonetag)) {
7563  the_zone = z;
7564  break;
7565  }
7566  }
7568  }
7569 
7570 /* No internal variable parsing for now, so we'll comment it out for the time being */
7571 #if 0
7572  /* Set the DIFF_* variables */
7573  ast_localtime(&t, &time_now, NULL);
7574  tv_now = ast_tvnow();
7575  ast_localtime(&tv_now, &time_then, NULL);
7576 
7577  /* Day difference */
7578  if (time_now.tm_year == time_then.tm_year)
7579  snprintf(temp, sizeof(temp), "%d", time_now.tm_yday);
7580  else
7581  snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday));
7582  pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp);
7583 
7584  /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */
7585 #endif
7586  if (the_zone) {
7587  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone);
7588  } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
7589  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
7590  } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */
7591  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL);
7592  } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
7593  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);
7594  } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */
7595  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL);
7596  } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */
7597  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL);
7598  } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */
7599  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL);
7600  } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */
7601  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);
7602  } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */
7603  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL);
7604  } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */
7605  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL);
7606  } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */
7607  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);
7608  } else {
7609  res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL);
7610  }
7611 #if 0
7612  pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL);
7613 #endif
7614  return res;
7615 }
#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 7683 of file app_voicemail_imapstorage.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().

7684 {
7685  int res = 0;
7686  int durationm;
7687  int durations;
7688  /* Verify that we have a duration for the message */
7689  if (duration == NULL)
7690  return res;
7691 
7692  /* Convert from seconds to minutes */
7693  durations = atoi(duration);
7694  durationm = (durations / 60);
7695 
7696  ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm);
7697 
7698  if ((!res) && (durationm >= minduration)) {
7699  res = wait_file2(chan, vms, "vm-duration");
7700 
7701  /* POLISH syntax */
7702  if (!strncasecmp(chan->language, "pl", 2)) {
7703  div_t num = div(durationm, 10);
7704 
7705  if (durationm == 1) {
7706  res = ast_play_and_wait(chan, "digits/1z");
7707  res = res ? res : ast_play_and_wait(chan, "vm-minute-ta");
7708  } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
7709  if (num.rem == 2) {
7710  if (!num.quot) {
7711  res = ast_play_and_wait(chan, "digits/2-ie");
7712  } else {
7713  res = say_and_wait(chan, durationm - 2 , chan->language);
7714  res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
7715  }
7716  } else {
7717  res = say_and_wait(chan, durationm, chan->language);
7718  }
7719  res = res ? res : ast_play_and_wait(chan, "vm-minute-ty");
7720  } else {
7721  res = say_and_wait(chan, durationm, chan->language);
7722  res = res ? res : ast_play_and_wait(chan, "vm-minute-t");
7723  }
7724  /* DEFAULT syntax */
7725  } else {
7726  res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL);
7727  res = wait_file2(chan, vms, "vm-minutes");
7728  }
7729  }
7730  return res;
7731 }
#define AST_DIGIT_ANY
Definition: file.h:47
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)
#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
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 13405 of file app_voicemail_imapstorage.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().

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

Definition at line 11415 of file app_voicemail_imapstorage.c.

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

Referenced by handle_subscribe(), and poll_subscribed_mailboxes().

11416 {
11417  int new = 0, old = 0, urgent = 0;
11418 
11419  inboxcount2(mwi_sub->mailbox, &urgent, &new, &old);
11420 
11421  if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) {
11422  mwi_sub->old_urgent = urgent;
11423  mwi_sub->old_new = new;
11424  mwi_sub->old_old = old;
11425  queue_mwi_event(mwi_sub->mailbox, urgent, new, old);
11426  run_externnotify(NULL, mwi_sub->mailbox, NULL);
11427  }
11428 }
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 11430 of file app_voicemail_imapstorage.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().

11431 {
11432  struct mwi_sub *mwi_sub;
11433 
11435  AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {
11436  if (!ast_strlen_zero(mwi_sub->mailbox)) {
11437  poll_subscribed_mailbox(mwi_sub);
11438  }
11439  }
11441 }
#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 1022 of file app_voicemail_imapstorage.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().

1023 {
1026  if (saydurationminfo) {
1028  }
1029  ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
1030  ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout));
1031  ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit));
1032  ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag));
1033  ast_copy_string(vmu->locale, locale, sizeof(vmu->locale));
1034  if (vmminsecs) {
1035  vmu->minsecs = vmminsecs;
1036  }
1037  if (vmmaxsecs) {
1038  vmu->maxsecs = vmmaxsecs;
1039  }
1040  if (maxmsg) {
1041  vmu->maxmsg = maxmsg;
1042  }
1043  if (maxdeletedmsg) {
1045  }
1046  vmu->volgain = volgain;
1047  ast_free(vmu->emailsubject);
1048  vmu->emailsubject = NULL;
1049  ast_free(vmu->emailbody);
1050  vmu->emailbody = NULL;
1051 #ifdef IMAP_STORAGE
1052  ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder));
1053 #endif
1054 }
double volgain
static double volgain
static int saydurationminfo
static int maxdeletedmsg
static int passwordlocation
#define ast_copy_flags(dest, src, flagz)
Definition: utils.h:84
char locale[20]
char * emailsubject
int passwordlocation
char zonetag[80]
static char dialcontext[AST_MAX_CONTEXT]
static char callcontext[AST_MAX_CONTEXT]
char * emailbody
static int vmminsecs
char exit[80]
#define ast_free(a)
Definition: astmm.h:97
#define AST_FLAGS_ALL
Definition: utils.h:196
static struct ast_flags globalflags
static int maxmsg
static char locale[20]
static char zonetag[80]
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]
static int vmmaxsecs
static char exitcontext[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 4383 of file app_voicemail_imapstorage.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().

4384 {
4385  char callerid[256];
4386  char num[12];
4387  char fromdir[256], fromfile[256];
4388  struct ast_config *msg_cfg;
4389  const char *origcallerid, *origtime;
4390  char origcidname[80], origcidnum[80], origdate[80];
4391  int inttime;
4392  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
4393 
4394  /* Prepare variables for substitution in email body and subject */
4395  pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname);
4396  pbx_builtin_setvar_helper(ast, "VM_DUR", dur);
4397  snprintf(num, sizeof(num), "%d", msgnum);
4398  pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num);
4399  pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context);
4400  pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox);
4401  pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ?
4402  ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller");
4403  pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller"));
4404  pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller"));
4405  pbx_builtin_setvar_helper(ast, "VM_DATE", date);
4406  pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category");
4407  pbx_builtin_setvar_helper(ast, "VM_FLAG", flag);
4408 
4409  /* Retrieve info from VM attribute file */
4410  make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder);
4411  make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1);
4412  if (strlen(fromfile) < sizeof(fromfile) - 5) {
4413  strcat(fromfile, ".txt");
4414  }
4415  if (!(msg_cfg = ast_config_load(fromfile, config_flags)) || !(valid_config(msg_cfg))) {
4416  if (option_debug > 0) {
4417  ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile);
4418  }
4419  return;
4420  }
4421 
4422  if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) {
4423  pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid);
4424  ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum));
4425  pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname);
4426  pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum);
4427  }
4428 
4429  if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) {
4430  struct timeval tv = { inttime, };
4431  struct ast_tm tm;
4432  ast_localtime(&tv, &tm, NULL);
4433  ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL));
4434  pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate);
4435  }
4436  ast_config_destroy(msg_cfg);
4437 }
static char emaildateformat[32]
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
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_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1093
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 option_debug
Definition: asterisk.c:182
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
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
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
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
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 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 7074 of file app_voicemail_imapstorage.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().

7075 {
7076  struct ast_event *event;
7077  char *mailbox, *context;
7078 
7079  /* Strip off @default */
7080  context = mailbox = ast_strdupa(box);
7081  strsep(&context, "@");
7082  if (ast_strlen_zero(context))
7083  context = "default";
7084 
7085  if (!(event = ast_event_new(AST_EVENT_MWI,
7090  AST_EVENT_IE_END))) {
7091  return;
7092  }
7093 
7095 }
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 12521 of file app_voicemail_imapstorage.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().

12521  {
12522  struct ast_config *pwconf;
12523  struct ast_flags config_flags = { 0 };
12524 
12525  pwconf = ast_config_load(secretfn, config_flags);
12526  if (valid_config(pwconf)) {
12527  const char *val = ast_variable_retrieve(pwconf, "general", "password");
12528  if (val) {
12529  ast_copy_string(password, val, passwordlen);
12530  ast_config_destroy(pwconf);
12531  return;
12532  }
12533  ast_config_destroy(pwconf);
12534  }
12535  ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn);
12536 }
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
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
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
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 13052 of file app_voicemail_imapstorage.c.

References load_config().

13053 {
13054  return load_config(1);
13055 }
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 4053 of file app_voicemail_imapstorage.c.

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

4054 {
4055  char stxt[PATH_MAX];
4056  char dtxt[PATH_MAX];
4057  ast_filerename(sfn, dfn, NULL);
4058  snprintf(stxt, sizeof(stxt), "%s.txt", sfn);
4059  snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn);
4060  if (ast_check_realtime("voicemail_data")) {
4061  ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL);
4062  }
4063  rename(stxt, dtxt);
4064 }
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 6200 of file app_voicemail_imapstorage.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().

6201 {
6202  /* we know the actual number of messages, so stop process when number is hit */
6203 
6204  int x, dest;
6205  char sfn[PATH_MAX];
6206  char dfn[PATH_MAX];
6207 
6208  if (vm_lock_path(dir)) {
6209  return ERROR_LOCK_PATH;
6210  }
6211 
6212  for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) {
6213  make_file(sfn, sizeof(sfn), dir, x);
6214  if (EXISTS(dir, x, sfn, NULL)) {
6215 
6216  if (x != dest) {
6217  make_file(dfn, sizeof(dfn), dir, dest);
6218  RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn);
6219  }
6220 
6221  dest++;
6222  }
6223  }
6224  ast_unlock_path(dir);
6225 
6226  return dest;
6227 }
#define EXISTS(a, b, c, d)
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 ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
char mailbox[AST_MAX_EXTENSION]
char context[AST_MAX_CONTEXT]
#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...
#define RENAME(a, b, c, d, e, f, g, h)
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 1492 of file app_voicemail_imapstorage.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().

1493 {
1494  /* This function could be made to generate one from a database, too */
1495  struct ast_vm_user *cur;
1496  int res = -1;
1497  AST_LIST_LOCK(&users);
1498  AST_LIST_TRAVERSE(&users, cur, list) {
1499  if ((!context || !strcasecmp(context, cur->context)) &&
1500  (!strcasecmp(mailbox, cur->mailbox)))
1501  break;
1502  }
1503  if (cur) {
1504  ast_copy_string(cur->password, newpass, sizeof(cur->password));
1505  res = 0;
1506  }
1508  return res;
1509 }
#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 5568 of file app_voicemail_imapstorage.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().

5569 {
5570  char arguments[255];
5571  char ext_context[256] = "";
5572  int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0;
5573  struct ast_smdi_mwi_message *mwi_msg;
5574 
5575  if (!ast_strlen_zero(context))
5576  snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context);
5577  else
5578  ast_copy_string(ext_context, extension, sizeof(ext_context));
5579 
5580  if (smdi_iface) {
5581  if (ast_app_has_voicemail(ext_context, NULL))
5583  else
5585 
5587  ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension);
5588  if (!strncmp(mwi_msg->cause, "INV", 3))
5589  ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st);
5590  else if (!strncmp(mwi_msg->cause, "BLK", 3))
5591  ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st);
5592  ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause);
5594  } else {
5595  ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension);
5596  }
5597  }
5598 
5599  if (!ast_strlen_zero(externnotify)) {
5600  if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) {
5601  ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
5602  } else {
5603  snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &",
5604  externnotify, S_OR(context, "\"\""),
5605  extension, newvoicemails,
5606  oldvoicemails, urgentvoicemails);
5607  ast_debug(1, "Executing %s\n", arguments);
5608  ast_safe_system(arguments);
5609  }
5610  }
5611 }
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
#define SMDI_MWI_WAIT_TIMEOUT
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
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
#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
static char externnotify[160]
void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg)
ast_smdi_mwi_message destructor.
Definition: res_smdi.c:829
static struct ast_smdi_interface * smdi_iface
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 6237 of file app_voicemail_imapstorage.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().

6238 {
6239 #ifdef IMAP_STORAGE
6240  /* we must use mbox(x) folder names, and copy the message there */
6241  /* simple. huh? */
6242  char sequence[10];
6243  char mailbox[256];
6244  int res;
6245 
6246  /* get the real IMAP message number for this message */
6247  snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
6248 
6249  ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box));
6250  ast_mutex_lock(&vms->lock);
6251  /* if save to Old folder, put in INBOX as read */
6252  if (box == OLD_FOLDER) {
6253  mail_setflag(vms->mailstream, sequence, "\\Seen");
6254  mail_clearflag(vms->mailstream, sequence, "\\Unseen");
6255  } else if (box == NEW_FOLDER) {
6256  mail_setflag(vms->mailstream, sequence, "\\Unseen");
6257  mail_clearflag(vms->mailstream, sequence, "\\Seen");
6258  }
6259  if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) {
6260  ast_mutex_unlock(&vms->lock);
6261  return 0;
6262  }
6263  /* Create the folder if it don't exist */
6264  imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */
6265  ast_debug(5, "Checking if folder exists: %s\n", mailbox);
6266  if (mail_create(vms->mailstream, mailbox) == NIL)
6267  ast_debug(5, "Folder exists.\n");
6268  else
6269  ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box));
6270  res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box));
6271  ast_mutex_unlock(&vms->lock);
6272  return res;
6273 #else
6274  char *dir = vms->curdir;
6275  char *username = vms->username;
6276  char *context = vmu->context;
6277  char sfn[PATH_MAX];
6278  char dfn[PATH_MAX];
6279  char ddir[PATH_MAX];
6280  const char *dbox = mbox(vmu, box);
6281  int x, i;
6282  create_dirpath(ddir, sizeof(ddir), context, username, dbox);
6283 
6284  if (vm_lock_path(ddir))
6285  return ERROR_LOCK_PATH;
6286 
6287  x = last_message_index(vmu, ddir) + 1;
6288 
6289  if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/
6290  x--;
6291  for (i = 1; i <= x; i++) {
6292  /* Push files down a "slot". The oldest file (msg0000) will be deleted. */
6293  make_file(sfn, sizeof(sfn), ddir, i);
6294  make_file(dfn, sizeof(dfn), ddir, i - 1);
6295  if (EXISTS(ddir, i, sfn, NULL)) {
6296  RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn);
6297  } else
6298  break;
6299  }
6300  } else {
6301  if (x >= vmu->maxmsg) {
6302  ast_unlock_path(ddir);
6303  return -1;
6304  }
6305  }
6306  make_file(sfn, sizeof(sfn), dir, msg);
6307  make_file(dfn, sizeof(dfn), ddir, x);
6308  if (strcmp(sfn, dfn)) {
6309  COPY(dir, msg, ddir, x, username, context, sfn, dfn);
6310  }
6311  ast_unlock_path(ddir);
6312 #endif
6313  return 0;
6314 }
#define EXISTS(a, b, c, d)
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 ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
char curdir[PATH_MAX]
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 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
char mailbox[AST_MAX_EXTENSION]
char username[80]
char context[AST_MAX_CONTEXT]
#define ERROR_LOCK_PATH
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 COPY(a, b, c, d, e, f, g, h)
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)
basically mkdir -p $dest/$context/$ext/$folder
char curbox[80]
#define RENAME(a, b, c, d, e, f, g, h)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static const char * mbox(struct ast_vm_user *vmu, int id)
#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 6230 of file app_voicemail_imapstorage.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().

6231 {
6232  int d;
6233  d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL);
6234  return d;
6235 }
#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 12507 of file app_voicemail_imapstorage.c.

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

Referenced by load_module(), and vmsayname_exec().

12508 {
12509  int res = -1;
12510  char dir[PATH_MAX];
12511  snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox);
12512  ast_debug(2, "About to try retrieving name file %s\n", dir);
12513  RETRIEVE(dir, -1, mailbox, context);
12514  if (ast_fileexists(dir, NULL, NULL)) {
12515  res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY);
12516  }
12517  DISPOSE(dir, -1);
12518  return res;
12519 }
#define RETRIEVE(a, b, c, d)
#define AST_DIGIT_ANY
Definition: file.h:47
static char VM_SPOOL_DIR[PATH_MAX]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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 context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
#define DISPOSE(a, b)
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 4898 of file app_voicemail_imapstorage.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().

4899 {
4900  FILE *p = NULL;
4901  char tmp[80] = "/tmp/astmail-XXXXXX";
4902  char tmp2[256];
4903  char *stringp;
4904 
4905  if (vmu && ast_strlen_zero(vmu->email)) {
4906  ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox);
4907  return(0);
4908  }
4909 
4910  /* Mail only the first format */
4912  stringp = format;
4913  strsep(&stringp, "|");
4914 
4915  if (!strcmp(format, "wav49"))
4916  format = "WAV";
4917  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));
4918  /* Make a temporary file instead of piping directly to sendmail, in case the mail
4919  command hangs */
4920  if ((p = vm_mkftemp(tmp)) == NULL) {
4921  ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
4922  return -1;
4923  } else {
4924  make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag);
4925  fclose(p);
4926  snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
4927  ast_safe_system(tmp2);
4928  ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd);
4929  }
4930  return 0;
4931 }
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.
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 VM_ATTACH
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define AST_LOG_WARNING
Definition: logger.h:149
static FILE * vm_mkftemp(char *template)
#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]
#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 struct ast_flags globalflags
static char mailcmd[160]
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 char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
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 4933 of file app_voicemail_imapstorage.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().

4934 {
4935  char enc_cidnum[256], enc_cidname[256];
4936  char date[256];
4937  char host[MAXHOSTNAMELEN] = "";
4938  char who[256];
4939  char dur[PATH_MAX];
4940  char tmp[80] = "/tmp/astmail-XXXXXX";
4941  char tmp2[PATH_MAX];
4942  struct ast_tm tm;
4943  FILE *p;
4944  struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
4945 
4946  if (!str1 || !str2) {
4947  ast_free(str1);
4948  ast_free(str2);
4949  return -1;
4950  }
4951 
4952  if (cidnum) {
4953  strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum));
4954  }
4955  if (cidname) {
4956  strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname));
4957  }
4958 
4959  if ((p = vm_mkftemp(tmp)) == NULL) {
4960  ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd);
4961  ast_free(str1);
4962  ast_free(str2);
4963  return -1;
4964  }
4965  gethostname(host, sizeof(host)-1);
4966  if (strchr(srcemail, '@')) {
4967  ast_copy_string(who, srcemail, sizeof(who));
4968  } else {
4969  snprintf(who, sizeof(who), "%s@%s", srcemail, host);
4970  }
4971  snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60);
4972  ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm));
4973  fprintf(p, "Date: %s\n", date);
4974 
4975  /* Reformat for custom pager format */
4976  ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL));
4977 
4979  struct ast_channel *ast;
4980  if ((ast = ast_dummy_channel_alloc())) {
4981  char *ptr;
4982  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag);
4984 
4985  if (check_mime(ast_str_buffer(str1))) {
4986  int first_line = 1;
4987  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3);
4988  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
4989  *ptr = '\0';
4990  fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2));
4991  first_line = 0;
4992  /* Substring is smaller, so this will never grow */
4993  ast_str_set(&str2, 0, "%s", ptr + 1);
4994  }
4995  fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who);
4996  } else {
4997  fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who);
4998  }
4999  ast = ast_channel_unref(ast);
5000  } else {
5001  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
5002  }
5003  } else {
5004  fprintf(p, "From: Asterisk PBX <%s>" ENDL, who);
5005  }
5006 
5007  if (check_mime(vmu->fullname)) {
5008  int first_line = 1;
5009  char *ptr;
5010  ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3);
5011  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
5012  *ptr = '\0';
5013  fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2));
5014  first_line = 0;
5015  /* Substring is smaller, so this will never grow */
5016  ast_str_set(&str2, 0, "%s", ptr + 1);
5017  }
5018  fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager);
5019  } else {
5020  fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager);
5021  }
5022 
5023  if (!ast_strlen_zero(pagersubject)) {
5024  struct ast_channel *ast;
5025  if ((ast = ast_dummy_channel_alloc())) {
5026  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
5028  if (check_mime(ast_str_buffer(str1))) {
5029  int first_line = 1;
5030  char *ptr;
5031  ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0);
5032  while ((ptr = strchr(ast_str_buffer(str2), ' '))) {
5033  *ptr = '\0';
5034  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
5035  first_line = 0;
5036  /* Substring is smaller, so this will never grow */
5037  ast_str_set(&str2, 0, "%s", ptr + 1);
5038  }
5039  fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2));
5040  } else {
5041  fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1));
5042  }
5043  ast = ast_channel_unref(ast);
5044  } else {
5045  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
5046  }
5047  } else {
5048  if (ast_strlen_zero(flag)) {
5049  fprintf(p, "Subject: New VM\n\n");
5050  } else {
5051  fprintf(p, "Subject: New %s VM\n\n", flag);
5052  }
5053  }
5054 
5055  if (pagerbody) {
5056  struct ast_channel *ast;
5057  if ((ast = ast_dummy_channel_alloc())) {
5058  prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag);
5059  ast_str_substitute_variables(&str1, 0, ast, pagerbody);
5060  fprintf(p, "%s" ENDL, ast_str_buffer(str1));
5061  ast = ast_channel_unref(ast);
5062  } else {
5063  ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n");
5064  }
5065  } else {
5066  fprintf(p, "New %s long %s msg in box %s\n"
5067  "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date);
5068  }
5069 
5070  fclose(p);
5071  snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp);
5072  ast_safe_system(tmp2);
5073  ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd);
5074  ast_free(str1);
5075  ast_free(str2);
5076  return 0;
5077 }
Main Channel structure associated with a channel.
Definition: channel.h:742
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
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
static FILE * vm_mkftemp(char *template)
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define MAXHOSTNAMELEN
Definition: network.h:69
static char * pagersubject
char locale[20]
static char pagerdateformat[32]
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 force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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 char pagerfromstring[100]
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)
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_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2351
static char mailcmd[160]
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.
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 context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
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.
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
static int check_mime(const char *str)
Check if the string would need encoding within the MIME standard, to avoid confusing certain mail sof...
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 ENDL
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
yylloc first_line
Definition: ast_expr2.c:1857
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 ...
static char* show_users_realtime ( int  fd,
const char *  context 
)
static

Definition at line 11072 of file app_voicemail_imapstorage.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().

11073 {
11074  struct ast_config *cfg;
11075  const char *cat = NULL;
11076 
11077  if (!(cfg = ast_load_realtime_multientry("voicemail",
11078  "context", context, SENTINEL))) {
11079  return CLI_FAILURE;
11080  }
11081 
11082  ast_cli(fd,
11083  "\n"
11084  "=============================================================\n"
11085  "=== Configured Voicemail Users ==============================\n"
11086  "=============================================================\n"
11087  "===\n");
11088 
11089  while ((cat = ast_category_browse(cfg, cat))) {
11090  struct ast_variable *var = NULL;
11091  ast_cli(fd,
11092  "=== Mailbox ...\n"
11093  "===\n");
11094  for (var = ast_variable_browse(cfg, cat); var; var = var->next)
11095  ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value);
11096  ast_cli(fd,
11097  "===\n"
11098  "=== ---------------------------------------------------------\n"
11099  "===\n");
11100  }
11101 
11102  ast_cli(fd,
11103  "=============================================================\n"
11104  "\n");
11105 
11106  ast_config_destroy(cfg);
11107 
11108  return CLI_SUCCESS;
11109 }
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 11577 of file app_voicemail_imapstorage.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().

11578 {
11579  int errcode;
11580  mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL,
11583 
11584  mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL,
11587 
11588  if (mwi_sub_sub)
11590 
11591  poll_thread_run = 1;
11592 
11593  if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) {
11594  ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode));
11595  }
11596 }
static struct ast_event_sub * mwi_unsub_sub
static unsigned char poll_thread_run
void ast_event_report_subs(const struct ast_event_sub *sub)
Report current subscriptions to a subscription subscriber.
Definition: event.c:701
static void * mb_poll_thread(void *data)
static void mwi_unsub_event_cb(const struct ast_event *event, void *userdata)
static pthread_t poll_thread
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
static struct ast_event_sub * mwi_sub_sub
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_pthread_create(a, b, c, d)
Definition: utils.h:418
static void mwi_sub_event_cb(const struct ast_event *event, void *userdata)
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 stop_poll_thread ( void  )
static

Definition at line 11598 of file app_voicemail_imapstorage.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().

11599 {
11600  poll_thread_run = 0;
11601 
11602  if (mwi_sub_sub) {
11604  mwi_sub_sub = NULL;
11605  }
11606 
11607  if (mwi_unsub_sub) {
11609  mwi_unsub_sub = NULL;
11610  }
11611 
11615 
11616  pthread_join(poll_thread, NULL);
11617 
11619 }
static struct ast_event_sub * mwi_unsub_sub
static unsigned char poll_thread_run
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
static ast_cond_t poll_cond
#define AST_PTHREADT_NULL
Definition: lock.h:65
static pthread_t poll_thread
static struct ast_event_sub * mwi_sub_sub
static ast_mutex_t poll_lock
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 992 of file app_voicemail_imapstorage.c.

References input().

Referenced by make_email_file(), and sendpage().

993 {
994  char *bufptr = buf;
995  for (; *input; input++) {
996  if (*input < 32) {
997  continue;
998  }
999  *bufptr++ = *input;
1000  if (bufptr == buf + buflen - 1) {
1001  break;
1002  }
1003  }
1004  *bufptr = '\0';
1005  return buf;
1006 }
static int input(yyscan_t yyscanner)
Definition: ast_expr2f.c:1575
static const char * substitute_escapes ( const char *  value)
static

Definition at line 11744 of file app_voicemail_imapstorage.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().

11745 {
11746  char *current;
11747 
11748  /* Add 16 for fudge factor */
11749  struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16);
11750 
11751  ast_str_reset(str);
11752 
11753  /* Substitute strings \r, \n, and \t into the appropriate characters */
11754  for (current = (char *) value; *current; current++) {
11755  if (*current == '\\') {
11756  current++;
11757  if (!*current) {
11758  ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n");
11759  break;
11760  }
11761  switch (*current) {
11762  case '\\':
11763  ast_str_append(&str, 0, "\\");
11764  break;
11765  case 'r':
11766  ast_str_append(&str, 0, "\r");
11767  break;
11768  case 'n':
11769 #ifdef IMAP_STORAGE
11770  if (!str->used || str->str[str->used - 1] != '\r') {
11771  ast_str_append(&str, 0, "\r");
11772  }
11773 #endif
11774  ast_str_append(&str, 0, "\n");
11775  break;
11776  case 't':
11777  ast_str_append(&str, 0, "\t");
11778  break;
11779  default:
11780  ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current);
11781  break;
11782  }
11783  } else {
11784  ast_str_append(&str, 0, "%c", *current);
11785  }
11786  }
11787 
11788  return ast_str_buffer(str);
11789 }
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 13057 of file app_voicemail_imapstorage.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().

13058 {
13059  int res;
13060 
13067  res |= ast_manager_unregister("VoicemailUsersList");
13068  res |= ast_data_unregister(NULL);
13069 #ifdef TEST_FRAMEWORK
13070  res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname);
13071  res |= AST_TEST_UNREGISTER(test_voicemail_msgcount);
13072  res |= AST_TEST_UNREGISTER(test_voicemail_vmuser);
13073  res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl);
13074  res |= AST_TEST_UNREGISTER(test_voicemail_load_config);
13075 #endif
13079 
13081  stop_poll_thread();
13082 
13084  ast_unload_realtime("voicemail");
13085  ast_unload_realtime("voicemail_data");
13086 
13087  free_vm_users();
13088  free_vm_zones();
13089  return res;
13090 }
static struct ast_cli_entry cli_voicemail[]
#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
static void free_vm_users(void)
Free the users structure.
static struct ast_custom_function mailbox_exists_acf
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static struct ast_taskprocessor * mwi_subscription_tps
static void stop_poll_thread(void)
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
#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 pthread_t poll_thread
static char * app3
static char * app2
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static char * sayname_app
static char * app
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
static void free_vm_zones(void)
Free the zones structure.
static char * app4
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 1514 of file app_voicemail_imapstorage.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().

1515 {
1516  return cfg && cfg != CONFIG_STATUS_FILEINVALID;
1517 }
#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 1775 of file app_voicemail_imapstorage.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().

1775  {
1776 
1777  int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg);
1778 
1779  /* remove old allocation */
1780  if (vms->deleted) {
1781  ast_free(vms->deleted);
1782  vms->deleted = NULL;
1783  }
1784  if (vms->heard) {
1785  ast_free(vms->heard);
1786  vms->heard = NULL;
1787  }
1788  vms->dh_arraysize = 0;
1789 
1790  if (arraysize > 0) {
1791  if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) {
1792  return -1;
1793  }
1794  if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) {
1795  ast_free(vms->deleted);
1796  vms->deleted = NULL;
1797  return -1;
1798  }
1799  vms->dh_arraysize = arraysize;
1800  }
1801 
1802  return 0;
1803 }
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 9752 of file app_voicemail_imapstorage.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().

9755 {
9756  int useadsi = 0, valid = 0, logretries = 0;
9757  char password[AST_MAX_EXTENSION]="", *passptr;
9758  struct ast_vm_user vmus, *vmu = NULL;
9759 
9760  /* If ADSI is supported, setup login screen */
9761  adsi_begin(chan, &useadsi);
9762  if (!skipuser && useadsi)
9763  adsi_login(chan);
9764  if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
9765  ast_log(AST_LOG_WARNING, "Couldn't stream login file\n");
9766  return -1;
9767  }
9768 
9769  /* Authenticate them and get their mailbox/password */
9770 
9771  while (!valid && (logretries < max_logins)) {
9772  /* Prompt for, and read in the username */
9773  if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
9774  ast_log(AST_LOG_WARNING, "Couldn't read username\n");
9775  return -1;
9776  }
9777  if (ast_strlen_zero(mailbox)) {
9778  if (chan->caller.id.number.valid && chan->caller.id.number.str) {
9779  ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size);
9780  } else {
9781  ast_verb(3, "Username not entered\n");
9782  return -1;
9783  }
9784  } else if (mailbox[0] == '*') {
9785  /* user entered '*' */
9786  ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n");
9787  if (ast_exists_extension(chan, chan->context, "a", 1,
9788  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
9789  return -1;
9790  }
9791  ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n");
9792  mailbox[0] = '\0';
9793  }
9794 
9795  if (useadsi)
9796  adsi_password(chan);
9797 
9798  if (!ast_strlen_zero(prefix)) {
9799  char fullusername[80] = "";
9800  ast_copy_string(fullusername, prefix, sizeof(fullusername));
9801  strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
9802  ast_copy_string(mailbox, fullusername, mailbox_size);
9803  }
9804 
9805  ast_debug(1, "Before find user for mailbox %s\n", mailbox);
9806  vmu = find_user(&vmus, context, mailbox);
9807  if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
9808  /* saved password is blank, so don't bother asking */
9809  password[0] = '\0';
9810  } else {
9811  if (ast_streamfile(chan, vm_password, chan->language)) {
9812  ast_log(AST_LOG_WARNING, "Unable to stream password file\n");
9813  return -1;
9814  }
9815  if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
9816  ast_log(AST_LOG_WARNING, "Unable to read password\n");
9817  return -1;
9818  } else if (password[0] == '*') {
9819  /* user entered '*' */
9820  ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n");
9821  if (ast_exists_extension(chan, chan->context, "a", 1,
9822  S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
9823  mailbox[0] = '*';
9824  return -1;
9825  }
9826  ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n");
9827  mailbox[0] = '\0';
9828  /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */
9829  vmu = NULL;
9830  }
9831  }
9832 
9833  if (vmu) {
9834  passptr = vmu->password;
9835  if (passptr[0] == '-') passptr++;
9836  }
9837  if (vmu && !strcmp(passptr, password))
9838  valid++;
9839  else {
9840  ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default");
9841  if (!ast_strlen_zero(prefix))
9842  mailbox[0] = '\0';
9843  }
9844  logretries++;
9845  if (!valid) {
9846  if (skipuser || logretries >= max_logins) {
9847  if (ast_streamfile(chan, "vm-incorrect", chan->language)) {
9848  ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n");
9849  return -1;
9850  }
9851  } else {
9852  if (useadsi)
9853  adsi_login(chan);
9854  if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) {
9855  ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n");
9856  return -1;
9857  }
9858  }
9859  if (ast_waitstream(chan, "")) /* Channel is hung up */
9860  return -1;
9861  }
9862  }
9863  if (!valid && (logretries >= max_logins)) {
9864  ast_stopstream(chan);
9865  ast_play_and_wait(chan, "vm-goodbye");
9866  return -1;
9867  }
9868  if (vmu && !skipuser) {
9869  memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
9870  }
9871  return 0;
9872 }
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Definition: file.c:946
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define AST_LOG_WARNING
Definition: logger.h:149
#define ast_verb(level,...)
Definition: logger.h:243
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
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.
static void adsi_login(struct ast_channel *chan)
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
static void adsi_begin(struct ast_channel *chan, int *useadsi)
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_password(struct ast_channel *chan)
static char vm_password[80]
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 10967 of file app_voicemail_imapstorage.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().

10968 {
10969  struct ast_vm_user svm;
10970  char *context, *box;
10972  AST_APP_ARG(mbox);
10973  AST_APP_ARG(options);
10974  );
10975  static int dep_warning = 0;
10976 
10977  if (ast_strlen_zero(data)) {
10978  ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n");
10979  return -1;
10980  }
10981 
10982  if (!dep_warning) {
10983  dep_warning = 1;
10984  ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data);
10985  }
10986 
10987  box = ast_strdupa(data);
10988 
10990 
10991  if (args.options) {
10992  }
10993 
10994  if ((context = strchr(args.mbox, '@'))) {
10995  *context = '\0';
10996  context++;
10997  }
10998 
10999  if (find_user(&svm, context, args.mbox)) {
11000  pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS");
11001  } else
11002  pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED");
11003 
11004  return 0;
11005 }
#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
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_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
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 const char * mbox(struct ast_vm_user *vmu, int id)
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 9734 of file app_voicemail_imapstorage.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().

9735 {
9736  if (!strncasecmp(chan->language, "es", 2) ||
9737  !strncasecmp(chan->language, "it", 2) ||
9738  !strncasecmp(chan->language, "pt", 2) ||
9739  !strncasecmp(chan->language, "gr", 2)) { /* SPANISH, ITALIAN, PORTUGUESE or GREEK */
9740  return vm_browse_messages_latin(chan, vms, vmu);
9741  } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */
9742  return vm_browse_messages_he(chan, vms, vmu);
9743  } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */
9744  return vm_browse_messages_vi(chan, vms, vmu);
9745  } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */
9746  return vm_browse_messages_zh(chan, vms, vmu);
9747  } else { /* Default to English syntax */
9748  return vm_browse_messages_en(chan, vms, vmu);
9749  }
9750 }
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_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_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.
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_he(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
const ast_string_field language
Definition: channel.h:787
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 9615 of file app_voicemail_imapstorage.c.

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

Referenced by vm_browse_messages().

9616 {
9617  int cmd = 0;
9618 
9619  if (vms->lastmsg > -1) {
9620  cmd = play_message(chan, vmu, vms);
9621  } else {
9622  cmd = ast_play_and_wait(chan, "vm-youhave");
9623  if (!cmd)
9624  cmd = ast_play_and_wait(chan, "vm-no");
9625  if (!cmd) {
9626  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9627  cmd = ast_play_and_wait(chan, vms->fn);
9628  }
9629  if (!cmd)
9630  cmd = ast_play_and_wait(chan, "vm-messages");
9631  }
9632  return cmd;
9633 }
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
char fn[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_he ( struct ast_channel chan,
struct vm_state vms,
struct ast_vm_user vmu 
)
static

Definition at line 9591 of file app_voicemail_imapstorage.c.

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

Referenced by vm_browse_messages().

9592 {
9593  int cmd = 0;
9594 
9595  if (vms->lastmsg > -1) {
9596  cmd = play_message(chan, vmu, vms);
9597  } else {
9598  if (!strcasecmp(vms->fn, "INBOX")) {
9599  cmd = ast_play_and_wait(chan, "vm-nonewmessages");
9600  } else {
9601  cmd = ast_play_and_wait(chan, "vm-nomessages");
9602  }
9603  }
9604  return cmd;
9605 }
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
char fn[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_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 9644 of file app_voicemail_imapstorage.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().

9645 {
9646  int cmd;
9647 
9648  if (vms->lastmsg > -1) {
9649  cmd = play_message(chan, vmu, vms);
9650  } else {
9651  cmd = ast_play_and_wait(chan, "vm-youhaveno");
9652  if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){
9653  if (!cmd) {
9654  snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox);
9655  cmd = ast_play_and_wait(chan, vms->fn);
9656  }
9657  if (!cmd)
9658  cmd = ast_play_and_wait(chan, "vm-messages");
9659  } else {
9660  if (!cmd)
9661  cmd = ast_play_and_wait(chan, "vm-messages");
9662  if (!cmd) {
9663  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9664  cmd = ast_play_and_wait(chan, vms->fn);
9665  }
9666  }
9667  }
9668  return cmd;
9669 }
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
char fn[PATH_MAX]
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 9707 of file app_voicemail_imapstorage.c.

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

Referenced by vm_browse_messages().

9708 {
9709  int cmd = 0;
9710 
9711  if (vms->lastmsg > -1) {
9712  cmd = play_message(chan, vmu, vms);
9713  } else {
9714  cmd = ast_play_and_wait(chan, "vm-no");
9715  if (!cmd) {
9716  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9717  cmd = ast_play_and_wait(chan, vms->fn);
9718  }
9719  }
9720  return cmd;
9721 }
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
char fn[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_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 9679 of file app_voicemail_imapstorage.c.

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

Referenced by vm_browse_messages().

9680 {
9681  int cmd;
9682 
9683  if (vms->lastmsg > -1) {
9684  cmd = play_message(chan, vmu, vms);
9685  } else {
9686  cmd = ast_play_and_wait(chan, "vm-you");
9687  if (!cmd)
9688  cmd = ast_play_and_wait(chan, "vm-haveno");
9689  if (!cmd)
9690  cmd = ast_play_and_wait(chan, "vm-messages");
9691  if (!cmd) {
9692  snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
9693  cmd = ast_play_and_wait(chan, vms->fn);
9694  }
9695  }
9696  return cmd;
9697 }
static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
char fn[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 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 1526 of file app_voicemail_imapstorage.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().

1527 {
1528  struct ast_config *cfg = NULL;
1529  struct ast_variable *var = NULL;
1530  struct ast_category *cat = NULL;
1531  char *category = NULL, *value = NULL, *new = NULL;
1532  const char *tmp = NULL;
1533  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
1534  char secretfn[PATH_MAX] = "";
1535  int found = 0;
1536 
1537  if (!change_password_realtime(vmu, newpassword))
1538  return;
1539 
1540  /* check if we should store the secret in the spool directory next to the messages */
1541  switch (vmu->passwordlocation) {
1542  case OPT_PWLOC_SPOOLDIR:
1543  snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
1544  if (write_password_to_file(secretfn, newpassword) == 0) {
1545  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf");
1546  ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn);
1547  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1548  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1549  break;
1550  } else {
1551  ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn);
1552  }
1553  /* Fall-through */
1555  if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && valid_config(cfg)) {
1556  while ((category = ast_category_browse(cfg, category))) {
1557  if (!strcasecmp(category, vmu->context)) {
1558  if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
1559  ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n");
1560  break;
1561  }
1562  value = strstr(tmp, ",");
1563  if (!value) {
1564  new = ast_alloca(strlen(newpassword)+1);
1565  sprintf(new, "%s", newpassword);
1566  } else {
1567  new = ast_alloca((strlen(value) + strlen(newpassword) + 1));
1568  sprintf(new, "%s%s", newpassword, value);
1569  }
1570  if (!(cat = ast_category_get(cfg, category))) {
1571  ast_log(AST_LOG_WARNING, "Failed to get category structure.\n");
1572  break;
1573  }
1574  ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
1575  found = 1;
1576  }
1577  }
1578  /* save the results */
1579  if (found) {
1580  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf");
1581  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1582  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1583  ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
1584  ast_config_destroy(cfg);
1585  break;
1586  }
1587 
1588  ast_config_destroy(cfg);
1589  }
1590  /* Fall-through */
1591  case OPT_PWLOC_USERSCONF:
1592  /* check users.conf and update the password stored for the mailbox */
1593  /* if no vmsecret entry exists create one. */
1594  if ((cfg = ast_config_load("users.conf", config_flags)) && valid_config(cfg)) {
1595  ast_debug(4, "we are looking for %s\n", vmu->mailbox);
1596  for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) {
1597  ast_debug(4, "users.conf: %s\n", category);
1598  if (!strcasecmp(category, vmu->mailbox)) {
1599  if (!ast_variable_retrieve(cfg, category, "vmsecret")) {
1600  ast_debug(3, "looks like we need to make vmsecret!\n");
1601  var = ast_variable_new("vmsecret", newpassword, "");
1602  } else {
1603  var = NULL;
1604  }
1605  new = ast_alloca(strlen(newpassword) + 1);
1606  sprintf(new, "%s", newpassword);
1607  if (!(cat = ast_category_get(cfg, category))) {
1608  ast_debug(4, "failed to get category!\n");
1609  ast_free(var);
1610  break;
1611  }
1612  if (!var) {
1613  ast_variable_update(cat, "vmsecret", new, NULL, 0);
1614  } else {
1615  ast_variable_append(cat, var);
1616  }
1617  found = 1;
1618  break;
1619  }
1620  }
1621  /* save the results and clean things up */
1622  if (found) {
1623  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf");
1624  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1625  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1626  ast_config_text_file_save("users.conf", cfg, "AppVoicemail");
1627  }
1628 
1629  ast_config_destroy(cfg);
1630  }
1631  }
1632 }
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 reset_user_pw(const char *context, const char *mailbox, const char *newpass)
Resets a user password to a specified password.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
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
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
static char VM_SPOOL_DIR[PATH_MAX]
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
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
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_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
#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
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int write_password_to_file(const char *secretfn, const char *password)
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
#define VOICEMAIL_CONFIG
char password[80]
static void vm_change_password_shell ( struct ast_vm_user vmu,
char *  newpassword 
)
static

Definition at line 1634 of file app_voicemail_imapstorage.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().

1635 {
1636  char buf[255];
1637  snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword);
1638  ast_debug(1, "External password: %s\n",buf);
1639  if (!ast_safe_system(buf)) {
1640  ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external");
1641  ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
1642  /* Reset the password in memory, too */
1643  reset_user_pw(vmu->context, vmu->mailbox, newpassword);
1644  }
1645 }
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
static int reset_user_pw(const char *context, const char *mailbox, const char *newpass)
Resets a user password to a specified password.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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
char password[80]
static char ext_pass_cmd[128]
static char* vm_check_password_shell ( char *  command,
char *  buf,
size_t  len 
)
static

Definition at line 1189 of file app_voicemail_imapstorage.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().

1190 {
1191  int fds[2], pid = 0;
1192 
1193  memset(buf, 0, len);
1194 
1195  if (pipe(fds)) {
1196  snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno));
1197  } else {
1198  /* good to go*/
1199  pid = ast_safe_fork(0);
1200 
1201  if (pid < 0) {
1202  /* ok maybe not */
1203  close(fds[0]);
1204  close(fds[1]);
1205  snprintf(buf, len, "FAILURE: Fork failed");
1206  } else if (pid) {
1207  /* parent */
1208  close(fds[1]);
1209  if (read(fds[0], buf, len) < 0) {
1210  ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
1211  }
1212  close(fds[0]);
1213  } else {
1214  /* child */
1216  AST_APP_ARG(v)[20];
1217  );
1218  char *mycmd = ast_strdupa(command);
1219 
1220  close(fds[0]);
1221  dup2(fds[1], STDOUT_FILENO);
1222  close(fds[1]);
1223  ast_close_fds_above_n(STDOUT_FILENO);
1224 
1225  AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' ');
1226 
1227  execv(arg.v[0], arg.v);
1228  printf("FAILURE: %s", strerror(errno));
1229  _exit(0);
1230  }
1231  }
1232  return buf;
1233 }
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 4237 of file app_voicemail_imapstorage.c.

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

Referenced by copy_message(), and notify_new_message().

4238 {
4239  char *txt;
4240  int txtsize = 0;
4241 
4242  txtsize = (strlen(file) + 5)*sizeof(char);
4243  txt = ast_alloca(txtsize);
4244  /* Sprintf here would safe because we alloca'd exactly the right length,
4245  * but trying to eliminate all sprintf's anyhow
4246  */
4247  if (ast_check_realtime("voicemail_data")) {
4248  ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL);
4249  }
4250  snprintf(txt, txtsize, "%s.txt", file);
4251  unlink(txt);
4252  return ast_filedelete(file, NULL);
4253 }
#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 10626 of file app_voicemail_imapstorage.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().

10627 {
10628  int res = 0;
10629  char *tmp;
10630  struct leave_vm_options leave_options;
10631  struct ast_flags flags = { 0 };
10632  char *opts[OPT_ARG_ARRAY_SIZE];
10634  AST_APP_ARG(argv0);
10635  AST_APP_ARG(argv1);
10636  );
10637 
10638  memset(&leave_options, 0, sizeof(leave_options));
10639 
10640  if (chan->_state != AST_STATE_UP)
10641  ast_answer(chan);
10642 
10643  if (!ast_strlen_zero(data)) {
10644  tmp = ast_strdupa(data);
10646  if (args.argc == 2) {
10647  if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1))
10648  return -1;
10650  if (ast_test_flag(&flags, OPT_RECORDGAIN)) {
10651  int gain;
10652 
10653  if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) {
10654  ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]);
10655  return -1;
10656  } else {
10657  leave_options.record_gain = (signed char) gain;
10658  }
10659  }
10660  if (ast_test_flag(&flags, OPT_DTMFEXIT)) {
10661  if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT]))
10662  leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT];
10663  }
10664  }
10665  } else {
10666  char temp[256];
10667  res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0);
10668  if (res < 0)
10669  return res;
10670  if (ast_strlen_zero(temp))
10671  return 0;
10672  args.argv0 = ast_strdupa(temp);
10673  }
10674 
10675  res = leave_voicemail(chan, args.argv0, &leave_options);
10676  if (res == 't') {
10677  ast_play_and_wait(chan, "vm-goodbye");
10678  res = 0;
10679  }
10680 
10681  if (res == OPERATOR_EXIT) {
10682  res = 0;
10683  }
10684 
10685  if (res == ERROR_LOCK_PATH) {
10686  ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n");
10687  pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED");
10688  res = 0;
10689  }
10690 
10691  return res;
10692 }
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
#define ERROR_LOCK_PATH
#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
static struct ast_app_option vm_app_options[128]
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
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
#define OPERATOR_EXIT
static int vm_execmain ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 9874 of file app_voicemail_imapstorage.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().

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

6920 {
6921  int cmd = 0;
6922  int retries = 0, prepend_duration = 0, already_recorded = 0;
6923  char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX];
6924  char textfile[PATH_MAX];
6925  struct ast_config *msg_cfg;
6926  struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE };
6927 #ifndef IMAP_STORAGE
6928  signed char zero_gain = 0;
6929 #endif
6930  const char *duration_str;
6931 
6932  /* Must always populate duration correctly */
6933  make_file(msgfile, sizeof(msgfile), curdir, curmsg);
6934  strcpy(textfile, msgfile);
6935  strcpy(backup, msgfile);
6936  strcpy(backup_textfile, msgfile);
6937  strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1);
6938  strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1);
6939  strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1);
6940 
6941  if ((msg_cfg = ast_config_load(textfile, config_flags)) && valid_config(msg_cfg) && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) {
6942  *duration = atoi(duration_str);
6943  } else {
6944  *duration = 0;
6945  }
6946 
6947  while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) {
6948  if (cmd)
6949  retries = 0;
6950  switch (cmd) {
6951  case '1':
6952 
6953 #ifdef IMAP_STORAGE
6954  /* Record new intro file */
6955  make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg);
6956  strncat(vms->introfn, "intro", sizeof(vms->introfn));
6957  ast_play_and_wait(chan, INTRO);
6958  ast_play_and_wait(chan, "beep");
6959  cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag);
6960  if (cmd == -1) {
6961  break;
6962  }
6963  cmd = 't';
6964 #else
6965 
6966  /* prepend a message to the current message, update the metadata and return */
6967 
6968  make_file(msgfile, sizeof(msgfile), curdir, curmsg);
6969  strcpy(textfile, msgfile);
6970  strncat(textfile, ".txt", sizeof(textfile) - 1);
6971  *duration = 0;
6972 
6973  /* if we can't read the message metadata, stop now */
6974  if (!valid_config(msg_cfg)) {
6975  cmd = 0;
6976  break;
6977  }
6978 
6979  /* Back up the original file, so we can retry the prepend and restore it after forward. */
6980 #ifndef IMAP_STORAGE
6981  if (already_recorded) {
6982  ast_filecopy(backup, msgfile, NULL);
6983  copy(backup_textfile, textfile);
6984  }
6985  else {
6986  ast_filecopy(msgfile, backup, NULL);
6987  copy(textfile, backup_textfile);
6988  }
6989 #endif
6990  already_recorded = 1;
6991 
6992  if (record_gain)
6993  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0);
6994 
6995  cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence);
6996 
6997  if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */
6998  ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */
7000  ast_filerename(backup, msgfile, NULL);
7001  }
7002 
7003  if (record_gain)
7004  ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0);
7005 
7006 
7007  if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration")))
7008  *duration = atoi(duration_str);
7009 
7010  if (prepend_duration) {
7011  struct ast_category *msg_cat;
7012  /* need enough space for a maximum-length message duration */
7013  char duration_buf[12];
7014 
7015  *duration += prepend_duration;
7016  msg_cat = ast_category_get(msg_cfg, "message");
7017  snprintf(duration_buf, 11, "%ld", *duration);
7018  if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) {
7019  ast_config_text_file_save(textfile, msg_cfg, "app_voicemail");
7020  }
7021  }
7022 
7023 #endif
7024  break;
7025  case '2':
7026  /* NULL out introfile so we know there is no intro! */
7027 #ifdef IMAP_STORAGE
7028  *vms->introfn = '\0';
7029 #endif
7030  cmd = 't';
7031  break;
7032  case '*':
7033  cmd = '*';
7034  break;
7035  default:
7036  /* If time_out and return to menu, reset already_recorded */
7037  already_recorded = 0;
7038 
7039  cmd = ast_play_and_wait(chan, "vm-forwardoptions");
7040  /* "Press 1 to prepend a message or 2 to forward the message without prepending" */
7041  if (!cmd) {
7042  cmd = ast_play_and_wait(chan, "vm-starmain");
7043  /* "press star to return to the main menu" */
7044  }
7045  if (!cmd) {
7046  cmd = ast_waitfordigit(chan, 6000);
7047  }
7048  if (!cmd) {
7049  retries++;
7050  }
7051  if (retries > 3) {
7052  cmd = '*'; /* Let's cancel this beast */
7053  }
7054  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
7055  }
7056  }
7057 
7058  if (valid_config(msg_cfg))
7059  ast_config_destroy(msg_cfg);
7060  if (prepend_duration)
7061  *duration = prepend_duration;
7062 
7063  if (already_recorded && cmd == -1) {
7064  /* restore original message if prepention cancelled */
7065  ast_filerename(backup, msgfile, NULL);
7066  rename(backup_textfile, textfile);
7067  }
7068 
7069  if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */
7070  cmd = 0;
7071  return cmd;
7072 }
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
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...
static int valid_config(const struct ast_config *cfg)
Check if configuration file is valid.
static int maxsilence
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
static int copy(char *infile, char *outfile)
Utility function to copy a file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define INTRO
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 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_suite_event_notify(s, f,...)
Definition: test.h:184
static char vm_prepend_timeout[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
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
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
#define AST_OPTION_RXGAIN
Definition: frame.h:463
static int silencethreshold
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
static char vm_pls_try_again[80]
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 9272 of file app_voicemail_imapstorage.c.

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

Referenced by vm_execmain().

9273 {
9274  if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */
9275  return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
9276  } else { /* Default to ENGLISH */
9277  return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
9278  }
9279 }
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)
const ast_string_field language
Definition: channel.h:787
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 9160 of file app_voicemail_imapstorage.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().

9161 {
9162  int res = 0;
9163  /* Play instructions and wait for new command */
9164  while (!res) {
9165  if (vms->starting) {
9166  if (vms->lastmsg > -1) {
9167  if (skipadvanced)
9168  res = ast_play_and_wait(chan, "vm-onefor-full");
9169  else
9170  res = ast_play_and_wait(chan, "vm-onefor");
9171  if (!res)
9172  res = vm_play_folder_name(chan, vms->vmbox);
9173  }
9174  if (!res) {
9175  if (skipadvanced)
9176  res = ast_play_and_wait(chan, "vm-opts-full");
9177  else
9178  res = ast_play_and_wait(chan, "vm-opts");
9179  }
9180  } else {
9181  /* Added for additional help */
9182  if (skipadvanced) {
9183  res = ast_play_and_wait(chan, "vm-onefor-full");
9184  if (!res)
9185  res = vm_play_folder_name(chan, vms->vmbox);
9186  res = ast_play_and_wait(chan, "vm-opts-full");
9187  }
9188  /* Logic:
9189  * If the current message is not the first OR
9190  * if we're listening to the first new message and there are
9191  * also urgent messages, then prompt for navigation to the
9192  * previous message
9193  */
9194  if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) {
9195  res = ast_play_and_wait(chan, "vm-prev");
9196  }
9197  if (!res && !skipadvanced)
9198  res = ast_play_and_wait(chan, "vm-advopts");
9199  if (!res)
9200  res = ast_play_and_wait(chan, "vm-repeat");
9201  /* Logic:
9202  * If we're not listening to the last message OR
9203  * we're listening to the last urgent message and there are
9204  * also new non-urgent messages, then prompt for navigation
9205  * to the next message
9206  */
9207  if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) ||
9208  (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) {
9209  res = ast_play_and_wait(chan, "vm-next");
9210  }
9211  if (!res) {
9212  int curmsg_deleted;
9213 #ifdef IMAP_STORAGE
9214  ast_mutex_lock(&vms->lock);
9215 #endif
9216  curmsg_deleted = vms->deleted[vms->curmsg];
9217 #ifdef IMAP_STORAGE
9218  ast_mutex_unlock(&vms->lock);
9219 #endif
9220  if (!curmsg_deleted) {
9221  res = ast_play_and_wait(chan, "vm-delete");
9222  } else {
9223  res = ast_play_and_wait(chan, "vm-undelete");
9224  }
9225  if (!res) {
9226  res = ast_play_and_wait(chan, "vm-toforward");
9227  }
9228  if (!res) {
9229  res = ast_play_and_wait(chan, "vm-savemessage");
9230  }
9231  }
9232  }
9233  if (!res) {
9234  res = ast_play_and_wait(chan, "vm-helpexit");
9235  }
9236  if (!res)
9237  res = ast_waitfordigit(chan, 6000);
9238  if (!res) {
9239  vms->repeats++;
9240  if (vms->repeats > 2) {
9241  res = 't';
9242  }
9243  }
9244  }
9245  return res;
9246 }
static int vm_play_folder_name(struct ast_channel *chan, char *mbox)
#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
int * deleted
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
#define VM_MESSAGEWRAP
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 9248 of file app_voicemail_imapstorage.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().

9249 {
9250  int res = 0;
9251  /* Play instructions and wait for new command */
9252  while (!res) {
9253  if (vms->lastmsg > -1) {
9254  res = ast_play_and_wait(chan, "vm-listen");
9255  if (!res)
9256  res = vm_play_folder_name(chan, vms->vmbox);
9257  if (!res)
9258  res = ast_play_and_wait(chan, "press");
9259  if (!res)
9260  res = ast_play_and_wait(chan, "digits/1");
9261  }
9262  if (!res)
9263  res = ast_play_and_wait(chan, "vm-opts");
9264  if (!res) {
9265  vms->starting = 0;
9266  return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
9267  }
9268  }
9269  return res;
9270 }
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_play_folder_name(struct ast_channel *chan, char *mbox)
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_intro ( struct ast_channel chan,
struct ast_vm_user vmu,
struct vm_state vms 
)
static

Definition at line 9098 of file app_voicemail_imapstorage.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().

9099 {
9100  char prefile[256];
9101 
9102  /* Notify the user that the temp greeting is set and give them the option to remove it */
9103  snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
9104  if (ast_test_flag(vmu, VM_TEMPGREETWARN)) {
9105  RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
9106  if (ast_fileexists(prefile, NULL, NULL) > 0) {
9107  ast_play_and_wait(chan, "vm-tempgreetactive");
9108  }
9109  DISPOSE(prefile, -1);
9110  }
9111 
9112  /* Play voicemail intro - syntax is different for different languages */
9113  if (0) {
9114  return 0;
9115  } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */
9116  return vm_intro_cs(chan, vms);
9117  } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */
9118  static int deprecation_warning = 0;
9119  if (deprecation_warning++ % 10 == 0) {
9120  ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n");
9121  }
9122  return vm_intro_cs(chan, vms);
9123  } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */
9124  return vm_intro_de(chan, vms);
9125  } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */
9126  return vm_intro_es(chan, vms);
9127  } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */
9128  return vm_intro_fr(chan, vms);
9129  } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */
9130  return vm_intro_gr(chan, vms);
9131  } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */
9132  return vm_intro_he(chan, vms);
9133  } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */
9134  return vm_intro_it(chan, vms);
9135  } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */
9136  return vm_intro_nl(chan, vms);
9137  } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */
9138  return vm_intro_no(chan, vms);
9139  } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */
9140  return vm_intro_pl(chan, vms);
9141  } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */
9142  return vm_intro_pt_BR(chan, vms);
9143  } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */
9144  return vm_intro_pt(chan, vms);
9145  } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */
9146  return vm_intro_multilang(chan, vms, "n");
9147  } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */
9148  return vm_intro_se(chan, vms);
9149  } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */
9150  return vm_intro_multilang(chan, vms, "n");
9151  } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */
9152  return vm_intro_vi(chan, vms);
9153  } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */
9154  return vm_intro_zh(chan, vms);
9155  } else { /* Default to ENGLISH */
9156  return vm_intro_en(chan, vms);
9157  }
9158 }
static int vm_intro_fr(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_gr(struct ast_channel *chan, struct vm_state *vms)
#define RETRIEVE(a, b, c, d)
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
#define VM_TEMPGREETWARN
static int vm_intro_pt(struct ast_channel *chan, struct vm_state *vms)
static char VM_SPOOL_DIR[PATH_MAX]
static int vm_intro_se(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_zh(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_pt_BR(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_en(struct ast_channel *chan, struct vm_state *vms)
static int vm_intro_es(struct ast_channel *chan, struct vm_state *vms)
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 vm_intro_no(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_nl(struct ast_channel *chan, struct vm_state *vms)
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_de(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_cs(struct ast_channel *chan, struct vm_state *vms)
const ast_string_field language
Definition: channel.h:787
static int vm_intro_multilang(struct ast_channel *chan, struct vm_state *vms, const char message_gender[])
static int vm_intro_he(struct ast_channel *chan, struct vm_state *vms)
#define DISPOSE(a, b)
static int vm_intro_cs ( struct ast_channel chan,
struct vm_state vms 
)
static

Definition at line 8968 of file app_voicemail_imapstorage.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().

8969 {
8970  int res;
8971  res = ast_play_and_wait(chan, "vm-youhave");
8972  if (!res) {
8973  if (vms->newmessages) {
8974  if (vms->newmessages == 1) {
8975  res = ast_play_and_wait(chan, "digits/jednu");
8976  } else {
8977  res = say_and_wait(chan, vms->newmessages, chan->language);
8978  }
8979  if (!res) {
8980  if ((vms->newmessages == 1))
8981  res = ast_play_and_wait(chan, "vm-novou");
8982  if ((vms->newmessages) > 1 && (vms->newmessages < 5))
8983  res = ast_play_and_wait(chan, "vm-nove");
8984  if (vms->newmessages > 4)
8985  res = ast_play_and_wait(chan, "vm-novych");
8986  }
8987  if (vms->oldmessages && !res)
8988  res = ast_play_and_wait(chan, "vm-and");
8989  else if (!res) {
8990  if ((vms->newmessages == 1))
8991  res = ast_play_and_wait(chan, "vm-zpravu");
8992  if ((vms->newmessages) > 1 && (vms->newmessages < 5))
8993  res = ast_play_and_wait(chan, "vm-zpravy");
8994  if (vms->newmessages > 4)
8995  res = ast_play_and_wait(chan, "vm-zprav");
8996  }
8997  }
8998  if (!res && vms->oldmessages) {
8999  res = say_and_wait(chan, vms->oldmessages, chan->language);
9000  if (!res) {
9001  if ((vms->oldmessages == 1))
9002  res = ast_play_and_wait(chan, "vm-starou");
9003  if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
9004  res = ast_play_and_wait(chan, "vm-stare");
9005  if (vms->oldmessages > 4)
9006  res = ast_play_and_wait(chan, "vm-starych");
9007  }
9008  if (!res) {
9009  if ((vms->oldmessages == 1))
9010  res = ast_play_and_wait(chan, "vm-zpravu");
9011  if ((vms->oldmessages) > 1 && (vms->oldmessages < 5))
9012  res = ast_play_and_wait(chan, "vm-zpravy");
9013  if (vms->oldmessages > 4)
9014  res = ast_play_and_wait(chan, "vm-zprav");
9015  }
9016  }
9017  if (!res) {
9018  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
9019  res = ast_play_and_wait(chan, "vm-no");
9020  if (!res)
9021  res = ast_play_and_wait(chan, "vm-zpravy");
9022  }
9023  }
9024  }
9025  return res;
9026 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8664 of file app_voicemail_imapstorage.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().

8665 {
8666  /* Introduce messages they have */
8667  int res;
8668  res = ast_play_and_wait(chan, "vm-youhave");
8669  if (!res) {
8670  if (vms->newmessages) {
8671  if ((vms->newmessages == 1))
8672  res = ast_play_and_wait(chan, "digits/1F");
8673  else
8674  res = say_and_wait(chan, vms->newmessages, chan->language);
8675  if (!res)
8676  res = ast_play_and_wait(chan, "vm-INBOX");
8677  if (vms->oldmessages && !res)
8678  res = ast_play_and_wait(chan, "vm-and");
8679  else if (!res) {
8680  if ((vms->newmessages == 1))
8681  res = ast_play_and_wait(chan, "vm-message");
8682  else
8683  res = ast_play_and_wait(chan, "vm-messages");
8684  }
8685 
8686  }
8687  if (!res && vms->oldmessages) {
8688  if (vms->oldmessages == 1)
8689  res = ast_play_and_wait(chan, "digits/1F");
8690  else
8691  res = say_and_wait(chan, vms->oldmessages, chan->language);
8692  if (!res)
8693  res = ast_play_and_wait(chan, "vm-Old");
8694  if (!res) {
8695  if (vms->oldmessages == 1)
8696  res = ast_play_and_wait(chan, "vm-message");
8697  else
8698  res = ast_play_and_wait(chan, "vm-messages");
8699  }
8700  }
8701  if (!res) {
8702  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8703  res = ast_play_and_wait(chan, "vm-no");
8704  if (!res)
8705  res = ast_play_and_wait(chan, "vm-messages");
8706  }
8707  }
8708  }
8709  return res;
8710 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8413 of file app_voicemail_imapstorage.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().

8414 {
8415  int res;
8416 
8417  /* Introduce messages they have */
8418  res = ast_play_and_wait(chan, "vm-youhave");
8419  if (!res) {
8420  if (vms->urgentmessages) {
8421  res = say_and_wait(chan, vms->urgentmessages, chan->language);
8422  if (!res)
8423  res = ast_play_and_wait(chan, "vm-Urgent");
8424  if ((vms->oldmessages || vms->newmessages) && !res) {
8425  res = ast_play_and_wait(chan, "vm-and");
8426  } else if (!res) {
8427  if ((vms->urgentmessages == 1))
8428  res = ast_play_and_wait(chan, "vm-message");
8429  else
8430  res = ast_play_and_wait(chan, "vm-messages");
8431  }
8432  }
8433  if (vms->newmessages) {
8434  res = say_and_wait(chan, vms->newmessages, chan->language);
8435  if (!res)
8436  res = ast_play_and_wait(chan, "vm-INBOX");
8437  if (vms->oldmessages && !res)
8438  res = ast_play_and_wait(chan, "vm-and");
8439  else if (!res) {
8440  if ((vms->newmessages == 1))
8441  res = ast_play_and_wait(chan, "vm-message");
8442  else
8443  res = ast_play_and_wait(chan, "vm-messages");
8444  }
8445 
8446  }
8447  if (!res && vms->oldmessages) {
8448  res = say_and_wait(chan, vms->oldmessages, chan->language);
8449  if (!res)
8450  res = ast_play_and_wait(chan, "vm-Old");
8451  if (!res) {
8452  if (vms->oldmessages == 1)
8453  res = ast_play_and_wait(chan, "vm-message");
8454  else
8455  res = ast_play_and_wait(chan, "vm-messages");
8456  }
8457  }
8458  if (!res) {
8459  if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) {
8460  res = ast_play_and_wait(chan, "vm-no");
8461  if (!res)
8462  res = ast_play_and_wait(chan, "vm-messages");
8463  }
8464  }
8465  }
8466  return res;
8467 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8713 of file app_voicemail_imapstorage.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().

8714 {
8715  /* Introduce messages they have */
8716  int res;
8717  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8718  res = ast_play_and_wait(chan, "vm-youhaveno");
8719  if (!res)
8720  res = ast_play_and_wait(chan, "vm-messages");
8721  } else {
8722  res = ast_play_and_wait(chan, "vm-youhave");
8723  }
8724  if (!res) {
8725  if (vms->newmessages) {
8726  if (!res) {
8727  if ((vms->newmessages == 1)) {
8728  res = ast_play_and_wait(chan, "digits/1");
8729  if (!res)
8730  res = ast_play_and_wait(chan, "vm-message");
8731  if (!res)
8732  res = ast_play_and_wait(chan, "vm-INBOXs");
8733  } else {
8734  res = say_and_wait(chan, vms->newmessages, chan->language);
8735  if (!res)
8736  res = ast_play_and_wait(chan, "vm-messages");
8737  if (!res)
8738  res = ast_play_and_wait(chan, "vm-INBOX");
8739  }
8740  }
8741  if (vms->oldmessages && !res)
8742  res = ast_play_and_wait(chan, "vm-and");
8743  }
8744  if (vms->oldmessages) {
8745  if (!res) {
8746  if (vms->oldmessages == 1) {
8747  res = ast_play_and_wait(chan, "digits/1");
8748  if (!res)
8749  res = ast_play_and_wait(chan, "vm-message");
8750  if (!res)
8751  res = ast_play_and_wait(chan, "vm-Olds");
8752  } else {
8753  res = say_and_wait(chan, vms->oldmessages, chan->language);
8754  if (!res)
8755  res = ast_play_and_wait(chan, "vm-messages");
8756  if (!res)
8757  res = ast_play_and_wait(chan, "vm-Old");
8758  }
8759  }
8760  }
8761  }
8762 return res;
8763 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8811 of file app_voicemail_imapstorage.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().

8812 {
8813  /* Introduce messages they have */
8814  int res;
8815  res = ast_play_and_wait(chan, "vm-youhave");
8816  if (!res) {
8817  if (vms->newmessages) {
8818  res = say_and_wait(chan, vms->newmessages, chan->language);
8819  if (!res)
8820  res = ast_play_and_wait(chan, "vm-INBOX");
8821  if (vms->oldmessages && !res)
8822  res = ast_play_and_wait(chan, "vm-and");
8823  else if (!res) {
8824  if ((vms->newmessages == 1))
8825  res = ast_play_and_wait(chan, "vm-message");
8826  else
8827  res = ast_play_and_wait(chan, "vm-messages");
8828  }
8829 
8830  }
8831  if (!res && vms->oldmessages) {
8832  res = say_and_wait(chan, vms->oldmessages, chan->language);
8833  if (!res)
8834  res = ast_play_and_wait(chan, "vm-Old");
8835  if (!res) {
8836  if (vms->oldmessages == 1)
8837  res = ast_play_and_wait(chan, "vm-message");
8838  else
8839  res = ast_play_and_wait(chan, "vm-messages");
8840  }
8841  }
8842  if (!res) {
8843  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8844  res = ast_play_and_wait(chan, "vm-no");
8845  if (!res)
8846  res = ast_play_and_wait(chan, "vm-messages");
8847  }
8848  }
8849  }
8850  return res;
8851 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8212 of file app_voicemail_imapstorage.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().

8213 {
8214  int res = 0;
8215 
8216  if (vms->newmessages) {
8217  res = ast_play_and_wait(chan, "vm-youhave");
8218  if (!res)
8219  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL);
8220  if (!res) {
8221  if ((vms->newmessages == 1)) {
8222  res = ast_play_and_wait(chan, "vm-INBOX");
8223  if (!res)
8224  res = ast_play_and_wait(chan, "vm-message");
8225  } else {
8226  res = ast_play_and_wait(chan, "vm-INBOXs");
8227  if (!res)
8228  res = ast_play_and_wait(chan, "vm-messages");
8229  }
8230  }
8231  } else if (vms->oldmessages){
8232  res = ast_play_and_wait(chan, "vm-youhave");
8233  if (!res)
8234  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL);
8235  if ((vms->oldmessages == 1)){
8236  res = ast_play_and_wait(chan, "vm-Old");
8237  if (!res)
8238  res = ast_play_and_wait(chan, "vm-message");
8239  } else {
8240  res = ast_play_and_wait(chan, "vm-Olds");
8241  if (!res)
8242  res = ast_play_and_wait(chan, "vm-messages");
8243  }
8244  } else if (!vms->oldmessages && !vms->newmessages)
8245  res = ast_play_and_wait(chan, "vm-denExeteMynhmata");
8246  return res;
8247 }
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 8346 of file app_voicemail_imapstorage.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().

8347 {
8348  int res = 0;
8349 
8350  /* Introduce messages they have */
8351  if (!res) {
8352  if ((vms->newmessages) || (vms->oldmessages)) {
8353  res = ast_play_and_wait(chan, "vm-youhave");
8354  }
8355  /*
8356  * The word "shtei" refers to the number 2 in hebrew when performing a count
8357  * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for
8358  * an element, this is one of them.
8359  */
8360  if (vms->newmessages) {
8361  if (!res) {
8362  if (vms->newmessages == 1) {
8363  res = ast_play_and_wait(chan, "vm-INBOX1");
8364  } else {
8365  if (vms->newmessages == 2) {
8366  res = ast_play_and_wait(chan, "vm-shtei");
8367  } else {
8368  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
8369  }
8370  res = ast_play_and_wait(chan, "vm-INBOX");
8371  }
8372  }
8373  if (vms->oldmessages && !res) {
8374  res = ast_play_and_wait(chan, "vm-and");
8375  if (vms->oldmessages == 1) {
8376  res = ast_play_and_wait(chan, "vm-Old1");
8377  } else {
8378  if (vms->oldmessages == 2) {
8379  res = ast_play_and_wait(chan, "vm-shtei");
8380  } else {
8381  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8382  }
8383  res = ast_play_and_wait(chan, "vm-Old");
8384  }
8385  }
8386  }
8387  if (!res && vms->oldmessages && !vms->newmessages) {
8388  if (!res) {
8389  if (vms->oldmessages == 1) {
8390  res = ast_play_and_wait(chan, "vm-Old1");
8391  } else {
8392  if (vms->oldmessages == 2) {
8393  res = ast_play_and_wait(chan, "vm-shtei");
8394  } else {
8395  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8396  }
8397  res = ast_play_and_wait(chan, "vm-Old");
8398  }
8399  }
8400  }
8401  if (!res) {
8402  if (!vms->oldmessages && !vms->newmessages) {
8403  if (!res) {
8404  res = ast_play_and_wait(chan, "vm-nomessages");
8405  }
8406  }
8407  }
8408  }
8409  return res;
8410 }
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 8470 of file app_voicemail_imapstorage.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().

8471 {
8472  /* Introduce messages they have */
8473  int res;
8474  if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages)
8475  res = ast_play_and_wait(chan, "vm-no") ||
8476  ast_play_and_wait(chan, "vm-message");
8477  else
8478  res = ast_play_and_wait(chan, "vm-youhave");
8479  if (!res && vms->newmessages) {
8480  res = (vms->newmessages == 1) ?
8481  ast_play_and_wait(chan, "digits/un") ||
8482  ast_play_and_wait(chan, "vm-nuovo") ||
8483  ast_play_and_wait(chan, "vm-message") :
8484  /* 2 or more new messages */
8485  say_and_wait(chan, vms->newmessages, chan->language) ||
8486  ast_play_and_wait(chan, "vm-nuovi") ||
8487  ast_play_and_wait(chan, "vm-messages");
8488  if (!res && vms->oldmessages)
8489  res = ast_play_and_wait(chan, "vm-and");
8490  }
8491  if (!res && vms->oldmessages) {
8492  res = (vms->oldmessages == 1) ?
8493  ast_play_and_wait(chan, "digits/un") ||
8494  ast_play_and_wait(chan, "vm-vecchio") ||
8495  ast_play_and_wait(chan, "vm-message") :
8496  /* 2 or more old messages */
8497  say_and_wait(chan, vms->oldmessages, chan->language) ||
8498  ast_play_and_wait(chan, "vm-vecchi") ||
8499  ast_play_and_wait(chan, "vm-messages");
8500  }
8501  return res;
8502 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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
int newmessages
static int vm_intro_multilang ( struct ast_channel chan,
struct vm_state vms,
const char  message_gender[] 
)
static

Definition at line 8306 of file app_voicemail_imapstorage.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().

8307 {
8308  int res;
8309  int lastnum = 0;
8310 
8311  res = ast_play_and_wait(chan, "vm-youhave");
8312 
8313  if (!res && vms->newmessages) {
8314  lastnum = vms->newmessages;
8315 
8316  if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
8317  res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender);
8318  }
8319 
8320  if (!res && vms->oldmessages) {
8321  res = ast_play_and_wait(chan, "vm-and");
8322  }
8323  }
8324 
8325  if (!res && vms->oldmessages) {
8326  lastnum = vms->oldmessages;
8327 
8328  if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) {
8329  res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender);
8330  }
8331  }
8332 
8333  if (!res) {
8334  if (lastnum == 0) {
8335  res = ast_play_and_wait(chan, "vm-no");
8336  }
8337  if (!res) {
8338  res = ast_say_counted_noun(chan, lastnum, "vm-message");
8339  }
8340  }
8341 
8342  return res;
8343 }
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 8854 of file app_voicemail_imapstorage.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().

8855 {
8856  /* Introduce messages they have */
8857  int res;
8858  res = ast_play_and_wait(chan, "vm-youhave");
8859  if (!res) {
8860  if (vms->newmessages) {
8861  res = say_and_wait(chan, vms->newmessages, chan->language);
8862  if (!res) {
8863  if (vms->newmessages == 1)
8864  res = ast_play_and_wait(chan, "vm-INBOXs");
8865  else
8866  res = ast_play_and_wait(chan, "vm-INBOX");
8867  }
8868  if (vms->oldmessages && !res)
8869  res = ast_play_and_wait(chan, "vm-and");
8870  else if (!res) {
8871  if ((vms->newmessages == 1))
8872  res = ast_play_and_wait(chan, "vm-message");
8873  else
8874  res = ast_play_and_wait(chan, "vm-messages");
8875  }
8876 
8877  }
8878  if (!res && vms->oldmessages) {
8879  res = say_and_wait(chan, vms->oldmessages, chan->language);
8880  if (!res) {
8881  if (vms->oldmessages == 1)
8882  res = ast_play_and_wait(chan, "vm-Olds");
8883  else
8884  res = ast_play_and_wait(chan, "vm-Old");
8885  }
8886  if (!res) {
8887  if (vms->oldmessages == 1)
8888  res = ast_play_and_wait(chan, "vm-message");
8889  else
8890  res = ast_play_and_wait(chan, "vm-messages");
8891  }
8892  }
8893  if (!res) {
8894  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8895  res = ast_play_and_wait(chan, "vm-no");
8896  if (!res)
8897  res = ast_play_and_wait(chan, "vm-messages");
8898  }
8899  }
8900  }
8901  return res;
8902 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8620 of file app_voicemail_imapstorage.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().

8621 {
8622  /* Introduce messages they have */
8623  int res;
8624 
8625  res = ast_play_and_wait(chan, "vm-youhave");
8626  if (res)
8627  return res;
8628 
8629  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8630  res = ast_play_and_wait(chan, "vm-no");
8631  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8632  return res;
8633  }
8634 
8635  if (vms->newmessages) {
8636  if ((vms->newmessages == 1)) {
8637  res = ast_play_and_wait(chan, "digits/1");
8638  res = res ? res : ast_play_and_wait(chan, "vm-ny");
8639  res = res ? res : ast_play_and_wait(chan, "vm-message");
8640  } else {
8641  res = say_and_wait(chan, vms->newmessages, chan->language);
8642  res = res ? res : ast_play_and_wait(chan, "vm-nye");
8643  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8644  }
8645  if (!res && vms->oldmessages)
8646  res = ast_play_and_wait(chan, "vm-and");
8647  }
8648  if (!res && vms->oldmessages) {
8649  if (vms->oldmessages == 1) {
8650  res = ast_play_and_wait(chan, "digits/1");
8651  res = res ? res : ast_play_and_wait(chan, "vm-gamel");
8652  res = res ? res : ast_play_and_wait(chan, "vm-message");
8653  } else {
8654  res = say_and_wait(chan, vms->oldmessages, chan->language);
8655  res = res ? res : ast_play_and_wait(chan, "vm-gamle");
8656  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8657  }
8658  }
8659 
8660  return res;
8661 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8505 of file app_voicemail_imapstorage.c.

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

Referenced by vm_intro().

8506 {
8507  /* Introduce messages they have */
8508  int res;
8509  div_t num;
8510 
8511  if (!vms->oldmessages && !vms->newmessages) {
8512  res = ast_play_and_wait(chan, "vm-no");
8513  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8514  return res;
8515  } else {
8516  res = ast_play_and_wait(chan, "vm-youhave");
8517  }
8518 
8519  if (vms->newmessages) {
8520  num = div(vms->newmessages, 10);
8521  if (vms->newmessages == 1) {
8522  res = ast_play_and_wait(chan, "digits/1-a");
8523  res = res ? res : ast_play_and_wait(chan, "vm-new-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->newmessages - 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->newmessages, chan->language);
8535  }
8536  res = res ? res : ast_play_and_wait(chan, "vm-new-e");
8537  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8538  } else {
8539  res = say_and_wait(chan, vms->newmessages, chan->language);
8540  res = res ? res : ast_play_and_wait(chan, "vm-new-ych");
8541  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8542  }
8543  if (!res && vms->oldmessages)
8544  res = ast_play_and_wait(chan, "vm-and");
8545  }
8546  if (!res && vms->oldmessages) {
8547  num = div(vms->oldmessages, 10);
8548  if (vms->oldmessages == 1) {
8549  res = ast_play_and_wait(chan, "digits/1-a");
8550  res = res ? res : ast_play_and_wait(chan, "vm-old-a");
8551  res = res ? res : ast_play_and_wait(chan, "vm-message");
8552  } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) {
8553  if (num.rem == 2) {
8554  if (!num.quot) {
8555  res = ast_play_and_wait(chan, "digits/2-ie");
8556  } else {
8557  res = say_and_wait(chan, vms->oldmessages - 2 , chan->language);
8558  res = res ? res : ast_play_and_wait(chan, "digits/2-ie");
8559  }
8560  } else {
8561  res = say_and_wait(chan, vms->oldmessages, chan->language);
8562  }
8563  res = res ? res : ast_play_and_wait(chan, "vm-old-e");
8564  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8565  } else {
8566  res = say_and_wait(chan, vms->oldmessages, chan->language);
8567  res = res ? res : ast_play_and_wait(chan, "vm-old-ych");
8568  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8569  }
8570  }
8571 
8572  return res;
8573 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 8905 of file app_voicemail_imapstorage.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().

8906 {
8907  /* Introduce messages they have */
8908  int res;
8909  res = ast_play_and_wait(chan, "vm-youhave");
8910  if (!res) {
8911  if (vms->newmessages) {
8912  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
8913  if (!res) {
8914  if ((vms->newmessages == 1)) {
8915  res = ast_play_and_wait(chan, "vm-message");
8916  if (!res)
8917  res = ast_play_and_wait(chan, "vm-INBOXs");
8918  } else {
8919  res = ast_play_and_wait(chan, "vm-messages");
8920  if (!res)
8921  res = ast_play_and_wait(chan, "vm-INBOX");
8922  }
8923  }
8924  if (vms->oldmessages && !res)
8925  res = ast_play_and_wait(chan, "vm-and");
8926  }
8927  if (!res && vms->oldmessages) {
8928  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8929  if (!res) {
8930  if (vms->oldmessages == 1) {
8931  res = ast_play_and_wait(chan, "vm-message");
8932  if (!res)
8933  res = ast_play_and_wait(chan, "vm-Olds");
8934  } else {
8935  res = ast_play_and_wait(chan, "vm-messages");
8936  if (!res)
8937  res = ast_play_and_wait(chan, "vm-Old");
8938  }
8939  }
8940  }
8941  if (!res) {
8942  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8943  res = ast_play_and_wait(chan, "vm-no");
8944  if (!res)
8945  res = ast_play_and_wait(chan, "vm-messages");
8946  }
8947  }
8948  }
8949  return res;
8950 }
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 8766 of file app_voicemail_imapstorage.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().

8766  {
8767  /* Introduce messages they have */
8768  int res;
8769  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8770  res = ast_play_and_wait(chan, "vm-nomessages");
8771  return res;
8772  } else {
8773  res = ast_play_and_wait(chan, "vm-youhave");
8774  }
8775  if (vms->newmessages) {
8776  if (!res)
8777  res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f");
8778  if ((vms->newmessages == 1)) {
8779  if (!res)
8780  res = ast_play_and_wait(chan, "vm-message");
8781  if (!res)
8782  res = ast_play_and_wait(chan, "vm-INBOXs");
8783  } else {
8784  if (!res)
8785  res = ast_play_and_wait(chan, "vm-messages");
8786  if (!res)
8787  res = ast_play_and_wait(chan, "vm-INBOX");
8788  }
8789  if (vms->oldmessages && !res)
8790  res = ast_play_and_wait(chan, "vm-and");
8791  }
8792  if (vms->oldmessages) {
8793  if (!res)
8794  res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f");
8795  if (vms->oldmessages == 1) {
8796  if (!res)
8797  res = ast_play_and_wait(chan, "vm-message");
8798  if (!res)
8799  res = ast_play_and_wait(chan, "vm-Olds");
8800  } else {
8801  if (!res)
8802  res = ast_play_and_wait(chan, "vm-messages");
8803  if (!res)
8804  res = ast_play_and_wait(chan, "vm-Old");
8805  }
8806  }
8807  return res;
8808 }
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 8576 of file app_voicemail_imapstorage.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().

8577 {
8578  /* Introduce messages they have */
8579  int res;
8580 
8581  res = ast_play_and_wait(chan, "vm-youhave");
8582  if (res)
8583  return res;
8584 
8585  if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) {
8586  res = ast_play_and_wait(chan, "vm-no");
8587  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8588  return res;
8589  }
8590 
8591  if (vms->newmessages) {
8592  if ((vms->newmessages == 1)) {
8593  res = ast_play_and_wait(chan, "digits/ett");
8594  res = res ? res : ast_play_and_wait(chan, "vm-nytt");
8595  res = res ? res : ast_play_and_wait(chan, "vm-message");
8596  } else {
8597  res = say_and_wait(chan, vms->newmessages, chan->language);
8598  res = res ? res : ast_play_and_wait(chan, "vm-nya");
8599  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8600  }
8601  if (!res && vms->oldmessages)
8602  res = ast_play_and_wait(chan, "vm-and");
8603  }
8604  if (!res && vms->oldmessages) {
8605  if (vms->oldmessages == 1) {
8606  res = ast_play_and_wait(chan, "digits/ett");
8607  res = res ? res : ast_play_and_wait(chan, "vm-gammalt");
8608  res = res ? res : ast_play_and_wait(chan, "vm-message");
8609  } else {
8610  res = say_and_wait(chan, vms->oldmessages, chan->language);
8611  res = res ? res : ast_play_and_wait(chan, "vm-gamla");
8612  res = res ? res : ast_play_and_wait(chan, "vm-messages");
8613  }
8614  }
8615 
8616  return res;
8617 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 9068 of file app_voicemail_imapstorage.c.

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

Referenced by vm_intro().

9069 {
9070  int res;
9071 
9072  /* Introduce messages they have */
9073  res = ast_play_and_wait(chan, "vm-youhave");
9074  if (!res) {
9075  if (vms->newmessages) {
9076  res = say_and_wait(chan, vms->newmessages, chan->language);
9077  if (!res)
9078  res = ast_play_and_wait(chan, "vm-INBOX");
9079  if (vms->oldmessages && !res)
9080  res = ast_play_and_wait(chan, "vm-and");
9081  }
9082  if (!res && vms->oldmessages) {
9083  res = say_and_wait(chan, vms->oldmessages, chan->language);
9084  if (!res)
9085  res = ast_play_and_wait(chan, "vm-Old");
9086  }
9087  if (!res) {
9088  if (!vms->oldmessages && !vms->newmessages) {
9089  res = ast_play_and_wait(chan, "vm-no");
9090  if (!res)
9091  res = ast_play_and_wait(chan, "vm-message");
9092  }
9093  }
9094  }
9095  return res;
9096 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 9029 of file app_voicemail_imapstorage.c.

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

Referenced by vm_intro().

9030 {
9031  int res;
9032  /* Introduce messages they have */
9033  res = ast_play_and_wait(chan, "vm-you");
9034 
9035  if (!res && vms->newmessages) {
9036  res = ast_play_and_wait(chan, "vm-have");
9037  if (!res)
9038  res = say_and_wait(chan, vms->newmessages, chan->language);
9039  if (!res)
9040  res = ast_play_and_wait(chan, "vm-tong");
9041  if (!res)
9042  res = ast_play_and_wait(chan, "vm-INBOX");
9043  if (vms->oldmessages && !res)
9044  res = ast_play_and_wait(chan, "vm-and");
9045  else if (!res)
9046  res = ast_play_and_wait(chan, "vm-messages");
9047  }
9048  if (!res && vms->oldmessages) {
9049  res = ast_play_and_wait(chan, "vm-have");
9050  if (!res)
9051  res = say_and_wait(chan, vms->oldmessages, chan->language);
9052  if (!res)
9053  res = ast_play_and_wait(chan, "vm-tong");
9054  if (!res)
9055  res = ast_play_and_wait(chan, "vm-Old");
9056  if (!res)
9057  res = ast_play_and_wait(chan, "vm-messages");
9058  }
9059  if (!res && !vms->oldmessages && !vms->newmessages) {
9060  res = ast_play_and_wait(chan, "vm-haveno");
9061  if (!res)
9062  res = ast_play_and_wait(chan, "vm-messages");
9063  }
9064  return res;
9065 }
int oldmessages
static int say_and_wait(struct ast_channel *chan, int num, const char *language)
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 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 3312 of file app_voicemail_imapstorage.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().

3313 {
3314  switch (ast_lock_path(path)) {
3315  case AST_LOCK_TIMEOUT:
3316  return -1;
3317  default:
3318  return 0;
3319  }
3320 }
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 1683 of file app_voicemail_imapstorage.c.

References VOICEMAIL_FILE_MODE.

Referenced by sendmail(), and sendpage().

1684 {
1685  FILE *p = NULL;
1686  int pfd = mkstemp(template);
1687  chmod(template, VOICEMAIL_FILE_MODE & ~my_umask);
1688  if (pfd > -1) {
1689  p = fdopen(pfd, "w+");
1690  if (!p) {
1691  close(pfd);
1692  pfd = -1;
1693  }
1694  }
1695  return p;
1696 }
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 9282 of file app_voicemail_imapstorage.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().

9283 {
9284  int cmd = 0;
9285  int duration = 0;
9286  int tries = 0;
9287  char newpassword[80] = "";
9288  char newpassword2[80] = "";
9289  char prefile[PATH_MAX] = "";
9290  unsigned char buf[256];
9291  int bytes = 0;
9292 
9293  ast_test_suite_event_notify("NEWUSER", "Message: entering new user state");
9294  if (ast_adsi_available(chan)) {
9295  bytes += adsi_logo(buf + bytes);
9296  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", "");
9297  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
9298  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
9299  bytes += ast_adsi_voice_mode(buf + bytes, 0);
9300  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
9301  }
9302 
9303  /* If forcename is set, have the user record their name */
9304  if (ast_test_flag(vmu, VM_FORCENAME)) {
9305  snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
9306  if (ast_fileexists(prefile, NULL, NULL) < 1) {
9307  cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9308  if (cmd < 0 || cmd == 't' || cmd == '#')
9309  return cmd;
9310  }
9311  }
9312 
9313  /* If forcegreetings is set, have the user record their greetings */
9314  if (ast_test_flag(vmu, VM_FORCEGREET)) {
9315  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
9316  if (ast_fileexists(prefile, NULL, NULL) < 1) {
9317  cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9318  if (cmd < 0 || cmd == 't' || cmd == '#')
9319  return cmd;
9320  }
9321 
9322  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
9323  if (ast_fileexists(prefile, NULL, NULL) < 1) {
9324  cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9325  if (cmd < 0 || cmd == 't' || cmd == '#')
9326  return cmd;
9327  }
9328  }
9329 
9330  /*
9331  * Change the password last since new users will be able to skip over any steps this one comes before
9332  * by hanging up and calling back to voicemail main since the password is used to verify new user status.
9333  */
9334  for (;;) {
9335  newpassword[1] = '\0';
9336  newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword);
9337  if (cmd == '#')
9338  newpassword[0] = '\0';
9339  if (cmd < 0 || cmd == 't' || cmd == '#')
9340  return cmd;
9341  cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#");
9342  if (cmd < 0 || cmd == 't' || cmd == '#')
9343  return cmd;
9344  cmd = check_password(vmu, newpassword); /* perform password validation */
9345  if (cmd != 0) {
9346  ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword);
9348  } else {
9349  newpassword2[1] = '\0';
9350  newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword);
9351  if (cmd == '#')
9352  newpassword2[0] = '\0';
9353  if (cmd < 0 || cmd == 't' || cmd == '#')
9354  return cmd;
9355  cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#");
9356  if (cmd < 0 || cmd == 't' || cmd == '#')
9357  return cmd;
9358  if (!strcmp(newpassword, newpassword2))
9359  break;
9360  ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
9361  cmd = ast_play_and_wait(chan, vm_mismatch);
9362  }
9363  if (++tries == 3)
9364  return -1;
9365  if (cmd != 0) {
9366  cmd = ast_play_and_wait(chan, vm_pls_try_again);
9367  }
9368  }
9370  vm_change_password(vmu, newpassword);
9372  vm_change_password_shell(vmu, newpassword);
9373 
9374  ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword));
9375  cmd = ast_play_and_wait(chan, vm_passchanged);
9376 
9377  return cmd;
9378 }
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 VM_FORCEGREET
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
The handler for the change password option.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define VM_FORCENAME
static char VM_SPOOL_DIR[PATH_MAX]
#define ADSI_COMM_PAGE
Definition: adsi.h:107
static int adsi_logo(unsigned char *buf)
#define AST_LOG_NOTICE
Definition: logger.h:138
static int pwdchange
#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 char vm_mismatch[80]
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char username[80]
char context[AST_MAX_CONTEXT]
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 vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
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
static int check_password(struct ast_vm_user *vmu, char *password)
Check that password meets minimum required length.
static char vm_newpassword[80]
#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
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_reenterpassword[80]
#define PWDCHANGE_EXTERNAL
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_invalid_password[80]
#define PWDCHANGE_INTERNAL
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 maxgreet
#define ADSI_JUST_CENT
Definition: adsi.h:114
static char vm_pls_try_again[80]
static char vm_passchanged[80]
static char ext_pass_cmd[128]
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 9380 of file app_voicemail_imapstorage.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().

9381 {
9382  int cmd = 0;
9383  int retries = 0;
9384  int duration = 0;
9385  char newpassword[80] = "";
9386  char newpassword2[80] = "";
9387  char prefile[PATH_MAX] = "";
9388  unsigned char buf[256];
9389  int bytes = 0;
9390 
9391  ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options");
9392  if (ast_adsi_available(chan)) {
9393  bytes += adsi_logo(buf + bytes);
9394  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", "");
9395  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
9396  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
9397  bytes += ast_adsi_voice_mode(buf + bytes, 0);
9398  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
9399  }
9400  while ((cmd >= 0) && (cmd != 't')) {
9401  if (cmd)
9402  retries = 0;
9403  switch (cmd) {
9404  case '1': /* Record your unavailable message */
9405  snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username);
9406  cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9407  break;
9408  case '2': /* Record your busy message */
9409  snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username);
9410  cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9411  break;
9412  case '3': /* Record greeting */
9413  snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username);
9414  cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9415  break;
9416  case '4': /* manage the temporary greeting */
9417  cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain);
9418  break;
9419  case '5': /* change password */
9420  if (vmu->password[0] == '-') {
9421  cmd = ast_play_and_wait(chan, "vm-no");
9422  break;
9423  }
9424  newpassword[1] = '\0';
9425  newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword);
9426  if (cmd == '#')
9427  newpassword[0] = '\0';
9428  else {
9429  if (cmd < 0)
9430  break;
9431  if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) {
9432  break;
9433  }
9434  }
9435  cmd = check_password(vmu, newpassword); /* perform password validation */
9436  if (cmd != 0) {
9437  ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword);
9439  if (!cmd) {
9440  cmd = ast_play_and_wait(chan, vm_pls_try_again);
9441  }
9442  break;
9443  }
9444  newpassword2[1] = '\0';
9445  newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword);
9446  if (cmd == '#')
9447  newpassword2[0] = '\0';
9448  else {
9449  if (cmd < 0)
9450  break;
9451 
9452  if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) {
9453  break;
9454  }
9455  }
9456  if (strcmp(newpassword, newpassword2)) {
9457  ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2);
9458  cmd = ast_play_and_wait(chan, vm_mismatch);
9459  if (!cmd) {
9460  cmd = ast_play_and_wait(chan, vm_pls_try_again);
9461  }
9462  break;
9463  }
9464 
9465  if (pwdchange & PWDCHANGE_INTERNAL) {
9466  vm_change_password(vmu, newpassword);
9467  }
9469  vm_change_password_shell(vmu, newpassword);
9470  }
9471 
9472  ast_debug(1, "User %s set password to %s of length %d\n",
9473  vms->username, newpassword, (int) strlen(newpassword));
9474  cmd = ast_play_and_wait(chan, vm_passchanged);
9475  break;
9476  case '*':
9477  cmd = 't';
9478  break;
9479  default:
9480  cmd = 0;
9481  snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
9482  RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
9483  if (ast_fileexists(prefile, NULL, NULL)) {
9484  cmd = ast_play_and_wait(chan, "vm-tmpexists");
9485  }
9486  DISPOSE(prefile, -1);
9487  if (!cmd) {
9488  cmd = ast_play_and_wait(chan, "vm-options");
9489  }
9490  if (!cmd) {
9491  cmd = ast_waitfordigit(chan, 6000);
9492  }
9493  if (!cmd) {
9494  retries++;
9495  }
9496  if (retries > 3) {
9497  cmd = 't';
9498  }
9499  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
9500  }
9501  }
9502  if (cmd == 't')
9503  cmd = 0;
9504  return cmd;
9505 }
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 RETRIEVE(a, b, c, d)
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
The handler for the change password option.
static char VM_SPOOL_DIR[PATH_MAX]
#define ADSI_COMM_PAGE
Definition: adsi.h:107
static int adsi_logo(unsigned char *buf)
#define AST_LOG_NOTICE
Definition: logger.h:138
static int pwdchange
#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 char vm_mismatch[80]
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char mailbox[AST_MAX_EXTENSION]
char username[80]
char context[AST_MAX_CONTEXT]
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 vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
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
static int check_password(struct ast_vm_user *vmu, char *password)
Check that password meets minimum required length.
static char vm_newpassword[80]
#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
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_reenterpassword[80]
#define PWDCHANGE_EXTERNAL
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
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_invalid_password[80]
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;.
#define PWDCHANGE_INTERNAL
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 maxgreet
#define ADSI_JUST_CENT
Definition: adsi.h:114
static char vm_pls_try_again[80]
static char vm_passchanged[80]
char password[80]
#define DISPOSE(a, b)
static char ext_pass_cmd[128]
static int vm_play_folder_name ( struct ast_channel chan,
char *  mbox 
)
static

Definition at line 8175 of file app_voicemail_imapstorage.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().

8176 {
8177  int cmd;
8178 
8179  if ( !strncasecmp(chan->language, "it", 2) ||
8180  !strncasecmp(chan->language, "es", 2) ||
8181  !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */
8182  cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */
8183  return cmd ? cmd : ast_play_and_wait(chan, box);
8184  } else if (!strncasecmp(chan->language, "gr", 2)) {
8185  return vm_play_folder_name_gr(chan, box);
8186  } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */
8187  return ast_play_and_wait(chan, box);
8188  } else if (!strncasecmp(chan->language, "pl", 2)) {
8189  return vm_play_folder_name_pl(chan, box);
8190  } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */
8191  return vm_play_folder_name_ua(chan, box);
8192  } else if (!strncasecmp(chan->language, "vi", 2)) {
8193  return ast_play_and_wait(chan, box);
8194  } else { /* Default English */
8195  cmd = ast_play_and_wait(chan, box);
8196  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */
8197  }
8198 }
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 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)
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 8128 of file app_voicemail_imapstorage.c.

References ast_alloca, and ast_play_and_wait().

Referenced by vm_play_folder_name().

8129 {
8130  int cmd;
8131  char *buf;
8132 
8133  buf = ast_alloca(strlen(box) + 2);
8134  strcpy(buf, box);
8135  strcat(buf, "s");
8136 
8137  if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){
8138  cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */
8139  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
8140  } else {
8141  cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */
8142  return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/
8143  }
8144 }
#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 8146 of file app_voicemail_imapstorage.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

8147 {
8148  int cmd;
8149 
8150  if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) {
8151  if (!strcasecmp(box, "vm-INBOX"))
8152  cmd = ast_play_and_wait(chan, "vm-new-e");
8153  else
8154  cmd = ast_play_and_wait(chan, "vm-old-e");
8155  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
8156  } else {
8157  cmd = ast_play_and_wait(chan, "vm-messages");
8158  return cmd ? cmd : ast_play_and_wait(chan, box);
8159  }
8160 }
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 8162 of file app_voicemail_imapstorage.c.

References ast_play_and_wait().

Referenced by vm_play_folder_name().

8163 {
8164  int cmd;
8165 
8166  if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){
8167  cmd = ast_play_and_wait(chan, "vm-messages");
8168  return cmd ? cmd : ast_play_and_wait(chan, box);
8169  } else {
8170  cmd = ast_play_and_wait(chan, box);
8171  return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
8172  }
8173 }
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 9523 of file app_voicemail_imapstorage.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().

9524 {
9525  int cmd = 0;
9526  int retries = 0;
9527  int duration = 0;
9528  char prefile[PATH_MAX] = "";
9529  unsigned char buf[256];
9530  int bytes = 0;
9531 
9532  if (ast_adsi_available(chan)) {
9533  bytes += adsi_logo(buf + bytes);
9534  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", "");
9535  bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", "");
9536  bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1);
9537  bytes += ast_adsi_voice_mode(buf + bytes, 0);
9538  ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY);
9539  }
9540 
9541  ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options");
9542  snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username);
9543  while ((cmd >= 0) && (cmd != 't')) {
9544  if (cmd)
9545  retries = 0;
9546  RETRIEVE(prefile, -1, vmu->mailbox, vmu->context);
9547  if (ast_fileexists(prefile, NULL, NULL) <= 0) {
9548  cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9549  if (cmd == -1) {
9550  break;
9551  }
9552  cmd = 't';
9553  } else {
9554  switch (cmd) {
9555  case '1':
9556  cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL);
9557  break;
9558  case '2':
9559  DELETE(prefile, -1, prefile, vmu);
9560  ast_play_and_wait(chan, "vm-tempremoved");
9561  cmd = 't';
9562  break;
9563  case '*':
9564  cmd = 't';
9565  break;
9566  default:
9567  cmd = ast_play_and_wait(chan,
9568  ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */
9569  "vm-tempgreeting2" : "vm-tempgreeting");
9570  if (!cmd) {
9571  cmd = ast_waitfordigit(chan, 6000);
9572  }
9573  if (!cmd) {
9574  retries++;
9575  }
9576  if (retries > 3) {
9577  cmd = 't';
9578  }
9579  ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd);
9580  }
9581  }
9582  DISPOSE(prefile, -1);
9583  }
9584  if (cmd == 't')
9585  cmd = 0;
9586  return cmd;
9587 }
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 RETRIEVE(a, b, c, d)
static char VM_SPOOL_DIR[PATH_MAX]
#define ADSI_COMM_PAGE
Definition: adsi.h:107
static int adsi_logo(unsigned char *buf)
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]
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_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
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
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 int maxgreet
#define DELETE(a, b, c, d)
#define ADSI_JUST_CENT
Definition: adsi.h:114
#define DISPOSE(a, b)
static int vm_users_data_provider_get ( const struct ast_data_search search,
struct ast_data data_root 
)
static

Definition at line 11392 of file app_voicemail_imapstorage.c.

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

11394 {
11395  struct ast_vm_user *user;
11396 
11397  AST_LIST_LOCK(&users);
11398  AST_LIST_TRAVERSE(&users, user, list) {
11399  vm_users_data_provider_get_helper(search, data_root, user);
11400  }
11402 
11403  return 0;
11404 }
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
#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 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 11345 of file app_voicemail_imapstorage.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().

11347 {
11348  struct ast_data *data_user, *data_zone;
11349  struct ast_data *data_state;
11350  struct vm_zone *zone = NULL;
11351  int urgentmsg = 0, newmsg = 0, oldmsg = 0;
11352  char ext_context[256] = "";
11353 
11354  data_user = ast_data_add_node(data_root, "user");
11355  if (!data_user) {
11356  return -1;
11357  }
11358 
11359  ast_data_add_structure(ast_vm_user, data_user, user);
11360 
11361  AST_LIST_LOCK(&zones);
11362  AST_LIST_TRAVERSE(&zones, zone, list) {
11363  if (!strcmp(zone->name, user->zonetag)) {
11364  break;
11365  }
11366  }
11368 
11369  /* state */
11370  data_state = ast_data_add_node(data_user, "state");
11371  if (!data_state) {
11372  return -1;
11373  }
11374  snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context);
11375  inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg);
11376  ast_data_add_int(data_state, "urgentmsg", urgentmsg);
11377  ast_data_add_int(data_state, "newmsg", newmsg);
11378  ast_data_add_int(data_state, "oldmsg", oldmsg);
11379 
11380  if (zone) {
11381  data_zone = ast_data_add_node(data_user, "zone");
11382  ast_data_add_structure(vm_zone, data_zone, zone);
11383  }
11384 
11385  if (!ast_data_search_match(search, data_user)) {
11386  ast_data_remove_node(data_root, data_user);
11387  }
11388 
11389  return 0;
11390 }
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 11031 of file app_voicemail_imapstorage.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().

11032 {
11033  char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = "";
11034  struct ast_vm_user vmus;
11035  char *options = NULL;
11036  int silent = 0, skipuser = 0;
11037  int res = -1;
11038 
11039  if (data) {
11040  s = ast_strdupa(data);
11041  user = strsep(&s, ",");
11042  options = strsep(&s, ",");
11043  if (user) {
11044  s = user;
11045  user = strsep(&s, "@");
11046  context = strsep(&s, "");
11047  if (!ast_strlen_zero(user))
11048  skipuser++;
11049  ast_copy_string(mailbox, user, sizeof(mailbox));
11050  }
11051  }
11052 
11053  if (options) {
11054  silent = (strchr(options, 's')) != NULL;
11055  }
11056 
11057  if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
11058  pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
11059  pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
11060  ast_play_and_wait(chan, "auth-thankyou");
11061  res = 0;
11062  } else if (mailbox[0] == '*') {
11063  /* user entered '*' */
11064  if (!ast_goto_if_exists(chan, chan->context, "a", 1)) {
11065  res = 0; /* prevent hangup */
11066  }
11067  }
11068 
11069  return res;
11070 }
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
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 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 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 12571 of file app_voicemail_imapstorage.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().

12572 {
12573  char *context;
12574  char *args_copy;
12575  int res;
12576 
12577  if (ast_strlen_zero(data)) {
12578  ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n");
12579  return -1;
12580  }
12581 
12582  args_copy = ast_strdupa(data);
12583  if ((context = strchr(args_copy, '@'))) {
12584  *context++ = '\0';
12585  } else {
12586  context = "default";
12587  }
12588 
12589  if ((res = sayname(chan, args_copy, context) < 0)) {
12590  ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context);
12591  res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY);
12592  if (!res) {
12593  res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language);
12594  }
12595  }
12596 
12597  return res;
12598 }
#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 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 int sayname(struct ast_channel *chan, const char *mailbox, const char *context)
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 4469 of file app_voicemail_imapstorage.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().

4470 {
4471  const struct vm_zone *z = NULL;
4472  struct timeval t = ast_tvnow();
4473 
4474  /* Does this user have a timezone specified? */
4475  if (!ast_strlen_zero(vmu->zonetag)) {
4476  /* Find the zone in the list */
4477  AST_LIST_LOCK(&zones);
4478  AST_LIST_TRAVERSE(&zones, z, list) {
4479  if (!strcmp(z->name, vmu->zonetag))
4480  break;
4481  }
4483  }
4484  ast_localtime(&t, tm, z ? z->timezone : NULL);
4485  return tm;
4486 }
#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 7524 of file app_voicemail_imapstorage.c.

References ast_control_streamfile(), and ast_test_suite_event_notify.

Referenced by advanced_options(), and play_message().

7525 {
7526  ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file);
7528 }
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 int skipms
static char listen_control_restart_key[12]
static char listen_control_forward_key[12]
#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 char listen_control_pause_key[12]
static int wait_file2 ( struct ast_channel chan,
struct vm_state vms,
char *  file 
)
static

Definition at line 7516 of file app_voicemail_imapstorage.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().

7517 {
7518  int res;
7519  if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0)
7520  ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file);
7521  return res;
7522 }
#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 12538 of file app_voicemail_imapstorage.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().

12538  {
12539  struct ast_config *conf;
12540  struct ast_category *cat;
12541  struct ast_variable *var;
12542  int res = -1;
12543 
12544  if (!(conf = ast_config_new())) {
12545  ast_log(LOG_ERROR, "Error creating new config structure\n");
12546  return res;
12547  }
12548  if (!(cat = ast_category_new("general", "", 1))) {
12549  ast_log(LOG_ERROR, "Error creating new category structure\n");
12550  ast_config_destroy(conf);
12551  return res;
12552  }
12553  if (!(var = ast_variable_new("password", password, ""))) {
12554  ast_log(LOG_ERROR, "Error creating new variable structure\n");
12555  ast_config_destroy(conf);
12556  ast_category_destroy(cat);
12557  return res;
12558  }
12559  ast_category_append(conf, cat);
12560  ast_variable_append(cat, var);
12561  if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) {
12562  res = 0;
12563  } else {
12564  ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn);
12565  }
12566 
12567  ast_config_destroy(conf);
12568  return res;
12569 }
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 13651 of file app_voicemail_imapstorage.c.

char* addesc = "Comedian Mail"
static

Definition at line 777 of file app_voicemail_imapstorage.c.

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

Definition at line 904 of file app_voicemail_imapstorage.c.

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

Definition at line 905 of file app_voicemail_imapstorage.c.

int adsiver = 1
static

Definition at line 906 of file app_voicemail_imapstorage.c.

char* app = "VoiceMail"
static

Definition at line 780 of file app_voicemail_imapstorage.c.

char* app2 = "VoiceMailMain"
static

Definition at line 783 of file app_voicemail_imapstorage.c.

char* app3 = "MailboxExists"
static

Definition at line 785 of file app_voicemail_imapstorage.c.

char* app4 = "VMAuthenticate"
static

Definition at line 786 of file app_voicemail_imapstorage.c.

Definition at line 13651 of file app_voicemail_imapstorage.c.

char callcontext[AST_MAX_CONTEXT] = ""
static

Definition at line 890 of file app_voicemail_imapstorage.c.

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

Definition at line 902 of file app_voicemail_imapstorage.c.

char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64]
static

Definition at line 893 of file app_voicemail_imapstorage.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_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_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Reload voicemail configuration from 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 11270 of file app_voicemail_imapstorage.c.

char dialcontext[AST_MAX_CONTEXT] = ""
static

Definition at line 889 of file app_voicemail_imapstorage.c.

char* emailbody = NULL
static

Definition at line 896 of file app_voicemail_imapstorage.c.

Referenced by make_email_file().

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

Definition at line 907 of file app_voicemail_imapstorage.c.

char* emailsubject = NULL
static

Definition at line 897 of file app_voicemail_imapstorage.c.

Referenced by make_email_file().

char exitcontext[AST_MAX_CONTEXT] = ""
static

Definition at line 891 of file app_voicemail_imapstorage.c.

char ext_pass_check_cmd[128]
static

Definition at line 757 of file app_voicemail_imapstorage.c.

char ext_pass_cmd[128]
static

Definition at line 756 of file app_voicemail_imapstorage.c.

char externnotify[160]
static

Definition at line 800 of file app_voicemail_imapstorage.c.

char fromstring[100]
static

Definition at line 900 of file app_voicemail_imapstorage.c.

struct ast_flags globalflags = {0}
static

Definition at line 885 of file app_voicemail_imapstorage.c.

struct ao2_container* inprocess_container

Definition at line 929 of file app_voicemail_imapstorage.c.

char listen_control_forward_key[12]
static

Definition at line 858 of file app_voicemail_imapstorage.c.

char listen_control_pause_key[12]
static

Definition at line 860 of file app_voicemail_imapstorage.c.

char listen_control_restart_key[12]
static

Definition at line 861 of file app_voicemail_imapstorage.c.

char listen_control_reverse_key[12]
static

Definition at line 859 of file app_voicemail_imapstorage.c.

char listen_control_stop_key[12]
static

Definition at line 862 of file app_voicemail_imapstorage.c.

char locale[20]
static

Definition at line 793 of file app_voicemail_imapstorage.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 11026 of file app_voicemail_imapstorage.c.

const char* const mailbox_folders[]
static

Definition at line 1719 of file app_voicemail_imapstorage.c.

char mailcmd[160]
static

Definition at line 799 of file app_voicemail_imapstorage.c.

int maxdeletedmsg
static

Definition at line 796 of file app_voicemail_imapstorage.c.

Referenced by populate_defaults().

int maxgreet
static

Definition at line 806 of file app_voicemail_imapstorage.c.

int maxlogins
static

Definition at line 808 of file app_voicemail_imapstorage.c.

int maxmsg
static

Definition at line 795 of file app_voicemail_imapstorage.c.

Referenced by populate_defaults().

int maxsilence
static

Definition at line 794 of file app_voicemail_imapstorage.c.

int minpassword
static

Definition at line 809 of file app_voicemail_imapstorage.c.

struct ast_event_sub* mwi_sub_sub
static

Subscription to ... MWI event subscriptions

Definition at line 827 of file app_voicemail_imapstorage.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 853 of file app_voicemail_imapstorage.c.

struct ast_event_sub* mwi_unsub_sub
static

Subscription to ... MWI event un-subscriptions

Definition at line 829 of file app_voicemail_imapstorage.c.

int my_umask
static

Definition at line 759 of file app_voicemail_imapstorage.c.

char* pagerbody = NULL
static

Definition at line 898 of file app_voicemail_imapstorage.c.

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

Definition at line 908 of file app_voicemail_imapstorage.c.

char pagerfromstring[100]
static

Definition at line 901 of file app_voicemail_imapstorage.c.

char* pagersubject = NULL
static

Definition at line 899 of file app_voicemail_imapstorage.c.

int passwordlocation
static

Definition at line 810 of file app_voicemail_imapstorage.c.

Referenced by populate_defaults().

ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER
static

Definition at line 822 of file app_voicemail_imapstorage.c.

unsigned int poll_freq
static

Polling frequency

Definition at line 817 of file app_voicemail_imapstorage.c.

ast_mutex_t poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 821 of file app_voicemail_imapstorage.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 814 of file app_voicemail_imapstorage.c.

pthread_t poll_thread = AST_PTHREADT_NULL
static

Definition at line 823 of file app_voicemail_imapstorage.c.

unsigned char poll_thread_run
static

Definition at line 824 of file app_voicemail_imapstorage.c.

int pwdchange = PWDCHANGE_INTERNAL
static

Definition at line 763 of file app_voicemail_imapstorage.c.

int saydurationminfo
static

Definition at line 887 of file app_voicemail_imapstorage.c.

Referenced by populate_defaults().

char* sayname_app = "VMSayName"
static

Definition at line 788 of file app_voicemail_imapstorage.c.

char serveremail[80]
static

Definition at line 798 of file app_voicemail_imapstorage.c.

Referenced by forward_message(), and notify_new_message().

int silencethreshold = 128
static

Definition at line 797 of file app_voicemail_imapstorage.c.

int skipms
static

Definition at line 807 of file app_voicemail_imapstorage.c.

struct ast_smdi_interface* smdi_iface = NULL
static

Definition at line 801 of file app_voicemail_imapstorage.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 775 of file app_voicemail_imapstorage.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 540 of file app_voicemail_imapstorage.c.

Referenced by vm_exec(), and vm_execmain().

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

Definition at line 11411 of file app_voicemail_imapstorage.c.

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

Definition at line 870 of file app_voicemail_imapstorage.c.

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

Definition at line 869 of file app_voicemail_imapstorage.c.

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

Definition at line 866 of file app_voicemail_imapstorage.c.

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

Definition at line 867 of file app_voicemail_imapstorage.c.

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

Definition at line 865 of file app_voicemail_imapstorage.c.

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

Definition at line 871 of file app_voicemail_imapstorage.c.

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

Definition at line 883 of file app_voicemail_imapstorage.c.

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

Definition at line 868 of file app_voicemail_imapstorage.c.

char VM_SPOOL_DIR[PATH_MAX]
static

Definition at line 754 of file app_voicemail_imapstorage.c.

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

Definition at line 11406 of file app_voicemail_imapstorage.c.

char vmfmts[80]
static

Definition at line 802 of file app_voicemail_imapstorage.c.

int vmmaxsecs
static

Definition at line 805 of file app_voicemail_imapstorage.c.

Referenced by apply_option(), and populate_defaults().

int vmminsecs
static

Definition at line 804 of file app_voicemail_imapstorage.c.

Referenced by apply_option(), and populate_defaults().

double volgain
static

Definition at line 803 of file app_voicemail_imapstorage.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 792 of file app_voicemail_imapstorage.c.