#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 |
Defines | |
#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 |
#define | STORE(a, b, c, d, e, f, g, h, i, j) |
#define | tdesc "Comedian Mail (Voicemail System)" |
#define | VALID_DTMF "1234567890*#" |
#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 } |
enum | vm_option_args { 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) } |
enum | vm_passwordlocation { 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. | |
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. | |
static void | apply_options (struct ast_vm_user *vmu, const char *options) |
Destructively Parse options and apply. | |
static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
Loads the options specific to a voicemail user. | |
AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
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. | |
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. | |
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. | |
static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
Performs a change of the voicemail passowrd in the realtime engine. | |
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. | |
static int | check_password (struct ast_vm_user *vmu, char *password) |
Check that password meets minimum required length. | |
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. | |
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 void | copy_plain_file (char *frompath, char *topath) |
Copies a voicemail information (envelope) file. | |
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 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 | dialout (struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) |
static struct ast_vm_user * | find_or_create (const char *context, const char *box) |
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 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. | |
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. | |
static void | free_user (struct ast_vm_user *vmu) |
static void | free_vm_users (void) |
Free the users structure. | |
static void | free_vm_zones (void) |
Free the zones structure. | |
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. | |
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 | |
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 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. | |
static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail users in the CLI. | |
static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | has_voicemail (const char *mailbox, const char *folder) |
Determines if the given folder has messages. | |
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() | |
static int | inchar (struct baseio *bio, FILE *fi) |
utility used by base_encode() | |
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. | |
static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
Determines the highest message number in use for a given user and mailbox folder. | |
static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
Prompts the user and records a voicemail to a mailbox. | |
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. | |
static void | make_email_file (FILE *p, char *srcemail, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *attach, char *attach2, char *format, int duration, int attach_user_voicemail, struct ast_channel *chan, const char *category, int imap, const char *flag) |
Creates the email file to be sent to indicate a new voicemail exists for a user. | |
static 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. | |
static int | manager_list_voicemail_users (struct mansession *s, const struct message *m) |
Manager list voicemail users command. | |
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. | |
static int | ochar (struct baseio *bio, int c, FILE *so) |
utility used by base_encode() | |
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. | |
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. | |
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. | |
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. | |
static const char * | substitute_escapes (const char *value) |
static int | unload_module (void) |
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. | |
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. | |
static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Spanish syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Greek syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Italian syntax for 'You have N messages' greeting. | |
static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
Portuguese syntax for 'You have N messages' greeting. | |
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. | |
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. | |
static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
The handler for the change password option. | |
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. | |
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. | |
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. | |
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'. | |
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_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. | |
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 = "88eaa8f5c1bd988bedd71113385e0886" , .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_info * | ast_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} |
ao2_container * | inprocess_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_sub * | mwi_sub_sub |
static struct ast_taskprocessor * | mwi_subscription_tps |
static struct ast_event_sub * | mwi_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_interface * | smdi_iface = NULL |
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 char | zonetag [80] |
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.
#define ASTERISK_USERNAME "asterisk" |
Definition at line 438 of file app_voicemail_imapstorage.c.
#define BASELINELEN 72 |
Definition at line 461 of file app_voicemail_imapstorage.c.
#define BASEMAXINLINE 256 |
Definition at line 462 of file app_voicemail_imapstorage.c.
#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, | |||||
h | ) | (copy_plain_file(g,h)); |
Definition at line 749 of file app_voicemail_imapstorage.c.
#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, name, AST_DATA_STRING) \ ZONE(vm_zone, timezone, AST_DATA_STRING) \ ZONE(vm_zone, msg_format, AST_DATA_STRING)
Definition at line 11332 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 443 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 445 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 446 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 444 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 447 of file app_voicemail_imapstorage.c.
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 819 of file app_voicemail_imapstorage.c.
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 750 of file app_voicemail_imapstorage.c.
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 745 of file app_voicemail_imapstorage.c.
#define ENDL "\n" |
Definition at line 466 of file app_voicemail_imapstorage.c.
#define ERROR_LOCK_PATH -100 |
Definition at line 491 of file app_voicemail_imapstorage.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 747 of file app_voicemail_imapstorage.c.
#define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
#define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define INTRO "vm-intro" |
Definition at line 454 of file app_voicemail_imapstorage.c.
#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.
#define MAXMSG 100 |
Definition at line 456 of file app_voicemail_imapstorage.c.
#define MAXMSGLIMIT 9999 |
Definition at line 457 of file app_voicemail_imapstorage.c.
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 459 of file app_voicemail_imapstorage.c.
#define OPERATOR_EXIT 300 |
Definition at line 492 of file app_voicemail_imapstorage.c.
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 762 of file app_voicemail_imapstorage.c.
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 761 of file app_voicemail_imapstorage.c.
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 748 of file app_voicemail_imapstorage.c.
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 744 of file app_voicemail_imapstorage.c.
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 452 of file app_voicemail_imapstorage.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 429 of file app_voicemail_imapstorage.c.
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 746 of file app_voicemail_imapstorage.c.
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 771 of file app_voicemail_imapstorage.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 448 of file app_voicemail_imapstorage.c.
#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.
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 483 of file app_voicemail_imapstorage.c.
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 484 of file app_voicemail_imapstorage.c.
#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.
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 476 of file app_voicemail_imapstorage.c.
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 480 of file app_voicemail_imapstorage.c.
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 479 of file app_voicemail_imapstorage.c.
#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.
#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.
#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.
#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.
#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.
#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.
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 474 of file app_voicemail_imapstorage.c.
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 477 of file app_voicemail_imapstorage.c.
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 486 of file app_voicemail_imapstorage.c.
#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.
#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.
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 487 of file app_voicemail_imapstorage.c.
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 686 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 437 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 433 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 434 of file app_voicemail_imapstorage.c.
enum vm_box |
Definition at line 495 of file app_voicemail_imapstorage.c.
00495 { 00496 NEW_FOLDER, 00497 OLD_FOLDER, 00498 WORK_FOLDER, 00499 FAMILY_FOLDER, 00500 FRIENDS_FOLDER, 00501 GREETINGS_FOLDER 00502 };
enum vm_option_args |
Definition at line 516 of file app_voicemail_imapstorage.c.
00516 { 00517 OPT_ARG_RECORDGAIN = 0, 00518 OPT_ARG_PLAYFOLDER = 1, 00519 OPT_ARG_DTMFEXIT = 2, 00520 /* This *must* be the last value in this enum! */ 00521 OPT_ARG_ARRAY_SIZE = 3, 00522 };
enum vm_option_flags |
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.
00504 { 00505 OPT_SILENT = (1 << 0), 00506 OPT_BUSY_GREETING = (1 << 1), 00507 OPT_UNAVAIL_GREETING = (1 << 2), 00508 OPT_RECORDGAIN = (1 << 3), 00509 OPT_PREPEND_MAILBOX = (1 << 4), 00510 OPT_AUTOPLAY = (1 << 6), 00511 OPT_DTMFEXIT = (1 << 7), 00512 OPT_MESSAGE_Urgent = (1 << 8), 00513 OPT_MESSAGE_PRIORITY = (1 << 9) 00514 };
enum vm_passwordlocation |
Definition at line 524 of file app_voicemail_imapstorage.c.
00524 { 00525 OPT_PWLOC_VOICEMAILCONF = 0, 00526 OPT_PWLOC_SPOOLDIR = 1, 00527 OPT_PWLOC_USERSCONF = 2, 00528 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5380 of file app_voicemail_imapstorage.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
05381 { 05382 DIR *dir; 05383 struct dirent *de; 05384 char fn[256]; 05385 int ret = 0; 05386 05387 /* If no mailbox, return immediately */ 05388 if (ast_strlen_zero(mailbox)) 05389 return 0; 05390 05391 if (ast_strlen_zero(folder)) 05392 folder = "INBOX"; 05393 if (ast_strlen_zero(context)) 05394 context = "default"; 05395 05396 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05397 05398 if (!(dir = opendir(fn))) 05399 return 0; 05400 05401 while ((de = readdir(dir))) { 05402 if (!strncasecmp(de->d_name, "msg", 3)) { 05403 if (shortcircuit) { 05404 ret = 1; 05405 break; 05406 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05407 ret++; 05408 } 05409 } 05410 } 05411 05412 closedir(dir); 05413 05414 return ret; 05415 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13629 of file app_voicemail_imapstorage.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13629 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 11008 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().
11009 { 11010 struct ast_vm_user svm; 11011 AST_DECLARE_APP_ARGS(arg, 11012 AST_APP_ARG(mbox); 11013 AST_APP_ARG(context); 11014 ); 11015 11016 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11017 11018 if (ast_strlen_zero(arg.mbox)) { 11019 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11020 return -1; 11021 } 11022 11023 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11024 return 0; 11025 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11829 of file app_voicemail_imapstorage.c.
References adsifdn, adsisec, adsiver, 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_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, callcontext, charset, cidinternalcontexts, 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, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, ext_pass_check_cmd, ext_pass_cmd, externnotify, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), vm_zone::list, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, locale, LOG_ERROR, mailcmd, MAX_NUM_CID_CONTEXTS, maxdeletedmsg, maxgreet, maxlogins, MAXMSG, maxmsg, MAXMSGLIMIT, maxsilence, MINPASSWORD, minpassword, vm_zone::msg_format, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, passwordlocation, poll_freq, poll_mailboxes, poll_thread, populate_defaults(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, serveremail, silencethreshold, skipms, smdi_iface, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, userscontext, var, VM_ATTACH, VM_DIRECFORWARD, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_FWDURGAUTO, vm_invalid_password, VM_MESSAGEWRAP, vm_mismatch, VM_MOVEHEARD, vm_newpassword, VM_OPERATOR, vm_passchanged, vm_password, VM_PBXSKIP, vm_pls_try_again, vm_prepend_timeout, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SPOOL_DIR, VM_SVMAIL, VM_TEMPGREETWARN, vmfmts, vmmaxsecs, vmminsecs, volgain, and zonetag.
11830 { 11831 struct ast_vm_user *current; 11832 char *cat; 11833 struct ast_variable *var; 11834 const char *val; 11835 char *q, *stringp, *tmp; 11836 int x; 11837 int tmpadsi[4]; 11838 char secretfn[PATH_MAX] = ""; 11839 11840 #ifdef IMAP_STORAGE 11841 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11842 #endif 11843 /* set audio control prompts */ 11844 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11845 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11846 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11847 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11848 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11849 11850 /* Free all the users structure */ 11851 free_vm_users(); 11852 11853 /* Free all the zones structure */ 11854 free_vm_zones(); 11855 11856 AST_LIST_LOCK(&users); 11857 11858 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11859 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11860 11861 if (cfg) { 11862 /* General settings */ 11863 11864 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11865 val = "default"; 11866 ast_copy_string(userscontext, val, sizeof(userscontext)); 11867 /* Attach voice message to mail message ? */ 11868 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11869 val = "yes"; 11870 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11871 11872 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11873 val = "no"; 11874 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11875 11876 volgain = 0.0; 11877 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11878 sscanf(val, "%30lf", &volgain); 11879 11880 #ifdef ODBC_STORAGE 11881 strcpy(odbc_database, "asterisk"); 11882 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11883 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11884 } 11885 strcpy(odbc_table, "voicemessages"); 11886 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11887 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11888 } 11889 #endif 11890 /* Mail command */ 11891 strcpy(mailcmd, SENDMAIL); 11892 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11893 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11894 11895 maxsilence = 0; 11896 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11897 maxsilence = atoi(val); 11898 if (maxsilence > 0) 11899 maxsilence *= 1000; 11900 } 11901 11902 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11903 maxmsg = MAXMSG; 11904 } else { 11905 maxmsg = atoi(val); 11906 if (maxmsg < 0) { 11907 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11908 maxmsg = MAXMSG; 11909 } else if (maxmsg > MAXMSGLIMIT) { 11910 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11911 maxmsg = MAXMSGLIMIT; 11912 } 11913 } 11914 11915 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11916 maxdeletedmsg = 0; 11917 } else { 11918 if (sscanf(val, "%30d", &x) == 1) 11919 maxdeletedmsg = x; 11920 else if (ast_true(val)) 11921 maxdeletedmsg = MAXMSG; 11922 else 11923 maxdeletedmsg = 0; 11924 11925 if (maxdeletedmsg < 0) { 11926 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11927 maxdeletedmsg = MAXMSG; 11928 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11929 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11930 maxdeletedmsg = MAXMSGLIMIT; 11931 } 11932 } 11933 11934 /* Load date format config for voicemail mail */ 11935 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11936 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11937 } 11938 11939 /* Load date format config for voicemail pager mail */ 11940 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11941 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11942 } 11943 11944 /* External password changing command */ 11945 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11946 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11947 pwdchange = PWDCHANGE_EXTERNAL; 11948 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11949 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11950 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11951 } 11952 11953 /* External password validation command */ 11954 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11955 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11956 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11957 } 11958 11959 #ifdef IMAP_STORAGE 11960 /* IMAP server address */ 11961 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11962 ast_copy_string(imapserver, val, sizeof(imapserver)); 11963 } else { 11964 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11965 } 11966 /* IMAP server port */ 11967 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11968 ast_copy_string(imapport, val, sizeof(imapport)); 11969 } else { 11970 ast_copy_string(imapport, "143", sizeof(imapport)); 11971 } 11972 /* IMAP server flags */ 11973 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11974 ast_copy_string(imapflags, val, sizeof(imapflags)); 11975 } 11976 /* IMAP server master username */ 11977 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11978 ast_copy_string(authuser, val, sizeof(authuser)); 11979 } 11980 /* IMAP server master password */ 11981 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11982 ast_copy_string(authpassword, val, sizeof(authpassword)); 11983 } 11984 /* Expunge on exit */ 11985 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11986 if (ast_false(val)) 11987 expungeonhangup = 0; 11988 else 11989 expungeonhangup = 1; 11990 } else { 11991 expungeonhangup = 1; 11992 } 11993 /* IMAP voicemail folder */ 11994 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11995 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 11996 } else { 11997 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 11998 } 11999 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12000 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12001 } 12002 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12003 imapgreetings = ast_true(val); 12004 } else { 12005 imapgreetings = 0; 12006 } 12007 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12008 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12009 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12010 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12011 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12012 } else { 12013 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12014 } 12015 12016 /* There is some very unorthodox casting done here. This is due 12017 * to the way c-client handles the argument passed in. It expects a 12018 * void pointer and casts the pointer directly to a long without 12019 * first dereferencing it. */ 12020 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12021 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12022 } else { 12023 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12024 } 12025 12026 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12027 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12028 } else { 12029 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12030 } 12031 12032 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12033 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12034 } else { 12035 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12036 } 12037 12038 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12039 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12040 } else { 12041 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12042 } 12043 12044 /* Increment configuration version */ 12045 imapversion++; 12046 #endif 12047 /* External voicemail notify application */ 12048 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12049 ast_copy_string(externnotify, val, sizeof(externnotify)); 12050 ast_debug(1, "found externnotify: %s\n", externnotify); 12051 } else { 12052 externnotify[0] = '\0'; 12053 } 12054 12055 /* SMDI voicemail notification */ 12056 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12057 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12058 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12059 smdi_iface = ast_smdi_interface_find(val); 12060 } else { 12061 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12062 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12063 } 12064 if (!smdi_iface) { 12065 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12066 } 12067 } 12068 12069 /* Silence treshold */ 12070 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12071 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12072 silencethreshold = atoi(val); 12073 12074 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12075 val = ASTERISK_USERNAME; 12076 ast_copy_string(serveremail, val, sizeof(serveremail)); 12077 12078 vmmaxsecs = 0; 12079 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12080 if (sscanf(val, "%30d", &x) == 1) { 12081 vmmaxsecs = x; 12082 } else { 12083 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12084 } 12085 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12086 static int maxmessage_deprecate = 0; 12087 if (maxmessage_deprecate == 0) { 12088 maxmessage_deprecate = 1; 12089 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12090 } 12091 if (sscanf(val, "%30d", &x) == 1) { 12092 vmmaxsecs = x; 12093 } else { 12094 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12095 } 12096 } 12097 12098 vmminsecs = 0; 12099 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12100 if (sscanf(val, "%30d", &x) == 1) { 12101 vmminsecs = x; 12102 if (maxsilence / 1000 >= vmminsecs) { 12103 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12104 } 12105 } else { 12106 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12107 } 12108 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12109 static int maxmessage_deprecate = 0; 12110 if (maxmessage_deprecate == 0) { 12111 maxmessage_deprecate = 1; 12112 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12113 } 12114 if (sscanf(val, "%30d", &x) == 1) { 12115 vmminsecs = x; 12116 if (maxsilence / 1000 >= vmminsecs) { 12117 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12118 } 12119 } else { 12120 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12121 } 12122 } 12123 12124 val = ast_variable_retrieve(cfg, "general", "format"); 12125 if (!val) { 12126 val = "wav"; 12127 } else { 12128 tmp = ast_strdupa(val); 12129 val = ast_format_str_reduce(tmp); 12130 if (!val) { 12131 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12132 val = "wav"; 12133 } 12134 } 12135 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12136 12137 skipms = 3000; 12138 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12139 if (sscanf(val, "%30d", &x) == 1) { 12140 maxgreet = x; 12141 } else { 12142 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12143 } 12144 } 12145 12146 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12147 if (sscanf(val, "%30d", &x) == 1) { 12148 skipms = x; 12149 } else { 12150 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12151 } 12152 } 12153 12154 maxlogins = 3; 12155 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12156 if (sscanf(val, "%30d", &x) == 1) { 12157 maxlogins = x; 12158 } else { 12159 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12160 } 12161 } 12162 12163 minpassword = MINPASSWORD; 12164 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12165 if (sscanf(val, "%30d", &x) == 1) { 12166 minpassword = x; 12167 } else { 12168 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12169 } 12170 } 12171 12172 /* Force new user to record name ? */ 12173 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12174 val = "no"; 12175 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12176 12177 /* Force new user to record greetings ? */ 12178 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12179 val = "no"; 12180 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12181 12182 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12183 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12184 stringp = ast_strdupa(val); 12185 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12186 if (!ast_strlen_zero(stringp)) { 12187 q = strsep(&stringp, ","); 12188 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12189 q++; 12190 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12191 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12192 } else { 12193 cidinternalcontexts[x][0] = '\0'; 12194 } 12195 } 12196 } 12197 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12198 ast_debug(1, "VM Review Option disabled globally\n"); 12199 val = "no"; 12200 } 12201 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12202 12203 /* Temporary greeting reminder */ 12204 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12205 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12206 val = "no"; 12207 } else { 12208 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12209 } 12210 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12211 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12212 ast_debug(1, "VM next message wrap disabled globally\n"); 12213 val = "no"; 12214 } 12215 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12216 12217 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12218 ast_debug(1, "VM Operator break disabled globally\n"); 12219 val = "no"; 12220 } 12221 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12222 12223 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12224 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12225 val = "no"; 12226 } 12227 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12228 12229 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12230 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12231 val = "no"; 12232 } 12233 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12234 12235 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12236 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12237 val = "yes"; 12238 } 12239 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12240 12241 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12242 ast_debug(1, "Move Heard enabled globally\n"); 12243 val = "yes"; 12244 } 12245 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12246 12247 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12248 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12249 val = "no"; 12250 } 12251 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12252 12253 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12254 ast_debug(1, "Duration info before msg enabled globally\n"); 12255 val = "yes"; 12256 } 12257 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12258 12259 saydurationminfo = 2; 12260 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12261 if (sscanf(val, "%30d", &x) == 1) { 12262 saydurationminfo = x; 12263 } else { 12264 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12265 } 12266 } 12267 12268 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12269 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12270 val = "no"; 12271 } 12272 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12273 12274 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12275 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12276 ast_debug(1, "found dialout context: %s\n", dialcontext); 12277 } else { 12278 dialcontext[0] = '\0'; 12279 } 12280 12281 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12282 ast_copy_string(callcontext, val, sizeof(callcontext)); 12283 ast_debug(1, "found callback context: %s\n", callcontext); 12284 } else { 12285 callcontext[0] = '\0'; 12286 } 12287 12288 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12289 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12290 ast_debug(1, "found operator context: %s\n", exitcontext); 12291 } else { 12292 exitcontext[0] = '\0'; 12293 } 12294 12295 /* load password sounds configuration */ 12296 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12297 ast_copy_string(vm_password, val, sizeof(vm_password)); 12298 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12299 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12300 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12301 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12302 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12303 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12304 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12305 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12306 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12307 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12308 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12309 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12310 } 12311 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12312 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12313 } 12314 /* load configurable audio prompts */ 12315 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12316 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12317 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12318 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12319 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12320 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12321 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12322 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12323 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12324 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12325 12326 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12327 val = "no"; 12328 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12329 12330 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12331 val = "voicemail.conf"; 12332 } 12333 if (!(strcmp(val, "spooldir"))) { 12334 passwordlocation = OPT_PWLOC_SPOOLDIR; 12335 } else { 12336 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12337 } 12338 12339 poll_freq = DEFAULT_POLL_FREQ; 12340 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12341 if (sscanf(val, "%30u", &poll_freq) != 1) { 12342 poll_freq = DEFAULT_POLL_FREQ; 12343 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12344 } 12345 } 12346 12347 poll_mailboxes = 0; 12348 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12349 poll_mailboxes = ast_true(val); 12350 12351 memset(fromstring, 0, sizeof(fromstring)); 12352 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12353 strcpy(charset, "ISO-8859-1"); 12354 if (emailbody) { 12355 ast_free(emailbody); 12356 emailbody = NULL; 12357 } 12358 if (emailsubject) { 12359 ast_free(emailsubject); 12360 emailsubject = NULL; 12361 } 12362 if (pagerbody) { 12363 ast_free(pagerbody); 12364 pagerbody = NULL; 12365 } 12366 if (pagersubject) { 12367 ast_free(pagersubject); 12368 pagersubject = NULL; 12369 } 12370 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12371 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12372 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12373 ast_copy_string(fromstring, val, sizeof(fromstring)); 12374 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12375 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12376 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12377 ast_copy_string(charset, val, sizeof(charset)); 12378 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12379 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12380 for (x = 0; x < 4; x++) { 12381 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12382 } 12383 } 12384 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12385 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12386 for (x = 0; x < 4; x++) { 12387 memcpy(&adsisec[x], &tmpadsi[x], 1); 12388 } 12389 } 12390 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12391 if (atoi(val)) { 12392 adsiver = atoi(val); 12393 } 12394 } 12395 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12396 ast_copy_string(zonetag, val, sizeof(zonetag)); 12397 } 12398 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12399 ast_copy_string(locale, val, sizeof(locale)); 12400 } 12401 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12402 emailsubject = ast_strdup(substitute_escapes(val)); 12403 } 12404 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12405 emailbody = ast_strdup(substitute_escapes(val)); 12406 } 12407 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12408 pagersubject = ast_strdup(substitute_escapes(val)); 12409 } 12410 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12411 pagerbody = ast_strdup(substitute_escapes(val)); 12412 } 12413 12414 /* load mailboxes from users.conf */ 12415 if (ucfg) { 12416 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12417 if (!strcasecmp(cat, "general")) { 12418 continue; 12419 } 12420 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12421 continue; 12422 if ((current = find_or_create(userscontext, cat))) { 12423 populate_defaults(current); 12424 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12425 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12426 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12427 current->passwordlocation = OPT_PWLOC_USERSCONF; 12428 } 12429 12430 switch (current->passwordlocation) { 12431 case OPT_PWLOC_SPOOLDIR: 12432 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12433 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12434 } 12435 } 12436 } 12437 } 12438 12439 /* load mailboxes from voicemail.conf */ 12440 cat = ast_category_browse(cfg, NULL); 12441 while (cat) { 12442 if (strcasecmp(cat, "general")) { 12443 var = ast_variable_browse(cfg, cat); 12444 if (strcasecmp(cat, "zonemessages")) { 12445 /* Process mailboxes in this context */ 12446 while (var) { 12447 append_mailbox(cat, var->name, var->value); 12448 var = var->next; 12449 } 12450 } else { 12451 /* Timezones in this context */ 12452 while (var) { 12453 struct vm_zone *z; 12454 if ((z = ast_malloc(sizeof(*z)))) { 12455 char *msg_format, *tzone; 12456 msg_format = ast_strdupa(var->value); 12457 tzone = strsep(&msg_format, "|,"); 12458 if (msg_format) { 12459 ast_copy_string(z->name, var->name, sizeof(z->name)); 12460 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12461 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12462 AST_LIST_LOCK(&zones); 12463 AST_LIST_INSERT_HEAD(&zones, z, list); 12464 AST_LIST_UNLOCK(&zones); 12465 } else { 12466 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12467 ast_free(z); 12468 } 12469 } else { 12470 AST_LIST_UNLOCK(&users); 12471 return -1; 12472 } 12473 var = var->next; 12474 } 12475 } 12476 } 12477 cat = ast_category_browse(cfg, cat); 12478 } 12479 12480 AST_LIST_UNLOCK(&users); 12481 12482 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12483 start_poll_thread(); 12484 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12485 stop_poll_thread();; 12486 12487 return 0; 12488 } else { 12489 AST_LIST_UNLOCK(&users); 12490 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12491 return 0; 12492 } 12493 }
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 4794 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, my_umask, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
04795 { 04796 char tmpdir[256], newtmp[256]; 04797 char fname[256]; 04798 char tmpcmd[256]; 04799 int tmpfd = -1; 04800 int soxstatus = 0; 04801 04802 /* Eww. We want formats to tell us their own MIME type */ 04803 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04804 04805 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04806 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04807 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04808 tmpfd = mkstemp(newtmp); 04809 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04810 ast_debug(3, "newtmp: %s\n", newtmp); 04811 if (tmpfd > -1) { 04812 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04813 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04814 attach = newtmp; 04815 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04816 } else { 04817 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04818 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04819 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04820 } 04821 } 04822 } 04823 fprintf(p, "--%s" ENDL, bound); 04824 if (msgnum > -1) 04825 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04826 else 04827 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04828 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04829 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04830 if (msgnum > -1) 04831 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04832 else 04833 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04834 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04835 base_encode(fname, p); 04836 if (last) 04837 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04838 if (tmpfd > -1) { 04839 if (soxstatus == 0) { 04840 unlink(fname); 04841 } 04842 close(tmpfd); 04843 unlink(newtmp); 04844 } 04845 return 0; 04846 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6398 of file app_voicemail_imapstorage.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), and ast_log().
06399 { 06400 int x; 06401 if (!ast_adsi_available(chan)) 06402 return; 06403 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06404 if (x < 0) 06405 return; 06406 if (!x) { 06407 if (adsi_load_vmail(chan, useadsi)) { 06408 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06409 return; 06410 } 06411 } else 06412 *useadsi = 1; 06413 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6587 of file app_voicemail_imapstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
06588 { 06589 int bytes = 0; 06590 unsigned char buf[256]; 06591 unsigned char keys[8]; 06592 06593 int x; 06594 06595 if (!ast_adsi_available(chan)) 06596 return; 06597 06598 /* New meaning for keys */ 06599 for (x = 0; x < 5; x++) 06600 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06601 06602 keys[6] = 0x0; 06603 keys[7] = 0x0; 06604 06605 if (!vms->curmsg) { 06606 /* No prev key, provide "Folder" instead */ 06607 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06608 } 06609 if (vms->curmsg >= vms->lastmsg) { 06610 /* If last message ... */ 06611 if (vms->curmsg) { 06612 /* but not only message, provide "Folder" instead */ 06613 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06614 } else { 06615 /* Otherwise if only message, leave blank */ 06616 keys[3] = 1; 06617 } 06618 } 06619 06620 /* If deleted, show "undeleted" */ 06621 if (vms->deleted[vms->curmsg]) 06622 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06623 06624 /* Except "Exit" */ 06625 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06626 bytes += ast_adsi_set_keys(buf + bytes, keys); 06627 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06628 06629 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06630 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6463 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().
06464 { 06465 unsigned char buf[256]; 06466 int bytes = 0; 06467 unsigned char keys[8]; 06468 int x, y; 06469 06470 if (!ast_adsi_available(chan)) 06471 return; 06472 06473 for (x = 0; x < 5; x++) { 06474 y = ADSI_KEY_APPS + 12 + start + x; 06475 if (y > ADSI_KEY_APPS + 12 + 4) 06476 y = 0; 06477 keys[x] = ADSI_KEY_SKT | y; 06478 } 06479 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06480 keys[6] = 0; 06481 keys[7] = 0; 06482 06483 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06484 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06485 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06486 bytes += ast_adsi_set_keys(buf + bytes, keys); 06487 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06488 06489 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06490 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6735 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().
06736 { 06737 unsigned char buf[256]; 06738 int bytes = 0; 06739 06740 if (!ast_adsi_available(chan)) 06741 return; 06742 bytes += adsi_logo(buf + bytes); 06743 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06744 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06745 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06746 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06747 06748 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06749 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6269 of file app_voicemail_imapstorage.c.
References addesc, ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, adsifdn, adsisec, adsiver, 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().
06270 { 06271 unsigned char buf[256]; 06272 int bytes = 0; 06273 int x; 06274 char num[5]; 06275 06276 *useadsi = 0; 06277 bytes += ast_adsi_data_mode(buf + bytes); 06278 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06279 06280 bytes = 0; 06281 bytes += adsi_logo(buf); 06282 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06283 #ifdef DISPLAY 06284 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06285 #endif 06286 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06287 bytes += ast_adsi_data_mode(buf + bytes); 06288 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06289 06290 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06291 bytes = 0; 06292 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06293 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06294 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06295 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06296 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06297 return 0; 06298 } 06299 06300 #ifdef DISPLAY 06301 /* Add a dot */ 06302 bytes = 0; 06303 bytes += ast_adsi_logo(buf); 06304 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06305 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06306 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06307 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06308 #endif 06309 bytes = 0; 06310 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06311 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06312 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06313 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06314 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06315 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06316 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06317 06318 #ifdef DISPLAY 06319 /* Add another dot */ 06320 bytes = 0; 06321 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06322 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06323 06324 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06325 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06326 #endif 06327 06328 bytes = 0; 06329 /* These buttons we load but don't use yet */ 06330 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06331 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06332 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06333 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06334 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06335 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06336 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06337 06338 #ifdef DISPLAY 06339 /* Add another dot */ 06340 bytes = 0; 06341 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06342 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06343 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06344 #endif 06345 06346 bytes = 0; 06347 for (x = 0; x < 5; x++) { 06348 snprintf(num, sizeof(num), "%d", x); 06349 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06350 } 06351 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06352 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06353 06354 #ifdef DISPLAY 06355 /* Add another dot */ 06356 bytes = 0; 06357 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06358 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06359 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06360 #endif 06361 06362 if (ast_adsi_end_download(chan)) { 06363 bytes = 0; 06364 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06365 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06366 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06367 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06368 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06369 return 0; 06370 } 06371 bytes = 0; 06372 bytes += ast_adsi_download_disconnect(buf + bytes); 06373 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06374 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06375 06376 ast_debug(1, "Done downloading scripts...\n"); 06377 06378 #ifdef DISPLAY 06379 /* Add last dot */ 06380 bytes = 0; 06381 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06382 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06383 #endif 06384 ast_debug(1, "Restarting session...\n"); 06385 06386 bytes = 0; 06387 /* Load the session now */ 06388 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06389 *useadsi = 1; 06390 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06391 } else 06392 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06393 06394 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06395 return 0; 06396 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6415 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().
06416 { 06417 unsigned char buf[256]; 06418 int bytes = 0; 06419 unsigned char keys[8]; 06420 int x; 06421 if (!ast_adsi_available(chan)) 06422 return; 06423 06424 for (x = 0; x < 8; x++) 06425 keys[x] = 0; 06426 /* Set one key for next */ 06427 keys[3] = ADSI_KEY_APPS + 3; 06428 06429 bytes += adsi_logo(buf + bytes); 06430 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06431 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06432 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06433 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06434 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06435 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06436 bytes += ast_adsi_set_keys(buf + bytes, keys); 06437 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06438 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06439 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6261 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().
06262 { 06263 int bytes = 0; 06264 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06265 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06266 return bytes; 06267 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6492 of file app_voicemail_imapstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), ast_copy_string(), ast_strlen_zero(), buf1, buf2, vm_state::curmsg, vm_state::fn, name, and strsep().
06493 { 06494 int bytes = 0; 06495 unsigned char buf[256]; 06496 char buf1[256], buf2[256]; 06497 char fn2[PATH_MAX]; 06498 06499 char cid[256] = ""; 06500 char *val; 06501 char *name, *num; 06502 char datetime[21] = ""; 06503 FILE *f; 06504 06505 unsigned char keys[8]; 06506 06507 int x; 06508 06509 if (!ast_adsi_available(chan)) 06510 return; 06511 06512 /* Retrieve important info */ 06513 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06514 f = fopen(fn2, "r"); 06515 if (f) { 06516 while (!feof(f)) { 06517 if (!fgets((char *) buf, sizeof(buf), f)) { 06518 continue; 06519 } 06520 if (!feof(f)) { 06521 char *stringp = NULL; 06522 stringp = (char *) buf; 06523 strsep(&stringp, "="); 06524 val = strsep(&stringp, "="); 06525 if (!ast_strlen_zero(val)) { 06526 if (!strcmp((char *) buf, "callerid")) 06527 ast_copy_string(cid, val, sizeof(cid)); 06528 if (!strcmp((char *) buf, "origdate")) 06529 ast_copy_string(datetime, val, sizeof(datetime)); 06530 } 06531 } 06532 } 06533 fclose(f); 06534 } 06535 /* New meaning for keys */ 06536 for (x = 0; x < 5; x++) 06537 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06538 keys[6] = 0x0; 06539 keys[7] = 0x0; 06540 06541 if (!vms->curmsg) { 06542 /* No prev key, provide "Folder" instead */ 06543 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06544 } 06545 if (vms->curmsg >= vms->lastmsg) { 06546 /* If last message ... */ 06547 if (vms->curmsg) { 06548 /* but not only message, provide "Folder" instead */ 06549 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06550 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06551 06552 } else { 06553 /* Otherwise if only message, leave blank */ 06554 keys[3] = 1; 06555 } 06556 } 06557 06558 if (!ast_strlen_zero(cid)) { 06559 ast_callerid_parse(cid, &name, &num); 06560 if (!name) 06561 name = num; 06562 } else 06563 name = "Unknown Caller"; 06564 06565 /* If deleted, show "undeleted" */ 06566 06567 if (vms->deleted[vms->curmsg]) 06568 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06569 06570 /* Except "Exit" */ 06571 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06572 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06573 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06574 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06575 06576 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06577 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06578 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06579 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06580 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06581 bytes += ast_adsi_set_keys(buf + bytes, keys); 06582 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06583 06584 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06585 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6441 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().
06442 { 06443 unsigned char buf[256]; 06444 int bytes = 0; 06445 unsigned char keys[8]; 06446 int x; 06447 if (!ast_adsi_available(chan)) 06448 return; 06449 06450 for (x = 0; x < 8; x++) 06451 keys[x] = 0; 06452 /* Set one key for next */ 06453 keys[3] = ADSI_KEY_APPS + 3; 06454 06455 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06456 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06457 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06458 bytes += ast_adsi_set_keys(buf + bytes, keys); 06459 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06460 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06461 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6632 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(), vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
06633 { 06634 unsigned char buf[256] = ""; 06635 char buf1[256] = "", buf2[256] = ""; 06636 int bytes = 0; 06637 unsigned char keys[8]; 06638 int x; 06639 06640 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06641 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06642 if (!ast_adsi_available(chan)) 06643 return; 06644 if (vms->newmessages) { 06645 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06646 if (vms->oldmessages) { 06647 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06648 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06649 } else { 06650 snprintf(buf2, sizeof(buf2), "%s.", newm); 06651 } 06652 } else if (vms->oldmessages) { 06653 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06654 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06655 } else { 06656 strcpy(buf1, "You have no messages."); 06657 buf2[0] = ' '; 06658 buf2[1] = '\0'; 06659 } 06660 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06661 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06662 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06663 06664 for (x = 0; x < 6; x++) 06665 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06666 keys[6] = 0; 06667 keys[7] = 0; 06668 06669 /* Don't let them listen if there are none */ 06670 if (vms->lastmsg < 0) 06671 keys[0] = 1; 06672 bytes += ast_adsi_set_keys(buf + bytes, keys); 06673 06674 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06675 06676 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06677 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6679 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(), vm_state::curbox, and vm_state::lastmsg.
06680 { 06681 unsigned char buf[256] = ""; 06682 char buf1[256] = "", buf2[256] = ""; 06683 int bytes = 0; 06684 unsigned char keys[8]; 06685 int x; 06686 06687 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06688 06689 if (!ast_adsi_available(chan)) 06690 return; 06691 06692 /* Original command keys */ 06693 for (x = 0; x < 6; x++) 06694 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06695 06696 keys[6] = 0; 06697 keys[7] = 0; 06698 06699 if ((vms->lastmsg + 1) < 1) 06700 keys[0] = 0; 06701 06702 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06703 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06704 06705 if (vms->lastmsg + 1) 06706 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06707 else 06708 strcpy(buf2, "no messages."); 06709 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06710 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06711 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06712 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06713 bytes += ast_adsi_set_keys(buf + bytes, keys); 06714 06715 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06716 06717 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06718 06719 }
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.
chan | ||
vmu | ||
vms | ||
msg | ||
option | ||
record_gain | Provides handling for the play message envelope, call the person back, or reply to message. |
Definition at line 13191 of file app_voicemail_imapstorage.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), 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, config_flags, CONFIG_STATUS_FILEINVALID, 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(), RETRIEVE, vm_state::starting, and wait_file().
13192 { 13193 int res = 0; 13194 char filename[PATH_MAX]; 13195 struct ast_config *msg_cfg = NULL; 13196 const char *origtime, *context; 13197 char *name, *num; 13198 int retries = 0; 13199 char *cid; 13200 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13201 13202 vms->starting = 0; 13203 13204 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13205 13206 /* Retrieve info from VM attribute file */ 13207 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13208 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13209 msg_cfg = ast_config_load(filename, config_flags); 13210 DISPOSE(vms->curdir, vms->curmsg); 13211 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13212 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13213 return 0; 13214 } 13215 13216 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13217 ast_config_destroy(msg_cfg); 13218 return 0; 13219 } 13220 13221 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13222 13223 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13224 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13225 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13226 switch (option) { 13227 case 3: /* Play message envelope */ 13228 if (!res) 13229 res = play_message_datetime(chan, vmu, origtime, filename); 13230 if (!res) 13231 res = play_message_callerid(chan, vms, cid, context, 0); 13232 13233 res = 't'; 13234 break; 13235 13236 case 2: /* Call back */ 13237 13238 if (ast_strlen_zero(cid)) 13239 break; 13240 13241 ast_callerid_parse(cid, &name, &num); 13242 while ((res > -1) && (res != 't')) { 13243 switch (res) { 13244 case '1': 13245 if (num) { 13246 /* Dial the CID number */ 13247 res = dialout(chan, vmu, num, vmu->callback); 13248 if (res) { 13249 ast_config_destroy(msg_cfg); 13250 return 9; 13251 } 13252 } else { 13253 res = '2'; 13254 } 13255 break; 13256 13257 case '2': 13258 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13259 if (!ast_strlen_zero(vmu->dialout)) { 13260 res = dialout(chan, vmu, NULL, vmu->dialout); 13261 if (res) { 13262 ast_config_destroy(msg_cfg); 13263 return 9; 13264 } 13265 } else { 13266 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13267 res = ast_play_and_wait(chan, "vm-sorry"); 13268 } 13269 ast_config_destroy(msg_cfg); 13270 return res; 13271 case '*': 13272 res = 't'; 13273 break; 13274 case '3': 13275 case '4': 13276 case '5': 13277 case '6': 13278 case '7': 13279 case '8': 13280 case '9': 13281 case '0': 13282 13283 res = ast_play_and_wait(chan, "vm-sorry"); 13284 retries++; 13285 break; 13286 default: 13287 if (num) { 13288 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13289 res = ast_play_and_wait(chan, "vm-num-i-have"); 13290 if (!res) 13291 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13292 if (!res) 13293 res = ast_play_and_wait(chan, "vm-tocallnum"); 13294 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13295 if (!ast_strlen_zero(vmu->dialout)) { 13296 if (!res) 13297 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13298 } 13299 } else { 13300 res = ast_play_and_wait(chan, "vm-nonumber"); 13301 if (!ast_strlen_zero(vmu->dialout)) { 13302 if (!res) 13303 res = ast_play_and_wait(chan, "vm-toenternumber"); 13304 } 13305 } 13306 if (!res) { 13307 res = ast_play_and_wait(chan, "vm-star-cancel"); 13308 } 13309 if (!res) { 13310 res = ast_waitfordigit(chan, 6000); 13311 } 13312 if (!res) { 13313 retries++; 13314 if (retries > 3) { 13315 res = 't'; 13316 } 13317 } 13318 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13319 break; 13320 13321 } 13322 if (res == 't') 13323 res = 0; 13324 else if (res == '*') 13325 res = -1; 13326 } 13327 break; 13328 13329 case 1: /* Reply */ 13330 /* Send reply directly to sender */ 13331 if (ast_strlen_zero(cid)) 13332 break; 13333 13334 ast_callerid_parse(cid, &name, &num); 13335 if (!num) { 13336 ast_verb(3, "No CID number available, no reply sent\n"); 13337 if (!res) 13338 res = ast_play_and_wait(chan, "vm-nonumber"); 13339 ast_config_destroy(msg_cfg); 13340 return res; 13341 } else { 13342 struct ast_vm_user vmu2; 13343 if (find_user(&vmu2, vmu->context, num)) { 13344 struct leave_vm_options leave_options; 13345 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13346 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13347 13348 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13349 13350 memset(&leave_options, 0, sizeof(leave_options)); 13351 leave_options.record_gain = record_gain; 13352 res = leave_voicemail(chan, mailbox, &leave_options); 13353 if (!res) 13354 res = 't'; 13355 ast_config_destroy(msg_cfg); 13356 return res; 13357 } else { 13358 /* Sender has no mailbox, can't reply */ 13359 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13360 ast_play_and_wait(chan, "vm-nobox"); 13361 res = 't'; 13362 ast_config_destroy(msg_cfg); 13363 return res; 13364 } 13365 } 13366 res = 0; 13367 13368 break; 13369 } 13370 13371 #ifndef IMAP_STORAGE 13372 ast_config_destroy(msg_cfg); 13373 13374 if (!res) { 13375 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13376 vms->heard[msg] = 1; 13377 res = wait_file(chan, vms, vms->fn); 13378 } 13379 #endif 13380 return res; 13381 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10735 of file app_voicemail_imapstorage.c.
References apply_options(), 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(), strsep(), and VM_SPOOL_DIR.
10736 { 10737 /* Assumes lock is already held */ 10738 char *tmp; 10739 char *stringp; 10740 char *s; 10741 struct ast_vm_user *vmu; 10742 char *mailbox_full; 10743 int new = 0, old = 0, urgent = 0; 10744 char secretfn[PATH_MAX] = ""; 10745 10746 tmp = ast_strdupa(data); 10747 10748 if (!(vmu = find_or_create(context, box))) 10749 return -1; 10750 10751 populate_defaults(vmu); 10752 10753 stringp = tmp; 10754 if ((s = strsep(&stringp, ","))) { 10755 if (!ast_strlen_zero(s) && s[0] == '*') { 10756 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10757 "\n\tmust be reset in voicemail.conf.\n", box); 10758 } 10759 /* assign password regardless of validity to prevent NULL password from being assigned */ 10760 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10761 } 10762 if (stringp && (s = strsep(&stringp, ","))) { 10763 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10764 } 10765 if (stringp && (s = strsep(&stringp, ","))) { 10766 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10767 } 10768 if (stringp && (s = strsep(&stringp, ","))) { 10769 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10770 } 10771 if (stringp && (s = strsep(&stringp, ","))) { 10772 apply_options(vmu, s); 10773 } 10774 10775 switch (vmu->passwordlocation) { 10776 case OPT_PWLOC_SPOOLDIR: 10777 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10778 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10779 } 10780 10781 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10782 strcpy(mailbox_full, box); 10783 strcat(mailbox_full, "@"); 10784 strcat(mailbox_full, context); 10785 10786 inboxcount2(mailbox_full, &urgent, &new, &old); 10787 queue_mwi_event(mailbox_full, urgent, new, old); 10788 10789 return 0; 10790 }
static void apply_option | ( | struct ast_vm_user * | vmu, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Sets a a specific property value.
vmu | The voicemail user object to work with. | |
var | The name of the property to be set. | |
value | The value to be set to the property. |
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, ast_vm_user::volgain, and ast_vm_user::zonetag.
01065 { 01066 int x; 01067 if (!strcasecmp(var, "attach")) { 01068 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01069 } else if (!strcasecmp(var, "attachfmt")) { 01070 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01071 } else if (!strcasecmp(var, "serveremail")) { 01072 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01073 } else if (!strcasecmp(var, "emailbody")) { 01074 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01075 } else if (!strcasecmp(var, "emailsubject")) { 01076 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01077 } else if (!strcasecmp(var, "language")) { 01078 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01079 } else if (!strcasecmp(var, "tz")) { 01080 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01081 } else if (!strcasecmp(var, "locale")) { 01082 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01083 #ifdef IMAP_STORAGE 01084 } else if (!strcasecmp(var, "imapuser")) { 01085 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01086 vmu->imapversion = imapversion; 01087 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01088 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01089 vmu->imapversion = imapversion; 01090 } else if (!strcasecmp(var, "imapfolder")) { 01091 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01092 } else if (!strcasecmp(var, "imapvmshareid")) { 01093 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01094 vmu->imapversion = imapversion; 01095 #endif 01096 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01097 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01098 } else if (!strcasecmp(var, "saycid")){ 01099 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01100 } else if (!strcasecmp(var, "sendvoicemail")){ 01101 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01102 } else if (!strcasecmp(var, "review")){ 01103 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01104 } else if (!strcasecmp(var, "tempgreetwarn")){ 01105 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01106 } else if (!strcasecmp(var, "messagewrap")){ 01107 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01108 } else if (!strcasecmp(var, "operator")) { 01109 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01110 } else if (!strcasecmp(var, "envelope")){ 01111 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01112 } else if (!strcasecmp(var, "moveheard")){ 01113 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01114 } else if (!strcasecmp(var, "sayduration")){ 01115 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01116 } else if (!strcasecmp(var, "saydurationm")){ 01117 if (sscanf(value, "%30d", &x) == 1) { 01118 vmu->saydurationm = x; 01119 } else { 01120 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01121 } 01122 } else if (!strcasecmp(var, "forcename")){ 01123 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01124 } else if (!strcasecmp(var, "forcegreetings")){ 01125 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01126 } else if (!strcasecmp(var, "callback")) { 01127 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01128 } else if (!strcasecmp(var, "dialout")) { 01129 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01130 } else if (!strcasecmp(var, "exitcontext")) { 01131 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01132 } else if (!strcasecmp(var, "minsecs")) { 01133 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01134 vmu->minsecs = x; 01135 } else { 01136 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01137 vmu->minsecs = vmminsecs; 01138 } 01139 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01140 vmu->maxsecs = atoi(value); 01141 if (vmu->maxsecs <= 0) { 01142 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01143 vmu->maxsecs = vmmaxsecs; 01144 } else { 01145 vmu->maxsecs = atoi(value); 01146 } 01147 if (!strcasecmp(var, "maxmessage")) 01148 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01149 } else if (!strcasecmp(var, "maxmsg")) { 01150 vmu->maxmsg = atoi(value); 01151 /* Accept maxmsg=0 (Greetings only voicemail) */ 01152 if (vmu->maxmsg < 0) { 01153 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01154 vmu->maxmsg = MAXMSG; 01155 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01156 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01157 vmu->maxmsg = MAXMSGLIMIT; 01158 } 01159 } else if (!strcasecmp(var, "nextaftercmd")) { 01160 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01161 } else if (!strcasecmp(var, "backupdeleted")) { 01162 if (sscanf(value, "%30d", &x) == 1) 01163 vmu->maxdeletedmsg = x; 01164 else if (ast_true(value)) 01165 vmu->maxdeletedmsg = MAXMSG; 01166 else 01167 vmu->maxdeletedmsg = 0; 01168 01169 if (vmu->maxdeletedmsg < 0) { 01170 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01171 vmu->maxdeletedmsg = MAXMSG; 01172 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01173 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01174 vmu->maxdeletedmsg = MAXMSGLIMIT; 01175 } 01176 } else if (!strcasecmp(var, "volgain")) { 01177 sscanf(value, "%30lf", &vmu->volgain); 01178 } else if (!strcasecmp(var, "passwordlocation")) { 01179 if (!strcasecmp(value, "spooldir")) { 01180 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01181 } else { 01182 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01183 } 01184 } else if (!strcasecmp(var, "options")) { 01185 apply_options(vmu, value); 01186 } 01187 }
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.
01306 { 01307 char *stringp; 01308 char *s; 01309 char *var, *value; 01310 stringp = ast_strdupa(options); 01311 while ((s = strsep(&stringp, "|"))) { 01312 value = s; 01313 if ((var = strsep(&value, "=")) && value) { 01314 apply_option(vmu, var, value); 01315 } 01316 } 01317 }
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 ast_copy_string(), ast_log(), ast_strlen_zero(), LOG_WARNING, ast_vm_user::mailbox, ast_vm_user::password, and var.
01325 { 01326 for (; var; var = var->next) { 01327 if (!strcasecmp(var->name, "vmsecret")) { 01328 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01329 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01330 if (ast_strlen_zero(retval->password)) { 01331 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01332 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01333 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01334 } else { 01335 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01336 } 01337 } 01338 } else if (!strcasecmp(var->name, "uniqueid")) { 01339 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01340 } else if (!strcasecmp(var->name, "pager")) { 01341 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01342 } else if (!strcasecmp(var->name, "email")) { 01343 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01344 } else if (!strcasecmp(var->name, "fullname")) { 01345 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01346 } else if (!strcasecmp(var->name, "context")) { 01347 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01348 } else if (!strcasecmp(var->name, "emailsubject")) { 01349 ast_free(retval->emailsubject); 01350 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01351 } else if (!strcasecmp(var->name, "emailbody")) { 01352 ast_free(retval->emailbody); 01353 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01354 #ifdef IMAP_STORAGE 01355 } else if (!strcasecmp(var->name, "imapuser")) { 01356 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01357 retval->imapversion = imapversion; 01358 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01359 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01360 retval->imapversion = imapversion; 01361 } else if (!strcasecmp(var->name, "imapfolder")) { 01362 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01363 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01364 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01365 retval->imapversion = imapversion; 01366 #endif 01367 } else 01368 apply_option(retval, var->name, var->value); 01369 } 01370 }
AST_DATA_STRUCTURE | ( | vm_zone | , | |
DATA_EXPORT_VM_ZONES | ||||
) |
AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
DATA_EXPORT_VM_USERS | ||||
) |
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.
end | An expandable buffer for holding the result | |
maxlen | Always zero, but see |
start | A string to be encoded | |
preamble | The length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars. | |
postamble | the length of any additional characters appended to the line, used to ensure proper field wrapping. |
The | encoded string. |
Definition at line 4469 of file app_voicemail_imapstorage.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), and charset.
04470 { 04471 struct ast_str *tmp = ast_str_alloca(80); 04472 int first_section = 1; 04473 04474 ast_str_reset(*end); 04475 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04476 for (; *start; start++) { 04477 int need_encoding = 0; 04478 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04479 need_encoding = 1; 04480 } 04481 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04482 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04483 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04484 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04485 /* Start new line */ 04486 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04487 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04488 first_section = 0; 04489 } 04490 if (need_encoding && *start == ' ') { 04491 ast_str_append(&tmp, -1, "_"); 04492 } else if (need_encoding) { 04493 ast_str_append(&tmp, -1, "=%hhX", *start); 04494 } else { 04495 ast_str_append(&tmp, -1, "%c", *start); 04496 } 04497 } 04498 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04499 return ast_str_buffer(*end); 04500 }
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.
from | The string to work with. | |
buf | The buffer into which to write the modified quoted string. | |
maxlen | Always zero, but see |
Definition at line 4397 of file app_voicemail_imapstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04398 { 04399 const char *ptr; 04400 04401 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04402 ast_str_set(buf, maxlen, "\""); 04403 for (ptr = from; *ptr; ptr++) { 04404 if (*ptr == '"' || *ptr == '\\') { 04405 ast_str_append(buf, maxlen, "\\%c", *ptr); 04406 } else { 04407 ast_str_append(buf, maxlen, "%c", *ptr); 04408 } 04409 } 04410 ast_str_append(buf, maxlen, "\""); 04411 04412 return ast_str_buffer(*buf); 04413 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10792 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, free_user(), OPT_PWLOC_SPOOLDIR, populate_defaults(), 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, and VM_TEMPGREETWARN.
10793 { 10794 int res = 0; 10795 struct ast_vm_user *vmu; 10796 /* language parameter seems to only be used for display in manager action */ 10797 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10798 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10799 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10800 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10801 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10802 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10803 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10804 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10805 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10806 #ifdef IMAP_STORAGE 10807 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10808 "imapfolder=INBOX|imapvmshareid=6000"; 10809 #endif 10810 10811 switch (cmd) { 10812 case TEST_INIT: 10813 info->name = "vmuser"; 10814 info->category = "/apps/app_voicemail/"; 10815 info->summary = "Vmuser unit test"; 10816 info->description = 10817 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10818 return AST_TEST_NOT_RUN; 10819 case TEST_EXECUTE: 10820 break; 10821 } 10822 10823 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10824 return AST_TEST_NOT_RUN; 10825 } 10826 ast_set_flag(vmu, VM_ALLOCED); 10827 populate_defaults(vmu); 10828 10829 apply_options(vmu, options_string); 10830 10831 if (!ast_test_flag(vmu, VM_ATTACH)) { 10832 ast_test_status_update(test, "Parse failure for attach option\n"); 10833 res = 1; 10834 } 10835 if (strcasecmp(vmu->attachfmt, "wav49")) { 10836 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10837 res = 1; 10838 } 10839 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10840 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10841 res = 1; 10842 } 10843 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10844 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10845 res = 1; 10846 } 10847 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10848 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10849 res = 1; 10850 } 10851 if (strcasecmp(vmu->zonetag, "central")) { 10852 ast_test_status_update(test, "Parse failure for tz option\n"); 10853 res = 1; 10854 } 10855 if (!ast_test_flag(vmu, VM_DELETE)) { 10856 ast_test_status_update(test, "Parse failure for delete option\n"); 10857 res = 1; 10858 } 10859 if (!ast_test_flag(vmu, VM_SAYCID)) { 10860 ast_test_status_update(test, "Parse failure for saycid option\n"); 10861 res = 1; 10862 } 10863 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10864 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10865 res = 1; 10866 } 10867 if (!ast_test_flag(vmu, VM_REVIEW)) { 10868 ast_test_status_update(test, "Parse failure for review option\n"); 10869 res = 1; 10870 } 10871 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10872 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10873 res = 1; 10874 } 10875 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10876 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10877 res = 1; 10878 } 10879 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10880 ast_test_status_update(test, "Parse failure for operator option\n"); 10881 res = 1; 10882 } 10883 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10884 ast_test_status_update(test, "Parse failure for envelope option\n"); 10885 res = 1; 10886 } 10887 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10888 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10889 res = 1; 10890 } 10891 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10892 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10893 res = 1; 10894 } 10895 if (vmu->saydurationm != 5) { 10896 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10897 res = 1; 10898 } 10899 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10900 ast_test_status_update(test, "Parse failure for forcename option\n"); 10901 res = 1; 10902 } 10903 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10904 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10905 res = 1; 10906 } 10907 if (strcasecmp(vmu->callback, "somecontext")) { 10908 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10909 res = 1; 10910 } 10911 if (strcasecmp(vmu->dialout, "somecontext2")) { 10912 ast_test_status_update(test, "Parse failure for dialout option\n"); 10913 res = 1; 10914 } 10915 if (strcasecmp(vmu->exit, "somecontext3")) { 10916 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10917 res = 1; 10918 } 10919 if (vmu->minsecs != 10) { 10920 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10921 res = 1; 10922 } 10923 if (vmu->maxsecs != 100) { 10924 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10925 res = 1; 10926 } 10927 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10928 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10929 res = 1; 10930 } 10931 if (vmu->maxdeletedmsg != 50) { 10932 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10933 res = 1; 10934 } 10935 if (vmu->volgain != 1.3) { 10936 ast_test_status_update(test, "Parse failure for volgain option\n"); 10937 res = 1; 10938 } 10939 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10940 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10941 res = 1; 10942 } 10943 #ifdef IMAP_STORAGE 10944 apply_options(vmu, option_string2); 10945 10946 if (strcasecmp(vmu->imapuser, "imapuser")) { 10947 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10948 res = 1; 10949 } 10950 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10951 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10952 res = 1; 10953 } 10954 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10955 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10956 res = 1; 10957 } 10958 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10959 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10960 res = 1; 10961 } 10962 #endif 10963 10964 free_user(vmu); 10965 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10966 }
static int base_encode | ( | char * | filename, | |
FILE * | so | |||
) | [static] |
Performs a base 64 encode algorithm on the contents of a File.
filename | The path to the file to be encoded. Must be readable, file is opened in read mode. | |
so | A FILE handle to the output file to receive the base 64 encoded contents of the input file, identified by filename. |
Definition at line 4273 of file app_voicemail_imapstorage.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04274 { 04275 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04276 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04277 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04278 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04279 int i, hiteof = 0; 04280 FILE *fi; 04281 struct baseio bio; 04282 04283 memset(&bio, 0, sizeof(bio)); 04284 bio.iocp = BASEMAXINLINE; 04285 04286 if (!(fi = fopen(filename, "rb"))) { 04287 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04288 return -1; 04289 } 04290 04291 while (!hiteof){ 04292 unsigned char igroup[3], ogroup[4]; 04293 int c, n; 04294 04295 memset(igroup, 0, sizeof(igroup)); 04296 04297 for (n = 0; n < 3; n++) { 04298 if ((c = inchar(&bio, fi)) == EOF) { 04299 hiteof = 1; 04300 break; 04301 } 04302 04303 igroup[n] = (unsigned char) c; 04304 } 04305 04306 if (n > 0) { 04307 ogroup[0]= dtable[igroup[0] >> 2]; 04308 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04309 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04310 ogroup[3]= dtable[igroup[2] & 0x3F]; 04311 04312 if (n < 3) { 04313 ogroup[3] = '='; 04314 04315 if (n < 2) 04316 ogroup[2] = '='; 04317 } 04318 04319 for (i = 0; i < 4; i++) 04320 ochar(&bio, ogroup[i], so); 04321 } 04322 } 04323 04324 fclose(fi); 04325 04326 if (fputs(ENDL, so) == EOF) { 04327 return 0; 04328 } 04329 04330 return 1; 04331 }
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.
vmu | The voicemail user to change the password for. | |
password | The new value to be set to the password for this user. |
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.
01284 { 01285 int res = -1; 01286 if (!strcmp(vmu->password, password)) { 01287 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01288 return 0; 01289 } 01290 01291 if (strlen(password) > 10) { 01292 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01293 } 01294 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01295 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01296 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01297 res = 0; 01298 } 01299 return res; 01300 }
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 4442 of file app_voicemail_imapstorage.c.
04443 { 04444 for (; *str; str++) { 04445 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04446 return 1; 04447 } 04448 } 04449 return 0; 04450 }
static int check_password | ( | struct ast_vm_user * | vmu, | |
char * | password | |||
) | [static] |
Check that password meets minimum required length.
vmu | The voicemail user to change the password for. | |
password | The password string to check |
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().
01243 { 01244 /* check minimum length */ 01245 if (strlen(password) < minpassword) 01246 return 1; 01247 /* check that password does not contain '*' character */ 01248 if (!ast_strlen_zero(password) && password[0] == '*') 01249 return 1; 01250 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01251 char cmd[255], buf[255]; 01252 01253 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01254 01255 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01256 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01257 ast_debug(5, "Result: %s\n", buf); 01258 if (!strncasecmp(buf, "VALID", 5)) { 01259 ast_debug(3, "Passed password check: '%s'\n", buf); 01260 return 0; 01261 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01262 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01263 return 0; 01264 } else { 01265 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01266 return 1; 01267 } 01268 } 01269 } 01270 return 0; 01271 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7938 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_log(), AST_LOG_NOTICE, ast_test_flag, ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, 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.
07939 { 07940 int x = 0; 07941 07942 #ifndef IMAP_STORAGE 07943 int last_msg_idx; 07944 int res = 0, nummsg; 07945 char fn2[PATH_MAX]; 07946 #endif 07947 07948 if (vms->lastmsg <= -1) { 07949 goto done; 07950 } 07951 07952 vms->curmsg = -1; 07953 #ifndef IMAP_STORAGE 07954 /* Get the deleted messages fixed */ 07955 if (vm_lock_path(vms->curdir)) { 07956 return ERROR_LOCK_PATH; 07957 } 07958 07959 /* update count as message may have arrived while we've got mailbox open */ 07960 last_msg_idx = last_message_index(vmu, vms->curdir); 07961 if (last_msg_idx != vms->lastmsg) { 07962 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07963 } 07964 07965 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07966 for (x = 0; x < last_msg_idx + 1; x++) { 07967 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07968 /* Save this message. It's not in INBOX or hasn't been heard */ 07969 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07970 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07971 break; 07972 } 07973 vms->curmsg++; 07974 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07975 if (strcmp(vms->fn, fn2)) { 07976 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07977 } 07978 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07979 /* Move to old folder before deleting */ 07980 res = save_to_folder(vmu, vms, x, 1); 07981 if (res == ERROR_LOCK_PATH) { 07982 /* If save failed do not delete the message */ 07983 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07984 vms->deleted[x] = 0; 07985 vms->heard[x] = 0; 07986 --x; 07987 } 07988 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07989 /* Move to deleted folder */ 07990 res = save_to_folder(vmu, vms, x, 10); 07991 if (res == ERROR_LOCK_PATH) { 07992 /* If save failed do not delete the message */ 07993 vms->deleted[x] = 0; 07994 vms->heard[x] = 0; 07995 --x; 07996 } 07997 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07998 /* If realtime storage enabled - we should explicitly delete this message, 07999 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08000 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08001 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08002 DELETE(vms->curdir, x, vms->fn, vmu); 08003 } 08004 } 08005 } 08006 08007 /* Delete ALL remaining messages */ 08008 nummsg = x - 1; 08009 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08010 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08011 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08012 DELETE(vms->curdir, x, vms->fn, vmu); 08013 } 08014 } 08015 ast_unlock_path(vms->curdir); 08016 #else /* defined(IMAP_STORAGE) */ 08017 if (vms->deleted) { 08018 /* Since we now expunge after each delete, deleting in reverse order 08019 * ensures that no reordering occurs between each step. */ 08020 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 08021 if (vms->deleted[x]) { 08022 ast_debug(3, "IMAP delete of %d\n", x); 08023 DELETE(vms->curdir, x, vms->fn, vmu); 08024 } 08025 } 08026 } 08027 #endif 08028 08029 done: 08030 if (vms->deleted && vmu->maxmsg) { 08031 memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 08032 } 08033 if (vms->heard && vmu->maxmsg) { 08034 memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 08035 } 08036 08037 return 0; 08038 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11112 of file app_voicemail_imapstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.
11113 { 11114 int which = 0; 11115 int wordlen; 11116 struct ast_vm_user *vmu; 11117 const char *context = ""; 11118 11119 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11120 if (pos > 4) 11121 return NULL; 11122 if (pos == 3) 11123 return (state == 0) ? ast_strdup("for") : NULL; 11124 wordlen = strlen(word); 11125 AST_LIST_TRAVERSE(&users, vmu, list) { 11126 if (!strncasecmp(word, vmu->context, wordlen)) { 11127 if (context && strcmp(context, vmu->context) && ++which > state) 11128 return ast_strdup(vmu->context); 11129 /* ignore repeated contexts ? */ 11130 context = vmu->context; 11131 } 11132 } 11133 return NULL; 11134 }
static int copy | ( | char * | infile, | |
char * | outfile | |||
) | [static] |
Utility function to copy a file.
infile | The path to the file to be copied. The file must be readable, it is opened in read only mode. | |
outfile | The 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. |
Definition at line 4077 of file app_voicemail_imapstorage.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
04078 { 04079 int ifd; 04080 int ofd; 04081 int res; 04082 int len; 04083 char buf[4096]; 04084 04085 #ifdef HARDLINK_WHEN_POSSIBLE 04086 /* Hard link if possible; saves disk space & is faster */ 04087 if (link(infile, outfile)) { 04088 #endif 04089 if ((ifd = open(infile, O_RDONLY)) < 0) { 04090 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04091 return -1; 04092 } 04093 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04094 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04095 close(ifd); 04096 return -1; 04097 } 04098 do { 04099 len = read(ifd, buf, sizeof(buf)); 04100 if (len < 0) { 04101 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04102 close(ifd); 04103 close(ofd); 04104 unlink(outfile); 04105 } 04106 if (len) { 04107 res = write(ofd, buf, len); 04108 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04109 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04110 close(ifd); 04111 close(ofd); 04112 unlink(outfile); 04113 } 04114 } 04115 } while (len); 04116 close(ifd); 04117 close(ofd); 04118 return 0; 04119 #ifdef HARDLINK_WHEN_POSSIBLE 04120 } else { 04121 /* Hard link succeeded */ 04122 return 0; 04123 } 04124 #endif 04125 }
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.
chan | ||
vmu | ||
imbox | ||
msgnum | ||
duration | ||
recip | ||
fmt | ||
dir | ||
flag | This is only used by file storage based mailboxes. |
Definition at line 5314 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(), maxmsg, 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().
05315 { 05316 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05317 const char *frombox = mbox(vmu, imbox); 05318 const char *userfolder; 05319 int recipmsgnum; 05320 int res = 0; 05321 05322 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05323 05324 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05325 userfolder = "Urgent"; 05326 } else { 05327 userfolder = "INBOX"; 05328 } 05329 05330 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05331 05332 if (!dir) 05333 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05334 else 05335 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05336 05337 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05338 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05339 05340 if (vm_lock_path(todir)) 05341 return ERROR_LOCK_PATH; 05342 05343 recipmsgnum = last_message_index(recip, todir) + 1; 05344 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05345 make_file(topath, sizeof(topath), todir, recipmsgnum); 05346 #ifndef ODBC_STORAGE 05347 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05348 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05349 } else { 05350 #endif 05351 /* If we are prepending a message for ODBC, then the message already 05352 * exists in the database, but we want to force copying from the 05353 * filesystem (since only the FS contains the prepend). */ 05354 copy_plain_file(frompath, topath); 05355 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05356 vm_delete(topath); 05357 #ifndef ODBC_STORAGE 05358 } 05359 #endif 05360 } else { 05361 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05362 res = -1; 05363 } 05364 ast_unlock_path(todir); 05365 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05366 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05367 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05368 flag); 05369 05370 return res; 05371 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4136 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), exten, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04137 { 04138 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04139 struct ast_variable *tmp,*var = NULL; 04140 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04141 ast_filecopy(frompath, topath, NULL); 04142 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04143 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04144 if (ast_check_realtime("voicemail_data")) { 04145 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04146 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04147 for (tmp = var; tmp; tmp = tmp->next) { 04148 if (!strcasecmp(tmp->name, "origmailbox")) { 04149 origmailbox = tmp->value; 04150 } else if (!strcasecmp(tmp->name, "context")) { 04151 context = tmp->value; 04152 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04153 macrocontext = tmp->value; 04154 } else if (!strcasecmp(tmp->name, "exten")) { 04155 exten = tmp->value; 04156 } else if (!strcasecmp(tmp->name, "priority")) { 04157 priority = tmp->value; 04158 } else if (!strcasecmp(tmp->name, "callerchan")) { 04159 callerchan = tmp->value; 04160 } else if (!strcasecmp(tmp->name, "callerid")) { 04161 callerid = tmp->value; 04162 } else if (!strcasecmp(tmp->name, "origdate")) { 04163 origdate = tmp->value; 04164 } else if (!strcasecmp(tmp->name, "origtime")) { 04165 origtime = tmp->value; 04166 } else if (!strcasecmp(tmp->name, "category")) { 04167 category = tmp->value; 04168 } else if (!strcasecmp(tmp->name, "duration")) { 04169 duration = tmp->value; 04170 } 04171 } 04172 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); 04173 } 04174 copy(frompath2, topath2); 04175 ast_variables_destroy(var); 04176 }
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.
vmu | ||
dir | This method is used when mailboxes are stored on the filesystem. (not ODBC and not IMAP). |
Definition at line 3972 of file app_voicemail_imapstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
03973 { 03974 03975 int vmcount = 0; 03976 DIR *vmdir = NULL; 03977 struct dirent *vment = NULL; 03978 03979 if (vm_lock_path(dir)) 03980 return ERROR_LOCK_PATH; 03981 03982 if ((vmdir = opendir(dir))) { 03983 while ((vment = readdir(vmdir))) { 03984 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03985 vmcount++; 03986 } 03987 } 03988 closedir(vmdir); 03989 } 03990 ast_unlock_path(dir); 03991 03992 return vmcount; 03993 }
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
dest | String. base directory. | |
len | Length of dest. | |
context | String. Ignored if is null or empty string. | |
ext | String. Ignored if is null or empty string. | |
folder | String. Ignored if is null or empty string. |
Definition at line 1689 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01690 { 01691 mode_t mode = VOICEMAIL_DIR_MODE; 01692 int res; 01693 01694 make_dir(dest, len, context, ext, folder); 01695 if ((res = ast_mkdir(dest, mode))) { 01696 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01697 return -1; 01698 } 01699 return 0; 01700 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 13118 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.
13119 { 13120 int cmd = 0; 13121 char destination[80] = ""; 13122 int retries = 0; 13123 13124 if (!num) { 13125 ast_verb(3, "Destination number will be entered manually\n"); 13126 while (retries < 3 && cmd != 't') { 13127 destination[1] = '\0'; 13128 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13129 if (!cmd) 13130 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13131 if (!cmd) 13132 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13133 if (!cmd) { 13134 cmd = ast_waitfordigit(chan, 6000); 13135 if (cmd) 13136 destination[0] = cmd; 13137 } 13138 if (!cmd) { 13139 retries++; 13140 } else { 13141 13142 if (cmd < 0) 13143 return 0; 13144 if (cmd == '*') { 13145 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13146 return 0; 13147 } 13148 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13149 retries++; 13150 else 13151 cmd = 't'; 13152 } 13153 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13154 } 13155 if (retries >= 3) { 13156 return 0; 13157 } 13158 13159 } else { 13160 if (option_verbose > 2) 13161 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13162 ast_copy_string(destination, num, sizeof(destination)); 13163 } 13164 13165 if (!ast_strlen_zero(destination)) { 13166 if (destination[strlen(destination) -1 ] == '*') 13167 return 0; 13168 if (option_verbose > 2) 13169 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13170 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13171 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13172 chan->priority = 0; 13173 return 9; 13174 } 13175 return 0; 13176 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10695 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, globalflags, ast_vm_user::list, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
10696 { 10697 struct ast_vm_user *vmu; 10698 10699 if (!ast_strlen_zero(box) && box[0] == '*') { 10700 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10701 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10702 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10703 "\n\tand will be ignored.\n", box, context); 10704 return NULL; 10705 } 10706 10707 AST_LIST_TRAVERSE(&users, vmu, list) { 10708 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10709 if (strcasecmp(vmu->context, context)) { 10710 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10711 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10712 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10713 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10714 } 10715 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10716 return NULL; 10717 } 10718 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10719 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10720 return NULL; 10721 } 10722 } 10723 10724 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10725 return NULL; 10726 10727 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10728 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10729 10730 AST_LIST_INSERT_TAIL(&users, vmu, list); 10731 10732 return vmu; 10733 }
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.
ivm | ||
context | ||
mailbox |
Definition at line 1441 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, find_user_realtime(), globalflags, ast_vm_user::list, VM_ALLOCED, and VM_SEARCH.
01442 { 01443 /* This function could be made to generate one from a database, too */ 01444 struct ast_vm_user *vmu = NULL, *cur; 01445 AST_LIST_LOCK(&users); 01446 01447 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01448 context = "default"; 01449 01450 AST_LIST_TRAVERSE(&users, cur, list) { 01451 #ifdef IMAP_STORAGE 01452 if (cur->imapversion != imapversion) { 01453 continue; 01454 } 01455 #endif 01456 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01457 break; 01458 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01459 break; 01460 } 01461 if (cur) { 01462 /* Make a copy, so that on a reload, we have no race */ 01463 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01464 *vmu = *cur; 01465 if (!ivm) { 01466 vmu->emailbody = ast_strdup(cur->emailbody); 01467 vmu->emailsubject = ast_strdup(cur->emailsubject); 01468 } 01469 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01470 AST_LIST_NEXT(vmu, list) = NULL; 01471 } 01472 } else 01473 vmu = find_user_realtime(ivm, context, mailbox); 01474 AST_LIST_UNLOCK(&users); 01475 return vmu; 01476 }
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.
ivm | ||
context | ||
mailbox | This 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. |
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(), globalflags, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
01405 { 01406 struct ast_variable *var; 01407 struct ast_vm_user *retval; 01408 01409 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01410 if (!ivm) 01411 ast_set_flag(retval, VM_ALLOCED); 01412 else 01413 memset(retval, 0, sizeof(*retval)); 01414 if (mailbox) 01415 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01416 populate_defaults(retval); 01417 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01418 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01419 else 01420 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01421 if (var) { 01422 apply_options_full(retval, var); 01423 ast_variables_destroy(var); 01424 } else { 01425 if (!ivm) 01426 free_user(retval); 01427 retval = NULL; 01428 } 01429 } 01430 return retval; 01431 }
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.
chan | ||
context | ||
vms | ||
sender | ||
fmt | ||
is_new_message | Used 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 | ||
urgent | Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory. |
When in the forward message mode (is_new_message == 0):
Definition at line 7143 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_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(), free_user(), globalflags, ast_party_caller::id, inboxcount(), inprocess_count(), ast_channel::language, leave_voicemail(), ast_app::list, 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, 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(), VM_FWDURGAUTO, VM_SPOOL_DIR, and vmfmts.
07144 { 07145 #ifdef IMAP_STORAGE 07146 int todircount = 0; 07147 struct vm_state *dstvms; 07148 #endif 07149 char username[70]=""; 07150 char fn[PATH_MAX]; /* for playback of name greeting */ 07151 char ecodes[16] = "#"; 07152 int res = 0, cmd = 0; 07153 struct ast_vm_user *receiver = NULL, *vmtmp; 07154 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07155 char *stringp; 07156 const char *s; 07157 int saved_messages = 0; 07158 int valid_extensions = 0; 07159 char *dir; 07160 int curmsg; 07161 char urgent_str[7] = ""; 07162 int prompt_played = 0; 07163 #ifndef IMAP_STORAGE 07164 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07165 #endif 07166 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07167 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07168 } 07169 07170 if (vms == NULL) return -1; 07171 dir = vms->curdir; 07172 curmsg = vms->curmsg; 07173 07174 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07175 while (!res && !valid_extensions) { 07176 int use_directory = 0; 07177 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07178 int done = 0; 07179 int retries = 0; 07180 cmd = 0; 07181 while ((cmd >= 0) && !done ){ 07182 if (cmd) 07183 retries = 0; 07184 switch (cmd) { 07185 case '1': 07186 use_directory = 0; 07187 done = 1; 07188 break; 07189 case '2': 07190 use_directory = 1; 07191 done = 1; 07192 break; 07193 case '*': 07194 cmd = 't'; 07195 done = 1; 07196 break; 07197 default: 07198 /* Press 1 to enter an extension press 2 to use the directory */ 07199 cmd = ast_play_and_wait(chan, "vm-forward"); 07200 if (!cmd) { 07201 cmd = ast_waitfordigit(chan, 3000); 07202 } 07203 if (!cmd) { 07204 retries++; 07205 } 07206 if (retries > 3) { 07207 cmd = 't'; 07208 done = 1; 07209 } 07210 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07211 } 07212 } 07213 if (cmd < 0 || cmd == 't') 07214 break; 07215 } 07216 07217 if (use_directory) { 07218 /* use app_directory */ 07219 07220 char old_context[sizeof(chan->context)]; 07221 char old_exten[sizeof(chan->exten)]; 07222 int old_priority; 07223 struct ast_app* directory_app; 07224 07225 directory_app = pbx_findapp("Directory"); 07226 if (directory_app) { 07227 char vmcontext[256]; 07228 /* make backup copies */ 07229 memcpy(old_context, chan->context, sizeof(chan->context)); 07230 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07231 old_priority = chan->priority; 07232 07233 /* call the the Directory, changes the channel */ 07234 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07235 res = pbx_exec(chan, directory_app, vmcontext); 07236 07237 ast_copy_string(username, chan->exten, sizeof(username)); 07238 07239 /* restore the old context, exten, and priority */ 07240 memcpy(chan->context, old_context, sizeof(chan->context)); 07241 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07242 chan->priority = old_priority; 07243 } else { 07244 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07245 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07246 } 07247 } else { 07248 /* Ask for an extension */ 07249 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07250 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07251 prompt_played++; 07252 if (res || prompt_played > 4) 07253 break; 07254 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07255 break; 07256 } 07257 07258 /* start all over if no username */ 07259 if (ast_strlen_zero(username)) 07260 continue; 07261 stringp = username; 07262 s = strsep(&stringp, "*"); 07263 /* start optimistic */ 07264 valid_extensions = 1; 07265 while (s) { 07266 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07267 int oldmsgs; 07268 int newmsgs; 07269 int capacity; 07270 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07271 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07272 /* Shouldn't happen, but allow trying another extension if it does */ 07273 res = ast_play_and_wait(chan, "pbx-invalid"); 07274 valid_extensions = 0; 07275 break; 07276 } 07277 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07278 if ((newmsgs + oldmsgs) >= capacity) { 07279 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07280 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07281 valid_extensions = 0; 07282 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07283 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07284 free_user(vmtmp); 07285 } 07286 inprocess_count(receiver->mailbox, receiver->context, -1); 07287 break; 07288 } 07289 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07290 } else { 07291 /* XXX Optimization for the future. When we encounter a single bad extension, 07292 * bailing out on all of the extensions may not be the way to go. We should 07293 * probably just bail on that single extension, then allow the user to enter 07294 * several more. XXX 07295 */ 07296 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07297 free_user(receiver); 07298 } 07299 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07300 /* "I am sorry, that's not a valid extension. Please try again." */ 07301 res = ast_play_and_wait(chan, "pbx-invalid"); 07302 valid_extensions = 0; 07303 break; 07304 } 07305 07306 /* play name if available, else play extension number */ 07307 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07308 RETRIEVE(fn, -1, s, receiver->context); 07309 if (ast_fileexists(fn, NULL, NULL) > 0) { 07310 res = ast_stream_and_wait(chan, fn, ecodes); 07311 if (res) { 07312 DISPOSE(fn, -1); 07313 return res; 07314 } 07315 } else { 07316 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07317 } 07318 DISPOSE(fn, -1); 07319 07320 s = strsep(&stringp, "*"); 07321 } 07322 /* break from the loop of reading the extensions */ 07323 if (valid_extensions) 07324 break; 07325 } 07326 /* check if we're clear to proceed */ 07327 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07328 return res; 07329 if (is_new_message == 1) { 07330 struct leave_vm_options leave_options; 07331 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07332 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07333 07334 /* Send VoiceMail */ 07335 memset(&leave_options, 0, sizeof(leave_options)); 07336 leave_options.record_gain = record_gain; 07337 cmd = leave_voicemail(chan, mailbox, &leave_options); 07338 } else { 07339 /* Forward VoiceMail */ 07340 long duration = 0; 07341 struct vm_state vmstmp; 07342 int copy_msg_result = 0; 07343 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07344 07345 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07346 07347 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07348 if (!cmd) { 07349 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07350 #ifdef IMAP_STORAGE 07351 int attach_user_voicemail; 07352 char *myserveremail = serveremail; 07353 07354 /* get destination mailbox */ 07355 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07356 if (!dstvms) { 07357 dstvms = create_vm_state_from_user(vmtmp); 07358 } 07359 if (dstvms) { 07360 init_mailstream(dstvms, 0); 07361 if (!dstvms->mailstream) { 07362 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07363 } else { 07364 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07365 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07366 } 07367 } else { 07368 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07369 } 07370 if (!ast_strlen_zero(vmtmp->serveremail)) 07371 myserveremail = vmtmp->serveremail; 07372 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07373 /* NULL category for IMAP storage */ 07374 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07375 dstvms->curbox, 07376 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07377 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07378 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07379 NULL, urgent_str); 07380 #else 07381 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07382 #endif 07383 saved_messages++; 07384 AST_LIST_REMOVE_CURRENT(list); 07385 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07386 free_user(vmtmp); 07387 if (res) 07388 break; 07389 } 07390 AST_LIST_TRAVERSE_SAFE_END; 07391 if (saved_messages > 0 && !copy_msg_result) { 07392 /* give confirmation that the message was saved */ 07393 /* commented out since we can't forward batches yet 07394 if (saved_messages == 1) 07395 res = ast_play_and_wait(chan, "vm-message"); 07396 else 07397 res = ast_play_and_wait(chan, "vm-messages"); 07398 if (!res) 07399 res = ast_play_and_wait(chan, "vm-saved"); */ 07400 #ifdef IMAP_STORAGE 07401 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07402 if (ast_strlen_zero(vmstmp.introfn)) 07403 #endif 07404 res = ast_play_and_wait(chan, "vm-msgsaved"); 07405 } 07406 #ifndef IMAP_STORAGE 07407 else { 07408 /* with IMAP, mailbox full warning played by imap_check_limits */ 07409 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07410 } 07411 /* Restore original message without prepended message if backup exists */ 07412 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07413 strcpy(textfile, msgfile); 07414 strcpy(backup, msgfile); 07415 strcpy(backup_textfile, msgfile); 07416 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07417 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07418 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07419 if (ast_fileexists(backup, NULL, NULL) > 0) { 07420 ast_filerename(backup, msgfile, NULL); 07421 rename(backup_textfile, textfile); 07422 } 07423 #endif 07424 } 07425 DISPOSE(dir, curmsg); 07426 #ifndef IMAP_STORAGE 07427 if (cmd) { /* assuming hangup, cleanup backup file */ 07428 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07429 strcpy(textfile, msgfile); 07430 strcpy(backup_textfile, msgfile); 07431 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07432 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07433 rename(backup_textfile, textfile); 07434 } 07435 #endif 07436 } 07437 07438 /* If anything failed above, we still have this list to free */ 07439 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07440 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07441 free_user(vmtmp); 07442 } 07443 return res ? res : cmd; 07444 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1744 of file app_voicemail_imapstorage.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01745 { 01746 if (ast_test_flag(vmu, VM_ALLOCED)) { 01747 01748 ast_free(vmu->emailbody); 01749 vmu->emailbody = NULL; 01750 01751 ast_free(vmu->emailsubject); 01752 vmu->emailsubject = NULL; 01753 01754 ast_free(vmu); 01755 } 01756 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11711 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), ast_vm_user::list, and VM_ALLOCED.
11712 { 11713 struct ast_vm_user *current; 11714 AST_LIST_LOCK(&users); 11715 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11716 ast_set_flag(current, VM_ALLOCED); 11717 free_user(current); 11718 } 11719 AST_LIST_UNLOCK(&users); 11720 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11723 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and vm_zone::list.
11724 { 11725 struct vm_zone *zcur; 11726 AST_LIST_LOCK(&zones); 11727 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11728 free_zone(zcur); 11729 AST_LIST_UNLOCK(&zones); 11730 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5082 of file app_voicemail_imapstorage.c.
References ast_free.
05083 { 05084 ast_free(z); 05085 }
static int get_date | ( | char * | s, | |
int | len | |||
) | [static] |
Gets the current date and time, as formatted string.
s | The buffer to hold the output formatted date. | |
len | the length of the buffer. Used to prevent buffer overflow in ast_strftime. |
Definition at line 5038 of file app_voicemail_imapstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05039 { 05040 struct ast_tm tm; 05041 struct timeval t = ast_tvnow(); 05042 05043 ast_localtime(&t, &tm, "UTC"); 05044 05045 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05046 }
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 6755 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().
06756 { 06757 int x; 06758 int d; 06759 char fn[PATH_MAX]; 06760 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06761 if (d) 06762 return d; 06763 for (x = start; x < 5; x++) { /* For all folders */ 06764 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06765 return d; 06766 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06767 if (d) 06768 return d; 06769 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06770 06771 /* The inbox folder can have its name changed under certain conditions 06772 * so this checks if the sound file exists for the inbox folder name and 06773 * if it doesn't, plays the default name instead. */ 06774 if (x == 0) { 06775 if (ast_fileexists(fn, NULL, NULL)) { 06776 d = vm_play_folder_name(chan, fn); 06777 } else { 06778 ast_verb(1, "failed to find %s\n", fn); 06779 d = vm_play_folder_name(chan, "vm-INBOX"); 06780 } 06781 } else { 06782 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06783 d = vm_play_folder_name(chan, fn); 06784 } 06785 06786 if (d) 06787 return d; 06788 d = ast_waitfordigit(chan, 500); 06789 if (d) 06790 return d; 06791 } 06792 06793 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06794 if (d) 06795 return d; 06796 d = ast_waitfordigit(chan, 4000); 06797 return d; 06798 }
static int get_folder2 | ( | struct ast_channel * | chan, | |
char * | fn, | |||
int | start | |||
) | [static] |
plays a prompt and waits for a keypress.
chan | ||
fn | the name of the voice prompt file to be played. For example, 'vm-changeto', 'vm-savefolder' | |
start | Does not appear to be used at this time. |
Definition at line 6812 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
06813 { 06814 int res = 0; 06815 int loops = 0; 06816 06817 res = ast_play_and_wait(chan, fn); /* Folder name */ 06818 while (((res < '0') || (res > '9')) && 06819 (res != '#') && (res >= 0) && 06820 loops < 4) { 06821 res = get_folder(chan, 0); 06822 loops++; 06823 } 06824 if (loops == 4) { /* give up */ 06825 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06826 return '#'; 06827 } 06828 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06829 return res; 06830 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1731 of file app_voicemail_imapstorage.c.
References ARRAY_LEN.
01732 { 01733 size_t i; 01734 01735 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01736 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01737 return i; 01738 } 01739 } 01740 01741 return -1; 01742 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11494 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, mwi_sub_task::mailbox, mwi_sub, poll_subscribed_mailbox(), mwi_sub_task::uniqueid, and ast_event_sub::uniqueid.
11495 { 11496 unsigned int len; 11497 struct mwi_sub *mwi_sub; 11498 struct mwi_sub_task *p = datap; 11499 11500 len = sizeof(*mwi_sub); 11501 if (!ast_strlen_zero(p->mailbox)) 11502 len += strlen(p->mailbox); 11503 11504 if (!ast_strlen_zero(p->context)) 11505 len += strlen(p->context) + 1; /* Allow for seperator */ 11506 11507 if (!(mwi_sub = ast_calloc(1, len))) 11508 return -1; 11509 11510 mwi_sub->uniqueid = p->uniqueid; 11511 if (!ast_strlen_zero(p->mailbox)) 11512 strcpy(mwi_sub->mailbox, p->mailbox); 11513 11514 if (!ast_strlen_zero(p->context)) { 11515 strcat(mwi_sub->mailbox, "@"); 11516 strcat(mwi_sub->mailbox, p->context); 11517 } 11518 11519 AST_RWLIST_WRLOCK(&mwi_subs); 11520 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11521 AST_RWLIST_UNLOCK(&mwi_subs); 11522 ast_free((void *) p->mailbox); 11523 ast_free((void *) p->context); 11524 ast_free(p); 11525 poll_subscribed_mailbox(mwi_sub); 11526 return 0; 11527 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11472 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::entry, mwi_sub, mwi_sub_destroy(), ast_event_sub::uniqueid, and mwi_sub::uniqueid.
11473 { 11474 struct mwi_sub *mwi_sub; 11475 uint32_t *uniqueid = datap; 11476 11477 AST_RWLIST_WRLOCK(&mwi_subs); 11478 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11479 if (mwi_sub->uniqueid == *uniqueid) { 11480 AST_LIST_REMOVE_CURRENT(entry); 11481 break; 11482 } 11483 } 11484 AST_RWLIST_TRAVERSE_SAFE_END 11485 AST_RWLIST_UNLOCK(&mwi_subs); 11486 11487 if (mwi_sub) 11488 mwi_sub_destroy(mwi_sub); 11489 11490 ast_free(uniqueid); 11491 return 0; 11492 }
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 11247 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.
11248 { 11249 switch (cmd) { 11250 case CLI_INIT: 11251 e->command = "voicemail reload"; 11252 e->usage = 11253 "Usage: voicemail reload\n" 11254 " Reload voicemail configuration\n"; 11255 return NULL; 11256 case CLI_GENERATE: 11257 return NULL; 11258 } 11259 11260 if (a->argc != 2) 11261 return CLI_SHOWUSAGE; 11262 11263 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11264 load_config(1); 11265 11266 return CLI_SUCCESS; 11267 }
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 11137 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::list, 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.
11138 { 11139 struct ast_vm_user *vmu; 11140 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11141 const char *context = NULL; 11142 int users_counter = 0; 11143 11144 switch (cmd) { 11145 case CLI_INIT: 11146 e->command = "voicemail show users"; 11147 e->usage = 11148 "Usage: voicemail show users [for <context>]\n" 11149 " Lists all mailboxes currently set up\n"; 11150 return NULL; 11151 case CLI_GENERATE: 11152 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11153 } 11154 11155 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11156 return CLI_SHOWUSAGE; 11157 if (a->argc == 5) { 11158 if (strcmp(a->argv[3],"for")) 11159 return CLI_SHOWUSAGE; 11160 context = a->argv[4]; 11161 } 11162 11163 if (ast_check_realtime("voicemail")) { 11164 if (!context) { 11165 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11166 return CLI_SHOWUSAGE; 11167 } 11168 return show_users_realtime(a->fd, context); 11169 } 11170 11171 AST_LIST_LOCK(&users); 11172 if (AST_LIST_EMPTY(&users)) { 11173 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11174 AST_LIST_UNLOCK(&users); 11175 return CLI_FAILURE; 11176 } 11177 if (a->argc == 3) 11178 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11179 else { 11180 int count = 0; 11181 AST_LIST_TRAVERSE(&users, vmu, list) { 11182 if (!strcmp(context, vmu->context)) 11183 count++; 11184 } 11185 if (count) { 11186 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11187 } else { 11188 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11189 AST_LIST_UNLOCK(&users); 11190 return CLI_FAILURE; 11191 } 11192 } 11193 AST_LIST_TRAVERSE(&users, vmu, list) { 11194 int newmsgs = 0, oldmsgs = 0; 11195 char count[12], tmp[256] = ""; 11196 11197 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 11198 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11199 inboxcount(tmp, &newmsgs, &oldmsgs); 11200 snprintf(count, sizeof(count), "%d", newmsgs); 11201 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11202 users_counter++; 11203 } 11204 } 11205 AST_LIST_UNLOCK(&users); 11206 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11207 return CLI_SUCCESS; 11208 }
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 11211 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::list, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.
11212 { 11213 struct vm_zone *zone; 11214 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11215 char *res = CLI_SUCCESS; 11216 11217 switch (cmd) { 11218 case CLI_INIT: 11219 e->command = "voicemail show zones"; 11220 e->usage = 11221 "Usage: voicemail show zones\n" 11222 " Lists zone message formats\n"; 11223 return NULL; 11224 case CLI_GENERATE: 11225 return NULL; 11226 } 11227 11228 if (a->argc != 3) 11229 return CLI_SHOWUSAGE; 11230 11231 AST_LIST_LOCK(&zones); 11232 if (!AST_LIST_EMPTY(&zones)) { 11233 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11234 AST_LIST_TRAVERSE(&zones, zone, list) { 11235 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11236 } 11237 } else { 11238 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11239 res = CLI_FAILURE; 11240 } 11241 AST_LIST_UNLOCK(&zones); 11242 11243 return res; 11244 }
static int has_voicemail | ( | const char * | mailbox, | |
const char * | folder | |||
) | [static] |
Determines if the given folder has messages.
mailbox | The @ delimited string for user. If no context is found, uses 'default' for the context. | |
folder | the folder to look in |
Definition at line 5426 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
05427 { 05428 char tmp[256], *tmp2 = tmp, *box, *context; 05429 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05430 if (ast_strlen_zero(folder)) { 05431 folder = "INBOX"; 05432 } 05433 while ((box = strsep(&tmp2, ",&"))) { 05434 if ((context = strchr(box, '@'))) 05435 *context++ = '\0'; 05436 else 05437 context = "default"; 05438 if (__has_voicemail(context, box, folder, 1)) 05439 return 1; 05440 /* If we are checking INBOX, we should check Urgent as well */ 05441 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05442 return 1; 05443 } 05444 } 05445 return 0; 05446 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5508 of file app_voicemail_imapstorage.c.
References inboxcount2().
05509 { 05510 int urgentmsgs = 0; 05511 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05512 if (newmsgs) { 05513 *newmsgs += urgentmsgs; 05514 } 05515 return res; 05516 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5449 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), inboxcount2(), and strsep().
05450 { 05451 char tmp[256]; 05452 char *context; 05453 05454 /* If no mailbox, return immediately */ 05455 if (ast_strlen_zero(mailbox)) 05456 return 0; 05457 05458 if (newmsgs) 05459 *newmsgs = 0; 05460 if (oldmsgs) 05461 *oldmsgs = 0; 05462 if (urgentmsgs) 05463 *urgentmsgs = 0; 05464 05465 if (strchr(mailbox, ',')) { 05466 int tmpnew, tmpold, tmpurgent; 05467 char *mb, *cur; 05468 05469 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05470 mb = tmp; 05471 while ((cur = strsep(&mb, ", "))) { 05472 if (!ast_strlen_zero(cur)) { 05473 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05474 return -1; 05475 else { 05476 if (newmsgs) 05477 *newmsgs += tmpnew; 05478 if (oldmsgs) 05479 *oldmsgs += tmpold; 05480 if (urgentmsgs) 05481 *urgentmsgs += tmpurgent; 05482 } 05483 } 05484 } 05485 return 0; 05486 } 05487 05488 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05489 05490 if ((context = strchr(tmp, '@'))) 05491 *context++ = '\0'; 05492 else 05493 context = "default"; 05494 05495 if (newmsgs) 05496 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05497 if (oldmsgs) 05498 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05499 if (urgentmsgs) 05500 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05501 05502 return 0; 05503 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4208 of file app_voicemail_imapstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
04209 { 04210 int l; 04211 04212 if (bio->ateof) 04213 return 0; 04214 04215 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04216 if (ferror(fi)) 04217 return -1; 04218 04219 bio->ateof = 1; 04220 return 0; 04221 } 04222 04223 bio->iolen = l; 04224 bio->iocp = 0; 04225 04226 return 1; 04227 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4232 of file app_voicemail_imapstorage.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
04233 { 04234 if (bio->iocp>=bio->iolen) { 04235 if (!inbuf(bio, fi)) 04236 return EOF; 04237 } 04238 04239 return bio->iobuf[bio->iocp++]; 04240 }
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.
00944 { 00945 struct inprocess *i = obj, *j = arg; 00946 if (strcmp(i->mailbox, j->mailbox)) { 00947 return 0; 00948 } 00949 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 00950 }
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_atomic_fetchadd_int(), ast_log(), inprocess::count, inprocess_container, and LOG_WARNING.
00953 { 00954 struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00955 arg->context = arg->mailbox + strlen(mailbox) + 1; 00956 strcpy(arg->mailbox, mailbox); /* SAFE */ 00957 strcpy(arg->context, context); /* SAFE */ 00958 ao2_lock(inprocess_container); 00959 if ((i = ao2_find(inprocess_container, arg, 0))) { 00960 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00961 ao2_unlock(inprocess_container); 00962 ao2_ref(i, -1); 00963 return ret; 00964 } 00965 if (delta < 0) { 00966 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00967 } 00968 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00969 ao2_unlock(inprocess_container); 00970 return 0; 00971 } 00972 i->context = i->mailbox + strlen(mailbox) + 1; 00973 strcpy(i->mailbox, mailbox); /* SAFE */ 00974 strcpy(i->context, context); /* SAFE */ 00975 i->count = delta; 00976 ao2_link(inprocess_container, i); 00977 ao2_unlock(inprocess_container); 00978 ao2_ref(i, -1); 00979 return 0; 00980 }
static int inprocess_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
static int invent_message | ( | struct ast_channel * | chan, | |
char * | context, | |||
char * | ext, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 5048 of file app_voicemail_imapstorage.c.
References ast_fileexists(), ast_log(), ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, ast_channel::language, RETRIEVE, and VM_SPOOL_DIR.
05049 { 05050 int res; 05051 char fn[PATH_MAX]; 05052 char dest[PATH_MAX]; 05053 05054 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05055 05056 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05057 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05058 return -1; 05059 } 05060 05061 RETRIEVE(fn, -1, ext, context); 05062 if (ast_fileexists(fn, NULL, NULL) > 0) { 05063 res = ast_stream_and_wait(chan, fn, ecodes); 05064 if (res) { 05065 DISPOSE(fn, -1); 05066 return res; 05067 } 05068 } else { 05069 /* Dispose just in case */ 05070 DISPOSE(fn, -1); 05071 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05072 if (res) 05073 return res; 05074 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05075 if (res) 05076 return res; 05077 } 05078 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05079 return res; 05080 }
static int is_valid_dtmf | ( | const char * | key | ) | [static] |
Determines if a DTMF key entered is valid.
key | The character to be compared. expects a single character. Though is capable of handling a string, this is internally copies using ast_strdupa. |
Definition at line 1379 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
01380 { 01381 int i; 01382 char *local_key = ast_strdupa(key); 01383 01384 for (i = 0; i < strlen(key); ++i) { 01385 if (!strchr(VALID_DTMF, *local_key)) { 01386 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01387 return 0; 01388 } 01389 local_key++; 01390 } 01391 return 1; 01392 }
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.
vmu | ||
dir | the folder the mailbox folder to look for messages. Used to construct the SQL where clause. |
Definition at line 4026 of file app_voicemail_imapstorage.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
04027 { 04028 int x; 04029 unsigned char map[MAXMSGLIMIT] = ""; 04030 DIR *msgdir; 04031 struct dirent *msgdirent; 04032 int msgdirint; 04033 char extension[4]; 04034 int stopcount = 0; 04035 04036 /* Reading the entire directory into a file map scales better than 04037 * doing a stat repeatedly on a predicted sequence. I suspect this 04038 * is partially due to stat(2) internally doing a readdir(2) itself to 04039 * find each file. */ 04040 if (!(msgdir = opendir(dir))) { 04041 return -1; 04042 } 04043 04044 while ((msgdirent = readdir(msgdir))) { 04045 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04046 map[msgdirint] = 1; 04047 stopcount++; 04048 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04049 } 04050 } 04051 closedir(msgdir); 04052 04053 for (x = 0; x < vmu->maxmsg; x++) { 04054 if (map[x] == 1) { 04055 stopcount--; 04056 } else if (map[x] == 0 && !stopcount) { 04057 break; 04058 } 04059 } 04060 04061 return x - 1; 04062 }
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.
chan | ||
ext | ||
options | OPT_BUSY_GREETING, OPT_UNAVAIL_GREETING |
Definition at line 5581 of file app_voicemail_imapstorage.c.
References ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_exists_extension(), ast_fileexists(), ast_free, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::caller, ast_channel::context, ast_vm_user::context, create_dirpath(), DISPOSE, errno, ast_vm_user::exit, find_user(), ast_party_caller::id, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, ast_party_id::number, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), RETRIEVE, S_COR, ast_party_number::str, ast_party_number::valid, VM_OPERATOR, VM_SPOOL_DIR, and VOICEMAIL_DIR_MODE.
05582 { 05583 #ifdef IMAP_STORAGE 05584 int newmsgs, oldmsgs; 05585 #else 05586 char urgdir[PATH_MAX]; 05587 #endif 05588 char txtfile[PATH_MAX]; 05589 char tmptxtfile[PATH_MAX]; 05590 struct vm_state *vms = NULL; 05591 char callerid[256]; 05592 FILE *txt; 05593 char date[256]; 05594 int txtdes; 05595 int res = 0; 05596 int msgnum; 05597 int duration = 0; 05598 int sound_duration = 0; 05599 int ausemacro = 0; 05600 int ousemacro = 0; 05601 int ouseexten = 0; 05602 char tmpdur[16]; 05603 char priority[16]; 05604 char origtime[16]; 05605 char dir[PATH_MAX]; 05606 char tmpdir[PATH_MAX]; 05607 char fn[PATH_MAX]; 05608 char prefile[PATH_MAX] = ""; 05609 char tempfile[PATH_MAX] = ""; 05610 char ext_context[256] = ""; 05611 char fmt[80]; 05612 char *context; 05613 char ecodes[17] = "#"; 05614 struct ast_str *tmp = ast_str_create(16); 05615 char *tmpptr; 05616 struct ast_vm_user *vmu; 05617 struct ast_vm_user svm; 05618 const char *category = NULL; 05619 const char *code; 05620 const char *alldtmf = "0123456789ABCD*#"; 05621 char flag[80]; 05622 05623 if (!tmp) { 05624 return -1; 05625 } 05626 05627 ast_str_set(&tmp, 0, "%s", ext); 05628 ext = ast_str_buffer(tmp); 05629 if ((context = strchr(ext, '@'))) { 05630 *context++ = '\0'; 05631 tmpptr = strchr(context, '&'); 05632 } else { 05633 tmpptr = strchr(ext, '&'); 05634 } 05635 05636 if (tmpptr) 05637 *tmpptr++ = '\0'; 05638 05639 ast_channel_lock(chan); 05640 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05641 category = ast_strdupa(category); 05642 } 05643 ast_channel_unlock(chan); 05644 05645 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05646 ast_copy_string(flag, "Urgent", sizeof(flag)); 05647 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05648 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05649 } else { 05650 flag[0] = '\0'; 05651 } 05652 05653 ast_debug(3, "Before find_user\n"); 05654 if (!(vmu = find_user(&svm, context, ext))) { 05655 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05656 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05657 ast_free(tmp); 05658 return res; 05659 } 05660 /* Setup pre-file if appropriate */ 05661 if (strcmp(vmu->context, "default")) 05662 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05663 else 05664 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05665 05666 /* Set the path to the prefile. Will be one of 05667 VM_SPOOL_DIRcontext/ext/busy 05668 VM_SPOOL_DIRcontext/ext/unavail 05669 Depending on the flag set in options. 05670 */ 05671 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05672 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05673 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05674 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05675 } 05676 /* Set the path to the tmpfile as 05677 VM_SPOOL_DIR/context/ext/temp 05678 and attempt to create the folder structure. 05679 */ 05680 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05681 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05682 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05683 ast_free(tmp); 05684 return -1; 05685 } 05686 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05687 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05688 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05689 05690 DISPOSE(tempfile, -1); 05691 /* It's easier just to try to make it than to check for its existence */ 05692 #ifndef IMAP_STORAGE 05693 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05694 #else 05695 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05696 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05697 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05698 } 05699 #endif 05700 05701 /* Check current or macro-calling context for special extensions */ 05702 if (ast_test_flag(vmu, VM_OPERATOR)) { 05703 if (!ast_strlen_zero(vmu->exit)) { 05704 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05705 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05706 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05707 ouseexten = 1; 05708 } 05709 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05710 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05711 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05712 ouseexten = 1; 05713 } else if (!ast_strlen_zero(chan->macrocontext) 05714 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05715 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05716 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05717 ousemacro = 1; 05718 } 05719 } 05720 05721 if (!ast_strlen_zero(vmu->exit)) { 05722 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05723 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05724 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05725 } 05726 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05727 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05728 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05729 } else if (!ast_strlen_zero(chan->macrocontext) 05730 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05731 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05732 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05733 ausemacro = 1; 05734 } 05735 05736 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05737 for (code = alldtmf; *code; code++) { 05738 char e[2] = ""; 05739 e[0] = *code; 05740 if (strchr(ecodes, e[0]) == NULL 05741 && ast_canmatch_extension(chan, chan->context, e, 1, 05742 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05743 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05744 } 05745 } 05746 } 05747 05748 /* Play the beginning intro if desired */ 05749 if (!ast_strlen_zero(prefile)) { 05750 #ifdef ODBC_STORAGE 05751 int success = 05752 #endif 05753 RETRIEVE(prefile, -1, ext, context); 05754 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05755 if (ast_streamfile(chan, prefile, chan->language) > -1) 05756 res = ast_waitstream(chan, ecodes); 05757 #ifdef ODBC_STORAGE 05758 if (success == -1) { 05759 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05760 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05761 store_file(prefile, vmu->mailbox, vmu->context, -1); 05762 } 05763 #endif 05764 } else { 05765 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05766 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05767 } 05768 DISPOSE(prefile, -1); 05769 if (res < 0) { 05770 ast_debug(1, "Hang up during prefile playback\n"); 05771 free_user(vmu); 05772 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05773 ast_free(tmp); 05774 return -1; 05775 } 05776 } 05777 if (res == '#') { 05778 /* On a '#' we skip the instructions */ 05779 ast_set_flag(options, OPT_SILENT); 05780 res = 0; 05781 } 05782 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05783 if (vmu->maxmsg == 0) { 05784 if (option_debug > 2) 05785 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05786 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05787 goto leave_vm_out; 05788 } 05789 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05790 res = ast_stream_and_wait(chan, INTRO, ecodes); 05791 if (res == '#') { 05792 ast_set_flag(options, OPT_SILENT); 05793 res = 0; 05794 } 05795 } 05796 if (res > 0) 05797 ast_stopstream(chan); 05798 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05799 other than the operator -- an automated attendant or mailbox login for example */ 05800 if (res == '*') { 05801 chan->exten[0] = 'a'; 05802 chan->exten[1] = '\0'; 05803 if (!ast_strlen_zero(vmu->exit)) { 05804 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05805 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05806 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05807 } 05808 chan->priority = 0; 05809 free_user(vmu); 05810 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05811 ast_free(tmp); 05812 return 0; 05813 } 05814 05815 /* Check for a '0' here */ 05816 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05817 transfer: 05818 if (ouseexten || ousemacro) { 05819 chan->exten[0] = 'o'; 05820 chan->exten[1] = '\0'; 05821 if (!ast_strlen_zero(vmu->exit)) { 05822 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05823 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05824 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05825 } 05826 ast_play_and_wait(chan, "transfer"); 05827 chan->priority = 0; 05828 free_user(vmu); 05829 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05830 } 05831 ast_free(tmp); 05832 return OPERATOR_EXIT; 05833 } 05834 05835 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05836 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05837 if (!ast_strlen_zero(options->exitcontext)) 05838 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05839 free_user(vmu); 05840 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05841 ast_free(tmp); 05842 return res; 05843 } 05844 05845 if (res < 0) { 05846 free_user(vmu); 05847 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05848 ast_free(tmp); 05849 return -1; 05850 } 05851 /* The meat of recording the message... All the announcements and beeps have been played*/ 05852 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05853 if (!ast_strlen_zero(fmt)) { 05854 msgnum = 0; 05855 05856 #ifdef IMAP_STORAGE 05857 /* Is ext a mailbox? */ 05858 /* must open stream for this user to get info! */ 05859 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05860 if (res < 0) { 05861 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05862 ast_free(tmp); 05863 return -1; 05864 } 05865 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05866 /* It is possible under certain circumstances that inboxcount did not 05867 * create a vm_state when it was needed. This is a catchall which will 05868 * rarely be used. 05869 */ 05870 if (!(vms = create_vm_state_from_user(vmu))) { 05871 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05872 ast_free(tmp); 05873 return -1; 05874 } 05875 } 05876 vms->newmessages++; 05877 05878 /* here is a big difference! We add one to it later */ 05879 msgnum = newmsgs + oldmsgs; 05880 ast_debug(3, "Messagecount set to %d\n", msgnum); 05881 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05882 /* set variable for compatibility */ 05883 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05884 05885 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05886 goto leave_vm_out; 05887 } 05888 #else 05889 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05890 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05891 if (!res) 05892 res = ast_waitstream(chan, ""); 05893 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05894 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05895 inprocess_count(vmu->mailbox, vmu->context, -1); 05896 goto leave_vm_out; 05897 } 05898 05899 #endif 05900 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05901 txtdes = mkstemp(tmptxtfile); 05902 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05903 if (txtdes < 0) { 05904 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05905 if (!res) 05906 res = ast_waitstream(chan, ""); 05907 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05908 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05909 inprocess_count(vmu->mailbox, vmu->context, -1); 05910 goto leave_vm_out; 05911 } 05912 05913 /* Now play the beep once we have the message number for our next message. */ 05914 if (res >= 0) { 05915 /* Unless we're *really* silent, try to send the beep */ 05916 res = ast_stream_and_wait(chan, "beep", ""); 05917 } 05918 05919 /* Store information in real-time storage */ 05920 if (ast_check_realtime("voicemail_data")) { 05921 snprintf(priority, sizeof(priority), "%d", chan->priority); 05922 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05923 get_date(date, sizeof(date)); 05924 ast_callerid_merge(callerid, sizeof(callerid), 05925 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05926 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05927 "Unknown"); 05928 ast_store_realtime("voicemail_data", 05929 "origmailbox", ext, 05930 "context", chan->context, 05931 "macrocontext", chan->macrocontext, 05932 "exten", chan->exten, 05933 "priority", priority, 05934 "callerchan", chan->name, 05935 "callerid", callerid, 05936 "origdate", date, 05937 "origtime", origtime, 05938 "category", S_OR(category, ""), 05939 "filename", tmptxtfile, 05940 SENTINEL); 05941 } 05942 05943 /* Store information */ 05944 txt = fdopen(txtdes, "w+"); 05945 if (txt) { 05946 get_date(date, sizeof(date)); 05947 ast_callerid_merge(callerid, sizeof(callerid), 05948 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05949 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05950 "Unknown"); 05951 fprintf(txt, 05952 ";\n" 05953 "; Message Information file\n" 05954 ";\n" 05955 "[message]\n" 05956 "origmailbox=%s\n" 05957 "context=%s\n" 05958 "macrocontext=%s\n" 05959 "exten=%s\n" 05960 "rdnis=%s\n" 05961 "priority=%d\n" 05962 "callerchan=%s\n" 05963 "callerid=%s\n" 05964 "origdate=%s\n" 05965 "origtime=%ld\n" 05966 "category=%s\n", 05967 ext, 05968 chan->context, 05969 chan->macrocontext, 05970 chan->exten, 05971 S_COR(chan->redirecting.from.number.valid, 05972 chan->redirecting.from.number.str, "unknown"), 05973 chan->priority, 05974 chan->name, 05975 callerid, 05976 date, (long) time(NULL), 05977 category ? category : ""); 05978 } else { 05979 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05980 inprocess_count(vmu->mailbox, vmu->context, -1); 05981 if (ast_check_realtime("voicemail_data")) { 05982 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05983 } 05984 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05985 goto leave_vm_out; 05986 } 05987 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05988 05989 if (txt) { 05990 fprintf(txt, "flag=%s\n", flag); 05991 if (sound_duration < vmu->minsecs) { 05992 fclose(txt); 05993 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 05994 ast_filedelete(tmptxtfile, NULL); 05995 unlink(tmptxtfile); 05996 if (ast_check_realtime("voicemail_data")) { 05997 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05998 } 05999 inprocess_count(vmu->mailbox, vmu->context, -1); 06000 } else { 06001 fprintf(txt, "duration=%d\n", duration); 06002 fclose(txt); 06003 if (vm_lock_path(dir)) { 06004 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06005 /* Delete files */ 06006 ast_filedelete(tmptxtfile, NULL); 06007 unlink(tmptxtfile); 06008 inprocess_count(vmu->mailbox, vmu->context, -1); 06009 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06010 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06011 unlink(tmptxtfile); 06012 ast_unlock_path(dir); 06013 inprocess_count(vmu->mailbox, vmu->context, -1); 06014 if (ast_check_realtime("voicemail_data")) { 06015 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06016 } 06017 } else { 06018 #ifndef IMAP_STORAGE 06019 msgnum = last_message_index(vmu, dir) + 1; 06020 #endif 06021 make_file(fn, sizeof(fn), dir, msgnum); 06022 06023 /* assign a variable with the name of the voicemail file */ 06024 #ifndef IMAP_STORAGE 06025 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06026 #else 06027 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06028 #endif 06029 06030 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06031 ast_filerename(tmptxtfile, fn, NULL); 06032 rename(tmptxtfile, txtfile); 06033 inprocess_count(vmu->mailbox, vmu->context, -1); 06034 06035 /* Properly set permissions on voicemail text descriptor file. 06036 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06037 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06038 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06039 06040 ast_unlock_path(dir); 06041 if (ast_check_realtime("voicemail_data")) { 06042 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06043 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06044 } 06045 /* We must store the file first, before copying the message, because 06046 * ODBC storage does the entire copy with SQL. 06047 */ 06048 if (ast_fileexists(fn, NULL, NULL) > 0) { 06049 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06050 } 06051 06052 /* Are there to be more recipients of this message? */ 06053 while (tmpptr) { 06054 struct ast_vm_user recipu, *recip; 06055 char *exten, *cntx; 06056 06057 exten = strsep(&tmpptr, "&"); 06058 cntx = strchr(exten, '@'); 06059 if (cntx) { 06060 *cntx = '\0'; 06061 cntx++; 06062 } 06063 if ((recip = find_user(&recipu, cntx, exten))) { 06064 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06065 free_user(recip); 06066 } 06067 } 06068 #ifndef IMAP_STORAGE 06069 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06070 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06071 char sfn[PATH_MAX]; 06072 char dfn[PATH_MAX]; 06073 int x; 06074 /* It's easier just to try to make it than to check for its existence */ 06075 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06076 x = last_message_index(vmu, urgdir) + 1; 06077 make_file(sfn, sizeof(sfn), dir, msgnum); 06078 make_file(dfn, sizeof(dfn), urgdir, x); 06079 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06080 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06081 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06082 ast_copy_string(fn, dfn, sizeof(fn)); 06083 msgnum = x; 06084 } 06085 #endif 06086 /* Notification needs to happen after the copy, though. */ 06087 if (ast_fileexists(fn, NULL, NULL)) { 06088 #ifdef IMAP_STORAGE 06089 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06090 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06091 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06092 flag); 06093 #else 06094 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06095 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06096 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06097 flag); 06098 #endif 06099 } 06100 06101 /* Disposal needs to happen after the optional move and copy */ 06102 if (ast_fileexists(fn, NULL, NULL)) { 06103 DISPOSE(dir, msgnum); 06104 } 06105 } 06106 } 06107 } else { 06108 inprocess_count(vmu->mailbox, vmu->context, -1); 06109 } 06110 if (res == '0') { 06111 goto transfer; 06112 } else if (res > 0 && res != 't') 06113 res = 0; 06114 06115 if (sound_duration < vmu->minsecs) 06116 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06117 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06118 else 06119 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06120 } else 06121 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06122 leave_vm_out: 06123 free_user(vmu); 06124 06125 #ifdef IMAP_STORAGE 06126 /* expunge message - use UID Expunge if supported on IMAP server*/ 06127 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06128 if (expungeonhangup == 1) { 06129 ast_mutex_lock(&vms->lock); 06130 #ifdef HAVE_IMAP_TK2006 06131 if (LEVELUIDPLUS (vms->mailstream)) { 06132 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06133 } else 06134 #endif 06135 mail_expunge(vms->mailstream); 06136 ast_mutex_unlock(&vms->lock); 06137 } 06138 #endif 06139 06140 ast_free(tmp); 06141 return res; 06142 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11779 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_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
11780 { 11781 struct ast_config *cfg, *ucfg; 11782 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11783 int res; 11784 11785 ast_unload_realtime("voicemail"); 11786 ast_unload_realtime("voicemail_data"); 11787 11788 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11789 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11790 return 0; 11791 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11792 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11793 ucfg = NULL; 11794 } 11795 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11796 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11797 ast_config_destroy(ucfg); 11798 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11799 return 0; 11800 } 11801 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11802 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11803 return 0; 11804 } else { 11805 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11806 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11807 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11808 ucfg = NULL; 11809 } 11810 } 11811 11812 res = actual_load_config(reload, cfg, ucfg); 11813 11814 ast_config_destroy(cfg); 11815 ast_config_destroy(ucfg); 11816 11817 return res; 11818 }
static int load_module | ( | void | ) | [static] |
Definition at line 13070 of file app_voicemail_imapstorage.c.
References ao2_container_alloc, app, app2, app3, app4, 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_manager_register_xml, AST_MODULE_LOAD_DECLINE, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), AST_TEST_REGISTER, cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), inprocess_cmp_fn(), inprocess_container, inprocess_hash_fn(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, my_umask, RQ_CHAR, RQ_UINTEGER3, sayname(), sayname_app, SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), VM_SPOOL_DIR, vmauthenticate(), and vmsayname_exec().
13071 { 13072 int res; 13073 my_umask = umask(0); 13074 umask(my_umask); 13075 13076 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13077 return AST_MODULE_LOAD_DECLINE; 13078 } 13079 13080 /* compute the location of the voicemail spool directory */ 13081 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13082 13083 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13084 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13085 } 13086 13087 if ((res = load_config(0))) 13088 return res; 13089 13090 res = ast_register_application_xml(app, vm_exec); 13091 res |= ast_register_application_xml(app2, vm_execmain); 13092 res |= ast_register_application_xml(app3, vm_box_exists); 13093 res |= ast_register_application_xml(app4, vmauthenticate); 13094 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13095 res |= ast_custom_function_register(&mailbox_exists_acf); 13096 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13097 #ifdef TEST_FRAMEWORK 13098 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13099 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13100 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13101 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13102 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13103 #endif 13104 13105 if (res) 13106 return res; 13107 13108 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13109 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13110 13111 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13112 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13113 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13114 13115 return res; 13116 }
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.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
context | ||
ext | ||
folder |
Definition at line 1643 of file app_voicemail_imapstorage.c.
References VM_SPOOL_DIR.
01644 { 01645 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01646 }
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.
p | The output file to generate the email contents into. | |
srcemail | The email address to send the email to, presumably the email address for the owner of the mailbox. | |
vmu | The voicemail user who is sending the voicemail. | |
msgnum | The message index in the mailbox folder. | |
context | ||
mailbox | The voicemail box to read the voicemail to be notified in this email. | |
fromfolder | ||
cidnum | The caller ID number. | |
cidname | The caller ID name. | |
attach | the name of the sound file to be attached to the email, if attach_user_voicemail == 1. | |
attach2 | ||
format | The message sound file format. i.e. .wav | |
duration | The time of the message content, in seconds. | |
attach_user_voicemail | if 1, the sound file is attached to the email. | |
chan | ||
category | ||
imap | if == 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. | |
flag | The 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 4525 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_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_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, 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(), VM_PBXSKIP, and vmu_tm().
04526 { 04527 char date[256]; 04528 char host[MAXHOSTNAMELEN] = ""; 04529 char who[256]; 04530 char bound[256]; 04531 char dur[256]; 04532 struct ast_tm tm; 04533 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04534 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04535 char *greeting_attachment; 04536 char filename[256]; 04537 04538 if (!str1 || !str2) { 04539 ast_free(str1); 04540 ast_free(str2); 04541 return; 04542 } 04543 04544 if (cidnum) { 04545 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04546 } 04547 if (cidname) { 04548 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04549 } 04550 gethostname(host, sizeof(host) - 1); 04551 04552 if (strchr(srcemail, '@')) { 04553 ast_copy_string(who, srcemail, sizeof(who)); 04554 } else { 04555 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04556 } 04557 04558 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04559 if (greeting_attachment) { 04560 *greeting_attachment++ = '\0'; 04561 } 04562 04563 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04564 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04565 fprintf(p, "Date: %s" ENDL, date); 04566 04567 /* Set date format for voicemail mail */ 04568 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04569 04570 if (!ast_strlen_zero(fromstring)) { 04571 struct ast_channel *ast; 04572 if ((ast = ast_dummy_channel_alloc())) { 04573 char *ptr; 04574 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04575 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04576 04577 if (check_mime(ast_str_buffer(str1))) { 04578 int first_line = 1; 04579 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04580 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04581 *ptr = '\0'; 04582 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04583 first_line = 0; 04584 /* Substring is smaller, so this will never grow */ 04585 ast_str_set(&str2, 0, "%s", ptr + 1); 04586 } 04587 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04588 } else { 04589 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04590 } 04591 ast = ast_channel_unref(ast); 04592 } else { 04593 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04594 } 04595 } else { 04596 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04597 } 04598 04599 if (check_mime(vmu->fullname)) { 04600 int first_line = 1; 04601 char *ptr; 04602 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04603 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04604 *ptr = '\0'; 04605 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04606 first_line = 0; 04607 /* Substring is smaller, so this will never grow */ 04608 ast_str_set(&str2, 0, "%s", ptr + 1); 04609 } 04610 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04611 } else { 04612 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04613 } 04614 04615 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04616 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04617 struct ast_channel *ast; 04618 if ((ast = ast_dummy_channel_alloc())) { 04619 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04620 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04621 if (check_mime(ast_str_buffer(str1))) { 04622 int first_line = 1; 04623 char *ptr; 04624 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04625 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04626 *ptr = '\0'; 04627 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04628 first_line = 0; 04629 /* Substring is smaller, so this will never grow */ 04630 ast_str_set(&str2, 0, "%s", ptr + 1); 04631 } 04632 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04633 } else { 04634 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04635 } 04636 ast = ast_channel_unref(ast); 04637 } else { 04638 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04639 } 04640 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04641 if (ast_strlen_zero(flag)) { 04642 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04643 } else { 04644 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04645 } 04646 } else { 04647 if (ast_strlen_zero(flag)) { 04648 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04649 } else { 04650 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04651 } 04652 } 04653 04654 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04655 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04656 if (imap) { 04657 /* additional information needed for IMAP searching */ 04658 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04659 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04660 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04661 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04662 #ifdef IMAP_STORAGE 04663 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04664 #else 04665 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04666 #endif 04667 /* flag added for Urgent */ 04668 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04669 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04670 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04671 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04672 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04673 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04674 if (!ast_strlen_zero(category)) { 04675 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04676 } else { 04677 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04678 } 04679 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04680 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04681 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04682 } 04683 if (!ast_strlen_zero(cidnum)) { 04684 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04685 } 04686 if (!ast_strlen_zero(cidname)) { 04687 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04688 } 04689 fprintf(p, "MIME-Version: 1.0" ENDL); 04690 if (attach_user_voicemail) { 04691 /* Something unique. */ 04692 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04693 (int) getpid(), (unsigned int) ast_random()); 04694 04695 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04696 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04697 fprintf(p, "--%s" ENDL, bound); 04698 } 04699 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04700 if (emailbody || vmu->emailbody) { 04701 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04702 struct ast_channel *ast; 04703 if ((ast = ast_dummy_channel_alloc())) { 04704 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04705 ast_str_substitute_variables(&str1, 0, ast, e_body); 04706 #ifdef IMAP_STORAGE 04707 { 04708 /* Convert body to native line terminators for IMAP backend */ 04709 char *line = ast_str_buffer(str1), *next; 04710 do { 04711 /* Terminate line before outputting it to the file */ 04712 if ((next = strchr(line, '\n'))) { 04713 *next++ = '\0'; 04714 } 04715 fprintf(p, "%s" ENDL, line); 04716 line = next; 04717 } while (!ast_strlen_zero(line)); 04718 } 04719 #else 04720 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04721 #endif 04722 ast = ast_channel_unref(ast); 04723 } else { 04724 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04725 } 04726 } else if (msgnum > -1) { 04727 if (strcmp(vmu->mailbox, mailbox)) { 04728 /* Forwarded type */ 04729 struct ast_config *msg_cfg; 04730 const char *v; 04731 int inttime; 04732 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04733 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04734 /* Retrieve info from VM attribute file */ 04735 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04736 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04737 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04738 strcat(fromfile, ".txt"); 04739 } 04740 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04741 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04742 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04743 } 04744 04745 /* You might be tempted to do origdate, except that a) it's in the wrong 04746 * format, and b) it's missing for IMAP recordings. */ 04747 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04748 struct timeval tv = { inttime, }; 04749 struct ast_tm tm; 04750 ast_localtime(&tv, &tm, NULL); 04751 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04752 } 04753 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04754 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04755 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04756 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04757 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04758 date, origcallerid, origdate); 04759 ast_config_destroy(msg_cfg); 04760 } else { 04761 goto plain_message; 04762 } 04763 } else { 04764 plain_message: 04765 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04766 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04767 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04768 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04769 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04770 } 04771 } else { 04772 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04773 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04774 } 04775 04776 if (imap || attach_user_voicemail) { 04777 if (!ast_strlen_zero(attach2)) { 04778 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04779 ast_debug(5, "creating second attachment filename %s\n", filename); 04780 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04781 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04782 ast_debug(5, "creating attachment filename %s\n", filename); 04783 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04784 } else { 04785 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04786 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04787 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04788 } 04789 } 04790 ast_free(str1); 04791 ast_free(str2); 04792 }
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.
dest | The variable to hold the output generated path expression. This buffer should be of size PATH_MAX. | |
len | The length of the path string that was written out. | |
dir | ||
num |
Definition at line 1660 of file app_voicemail_imapstorage.c.
01661 { 01662 return snprintf(dest, len, "%s/msg%04d", dir, num); 01663 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11610 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::list, ast_vm_user::mailbox, ast_vm_user::mailcmd, 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.
11611 { 11612 struct ast_vm_user *vmu = NULL; 11613 const char *id = astman_get_header(m, "ActionID"); 11614 char actionid[128] = ""; 11615 11616 if (!ast_strlen_zero(id)) 11617 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11618 11619 AST_LIST_LOCK(&users); 11620 11621 if (AST_LIST_EMPTY(&users)) { 11622 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11623 AST_LIST_UNLOCK(&users); 11624 return RESULT_SUCCESS; 11625 } 11626 11627 astman_send_ack(s, m, "Voicemail user list will follow"); 11628 11629 AST_LIST_TRAVERSE(&users, vmu, list) { 11630 char dirname[256]; 11631 11632 #ifdef IMAP_STORAGE 11633 int new, old; 11634 inboxcount(vmu->mailbox, &new, &old); 11635 #endif 11636 11637 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11638 astman_append(s, 11639 "%s" 11640 "Event: VoicemailUserEntry\r\n" 11641 "VMContext: %s\r\n" 11642 "VoiceMailbox: %s\r\n" 11643 "Fullname: %s\r\n" 11644 "Email: %s\r\n" 11645 "Pager: %s\r\n" 11646 "ServerEmail: %s\r\n" 11647 "MailCommand: %s\r\n" 11648 "Language: %s\r\n" 11649 "TimeZone: %s\r\n" 11650 "Callback: %s\r\n" 11651 "Dialout: %s\r\n" 11652 "UniqueID: %s\r\n" 11653 "ExitContext: %s\r\n" 11654 "SayDurationMinimum: %d\r\n" 11655 "SayEnvelope: %s\r\n" 11656 "SayCID: %s\r\n" 11657 "AttachMessage: %s\r\n" 11658 "AttachmentFormat: %s\r\n" 11659 "DeleteMessage: %s\r\n" 11660 "VolumeGain: %.2f\r\n" 11661 "CanReview: %s\r\n" 11662 "CallOperator: %s\r\n" 11663 "MaxMessageCount: %d\r\n" 11664 "MaxMessageLength: %d\r\n" 11665 "NewMessageCount: %d\r\n" 11666 #ifdef IMAP_STORAGE 11667 "OldMessageCount: %d\r\n" 11668 "IMAPUser: %s\r\n" 11669 #endif 11670 "\r\n", 11671 actionid, 11672 vmu->context, 11673 vmu->mailbox, 11674 vmu->fullname, 11675 vmu->email, 11676 vmu->pager, 11677 vmu->serveremail, 11678 vmu->mailcmd, 11679 vmu->language, 11680 vmu->zonetag, 11681 vmu->callback, 11682 vmu->dialout, 11683 vmu->uniqueid, 11684 vmu->exit, 11685 vmu->saydurationm, 11686 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11687 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11688 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11689 vmu->attachfmt, 11690 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11691 vmu->volgain, 11692 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11693 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11694 vmu->maxmsg, 11695 vmu->maxsecs, 11696 #ifdef IMAP_STORAGE 11697 new, old, vmu->imapuser 11698 #else 11699 count_messages(vmu, dirname) 11700 #endif 11701 ); 11702 } 11703 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11704 11705 AST_LIST_UNLOCK(&users); 11706 11707 return RESULT_SUCCESS; 11708 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11444 of file app_voicemail_imapstorage.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_cond, poll_freq, poll_lock, poll_subscribed_mailboxes(), and poll_thread_run.
11445 { 11446 while (poll_thread_run) { 11447 struct timespec ts = { 0, }; 11448 struct timeval wait; 11449 11450 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11451 ts.tv_sec = wait.tv_sec; 11452 ts.tv_nsec = wait.tv_usec * 1000; 11453 11454 ast_mutex_lock(&poll_lock); 11455 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11456 ast_mutex_unlock(&poll_lock); 11457 11458 if (!poll_thread_run) 11459 break; 11460 11461 poll_subscribed_mailboxes(); 11462 } 11463 11464 return NULL; 11465 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1721 of file app_voicemail_imapstorage.c.
References ARRAY_LEN.
01722 { 01723 #ifdef IMAP_STORAGE 01724 if (vmu && id == 0) { 01725 return vmu->imapfolder; 01726 } 01727 #endif 01728 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01729 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5375 of file app_voicemail_imapstorage.c.
References __has_voicemail().
05376 { 05377 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05378 }
static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11545 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(), handle_subscribe(), LOG_ERROR, and mwi_subscription_tps.
11546 { 11547 struct mwi_sub_task *mwist; 11548 11549 if (ast_event_get_type(event) != AST_EVENT_SUB) 11550 return; 11551 11552 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11553 return; 11554 11555 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11556 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11557 return; 11558 } 11559 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11560 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11561 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11562 11563 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11564 ast_free(mwist); 11565 } 11566 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11529 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_taskprocessor_push(), handle_unsubscribe(), mwi_subscription_tps, and mwi_sub_task::uniqueid.
11530 { 11531 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11532 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11533 return; 11534 11535 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11536 return; 11537 11538 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11539 *uniqueid = u; 11540 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11541 ast_free(uniqueid); 11542 } 11543 }
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.
chan | ||
vmu | ||
vms | ||
msgnum | ||
duration | ||
fmt | ||
cidnum | The Caller ID phone number value. | |
cidname | The Caller ID name value. | |
flag |
Definition at line 7040 of file app_voicemail_imapstorage.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), 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(), VM_DELETE, and VM_SPOOL_DIR.
07041 { 07042 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07043 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07044 const char *category; 07045 char *myserveremail = serveremail; 07046 07047 ast_channel_lock(chan); 07048 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07049 category = ast_strdupa(category); 07050 } 07051 ast_channel_unlock(chan); 07052 07053 #ifndef IMAP_STORAGE 07054 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07055 #else 07056 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07057 #endif 07058 make_file(fn, sizeof(fn), todir, msgnum); 07059 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07060 07061 if (!ast_strlen_zero(vmu->attachfmt)) { 07062 if (strstr(fmt, vmu->attachfmt)) 07063 fmt = vmu->attachfmt; 07064 else 07065 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); 07066 } 07067 07068 /* Attach only the first format */ 07069 fmt = ast_strdupa(fmt); 07070 stringp = fmt; 07071 strsep(&stringp, "|"); 07072 07073 if (!ast_strlen_zero(vmu->serveremail)) 07074 myserveremail = vmu->serveremail; 07075 07076 if (!ast_strlen_zero(vmu->email)) { 07077 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07078 07079 if (attach_user_voicemail) 07080 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07081 07082 /* XXX possible imap issue, should category be NULL XXX */ 07083 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07084 07085 if (attach_user_voicemail) 07086 DISPOSE(todir, msgnum); 07087 } 07088 07089 if (!ast_strlen_zero(vmu->pager)) { 07090 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07091 } 07092 07093 if (ast_test_flag(vmu, VM_DELETE)) 07094 DELETE(todir, msgnum, fn, vmu); 07095 07096 /* Leave voicemail for someone */ 07097 if (ast_app_has_voicemail(ext_context, NULL)) 07098 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07099 07100 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07101 07102 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); 07103 run_externnotify(vmu->context, vmu->mailbox, flag); 07104 07105 #ifdef IMAP_STORAGE 07106 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07107 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07108 vm_imap_delete(NULL, vms->curmsg, vmu); 07109 vms->newmessages--; /* Fix new message count */ 07110 } 07111 #endif 07112 07113 return 0; 07114 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4245 of file app_voicemail_imapstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
04246 { 04247 if (bio->linelength >= BASELINELEN) { 04248 if (fputs(ENDL, so) == EOF) { 04249 return -1; 04250 } 04251 04252 bio->linelength = 0; 04253 } 04254 04255 if (putc(((unsigned char) c), so) == EOF) { 04256 return -1; 04257 } 04258 04259 bio->linelength++; 04260 04261 return 1; 04262 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7885 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.
07886 { 07887 int count_msg, last_msg; 07888 07889 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07890 07891 /* Rename the member vmbox HERE so that we don't try to return before 07892 * we know what's going on. 07893 */ 07894 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07895 07896 /* Faster to make the directory than to check if it exists. */ 07897 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07898 07899 /* traverses directory using readdir (or select query for ODBC) */ 07900 count_msg = count_messages(vmu, vms->curdir); 07901 if (count_msg < 0) { 07902 return count_msg; 07903 } else { 07904 vms->lastmsg = count_msg - 1; 07905 } 07906 07907 if (vm_allocate_dh(vms, vmu, count_msg)) { 07908 return -1; 07909 } 07910 07911 /* 07912 The following test is needed in case sequencing gets messed up. 07913 There appears to be more than one way to mess up sequence, so 07914 we will not try to find all of the root causes--just fix it when 07915 detected. 07916 */ 07917 07918 if (vm_lock_path(vms->curdir)) { 07919 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07920 return ERROR_LOCK_PATH; 07921 } 07922 07923 /* for local storage, checks directory for messages up to maxmsg limit */ 07924 last_msg = last_message_index(vmu, vms->curdir); 07925 ast_unlock_path(vms->curdir); 07926 07927 if (last_msg < -1) { 07928 return last_msg; 07929 } else if (vms->lastmsg != last_msg) { 07930 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); 07931 resequence_mailbox(vmu, vms->curdir, count_msg); 07932 } 07933 07934 return 0; 07935 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7663 of file app_voicemail_imapstorage.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, 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, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
07664 { 07665 int res = 0; 07666 char filename[256], *cid; 07667 const char *origtime, *context, *category, *duration, *flag; 07668 struct ast_config *msg_cfg; 07669 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07670 07671 vms->starting = 0; 07672 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07673 adsi_message(chan, vms); 07674 if (!vms->curmsg) { 07675 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07676 } else if (vms->curmsg == vms->lastmsg) { 07677 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07678 } 07679 07680 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07681 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07682 msg_cfg = ast_config_load(filename, config_flags); 07683 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07684 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07685 return 0; 07686 } 07687 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07688 07689 /* Play the word urgent if we are listening to urgent messages */ 07690 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07691 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07692 } 07693 07694 if (!res) { 07695 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07696 /* POLISH syntax */ 07697 if (!strncasecmp(chan->language, "pl", 2)) { 07698 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07699 int ten, one; 07700 char nextmsg[256]; 07701 ten = (vms->curmsg + 1) / 10; 07702 one = (vms->curmsg + 1) % 10; 07703 07704 if (vms->curmsg < 20) { 07705 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07706 res = wait_file2(chan, vms, nextmsg); 07707 } else { 07708 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07709 res = wait_file2(chan, vms, nextmsg); 07710 if (one > 0) { 07711 if (!res) { 07712 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07713 res = wait_file2(chan, vms, nextmsg); 07714 } 07715 } 07716 } 07717 } 07718 if (!res) 07719 res = wait_file2(chan, vms, "vm-message"); 07720 /* HEBREW syntax */ 07721 } else if (!strncasecmp(chan->language, "he", 2)) { 07722 if (!vms->curmsg) { 07723 res = wait_file2(chan, vms, "vm-message"); 07724 res = wait_file2(chan, vms, "vm-first"); 07725 } else if (vms->curmsg == vms->lastmsg) { 07726 res = wait_file2(chan, vms, "vm-message"); 07727 res = wait_file2(chan, vms, "vm-last"); 07728 } else { 07729 res = wait_file2(chan, vms, "vm-message"); 07730 res = wait_file2(chan, vms, "vm-number"); 07731 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07732 } 07733 /* VIETNAMESE syntax */ 07734 } else if (!strncasecmp(chan->language, "vi", 2)) { 07735 if (!vms->curmsg) { 07736 res = wait_file2(chan, vms, "vm-message"); 07737 res = wait_file2(chan, vms, "vm-first"); 07738 } else if (vms->curmsg == vms->lastmsg) { 07739 res = wait_file2(chan, vms, "vm-message"); 07740 res = wait_file2(chan, vms, "vm-last"); 07741 } else { 07742 res = wait_file2(chan, vms, "vm-message"); 07743 res = wait_file2(chan, vms, "vm-number"); 07744 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07745 } 07746 } else { 07747 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07748 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07749 } else { /* DEFAULT syntax */ 07750 res = wait_file2(chan, vms, "vm-message"); 07751 } 07752 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07753 if (!res) { 07754 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07755 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07756 } 07757 } 07758 } 07759 } 07760 07761 if (!msg_cfg) { 07762 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07763 return 0; 07764 } 07765 07766 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07767 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07768 DISPOSE(vms->curdir, vms->curmsg); 07769 ast_config_destroy(msg_cfg); 07770 return 0; 07771 } 07772 07773 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07774 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07775 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07776 07777 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07778 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07779 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07780 if (!res) { 07781 res = play_message_category(chan, category); 07782 } 07783 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07784 res = play_message_datetime(chan, vmu, origtime, filename); 07785 } 07786 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07787 res = play_message_callerid(chan, vms, cid, context, 0); 07788 } 07789 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07790 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07791 } 07792 /* Allow pressing '1' to skip envelope / callerid */ 07793 if (res == '1') { 07794 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07795 res = 0; 07796 } 07797 ast_config_destroy(msg_cfg); 07798 07799 if (!res) { 07800 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07801 vms->heard[vms->curmsg] = 1; 07802 #ifdef IMAP_STORAGE 07803 /*IMAP storage stores any prepended message from a forward 07804 * as a separate file from the rest of the message 07805 */ 07806 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07807 wait_file(chan, vms, vms->introfn); 07808 } 07809 #endif 07810 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07811 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07812 res = 0; 07813 } 07814 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07815 } 07816 DISPOSE(vms->curdir, vms->curmsg); 07817 return res; 07818 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7549 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, cidinternalcontexts, ast_channel::language, MAX_NUM_CID_CONTEXTS, name, VM_SPOOL_DIR, and wait_file2().
07550 { 07551 int res = 0; 07552 int i; 07553 char *callerid, *name; 07554 char prefile[PATH_MAX] = ""; 07555 07556 07557 /* If voicemail cid is not enabled, or we didn't get cid or context from 07558 * the attribute file, leave now. 07559 * 07560 * TODO Still need to change this so that if this function is called by the 07561 * message envelope (and someone is explicitly requesting to hear the CID), 07562 * it does not check to see if CID is enabled in the config file. 07563 */ 07564 if ((cid == NULL)||(context == NULL)) 07565 return res; 07566 07567 /* Strip off caller ID number from name */ 07568 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07569 ast_callerid_parse(cid, &name, &callerid); 07570 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07571 /* Check for internal contexts and only */ 07572 /* say extension when the call didn't come from an internal context in the list */ 07573 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07574 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07575 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07576 break; 07577 } 07578 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07579 if (!res) { 07580 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07581 if (!ast_strlen_zero(prefile)) { 07582 /* See if we can find a recorded name for this person instead of their extension number */ 07583 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07584 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07585 if (!callback) 07586 res = wait_file2(chan, vms, "vm-from"); 07587 res = ast_stream_and_wait(chan, prefile, ""); 07588 } else { 07589 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07590 /* Say "from extension" as one saying to sound smoother */ 07591 if (!callback) 07592 res = wait_file2(chan, vms, "vm-from-extension"); 07593 res = ast_say_digit_str(chan, callerid, "", chan->language); 07594 } 07595 } 07596 } 07597 } else if (!res) { 07598 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07599 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07600 if (!callback) 07601 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07602 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07603 } 07604 } else { 07605 /* Number unknown */ 07606 ast_debug(1, "VM-CID: From an unknown number\n"); 07607 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07608 res = wait_file2(chan, vms, "vm-unknown-caller"); 07609 } 07610 return res; 07611 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7460 of file app_voicemail_imapstorage.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
07461 { 07462 int res = 0; 07463 07464 if (!ast_strlen_zero(category)) 07465 res = ast_play_and_wait(chan, category); 07466 07467 if (res) { 07468 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07469 res = 0; 07470 } 07471 07472 return res; 07473 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7475 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_say_date_with_format, ast_strlen_zero(), ast_tvnow(), ast_channel::language, vm_zone::list, vm_zone::msg_format, vm_zone::name, pbx_builtin_setvar_helper(), vm_zone::timezone, and ast_vm_user::zonetag.
07476 { 07477 int res = 0; 07478 struct vm_zone *the_zone = NULL; 07479 time_t t; 07480 07481 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07482 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07483 return 0; 07484 } 07485 07486 /* Does this user have a timezone specified? */ 07487 if (!ast_strlen_zero(vmu->zonetag)) { 07488 /* Find the zone in the list */ 07489 struct vm_zone *z; 07490 AST_LIST_LOCK(&zones); 07491 AST_LIST_TRAVERSE(&zones, z, list) { 07492 if (!strcmp(z->name, vmu->zonetag)) { 07493 the_zone = z; 07494 break; 07495 } 07496 } 07497 AST_LIST_UNLOCK(&zones); 07498 } 07499 07500 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07501 #if 0 07502 /* Set the DIFF_* variables */ 07503 ast_localtime(&t, &time_now, NULL); 07504 tv_now = ast_tvnow(); 07505 ast_localtime(&tv_now, &time_then, NULL); 07506 07507 /* Day difference */ 07508 if (time_now.tm_year == time_then.tm_year) 07509 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07510 else 07511 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07512 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07513 07514 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07515 #endif 07516 if (the_zone) { 07517 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07518 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07519 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07520 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07521 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07522 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07523 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); 07524 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07525 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07526 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07527 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07528 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07529 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07530 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07531 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); 07532 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07533 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07534 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07535 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07536 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07537 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); 07538 } else { 07539 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07540 } 07541 #if 0 07542 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07543 #endif 07544 return res; 07545 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7613 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().
07614 { 07615 int res = 0; 07616 int durationm; 07617 int durations; 07618 /* Verify that we have a duration for the message */ 07619 if (duration == NULL) 07620 return res; 07621 07622 /* Convert from seconds to minutes */ 07623 durations = atoi(duration); 07624 durationm = (durations / 60); 07625 07626 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07627 07628 if ((!res) && (durationm >= minduration)) { 07629 res = wait_file2(chan, vms, "vm-duration"); 07630 07631 /* POLISH syntax */ 07632 if (!strncasecmp(chan->language, "pl", 2)) { 07633 div_t num = div(durationm, 10); 07634 07635 if (durationm == 1) { 07636 res = ast_play_and_wait(chan, "digits/1z"); 07637 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07638 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07639 if (num.rem == 2) { 07640 if (!num.quot) { 07641 res = ast_play_and_wait(chan, "digits/2-ie"); 07642 } else { 07643 res = say_and_wait(chan, durationm - 2 , chan->language); 07644 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07645 } 07646 } else { 07647 res = say_and_wait(chan, durationm, chan->language); 07648 } 07649 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07650 } else { 07651 res = say_and_wait(chan, durationm, chan->language); 07652 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07653 } 07654 /* DEFAULT syntax */ 07655 } else { 07656 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07657 res = wait_file2(chan, vms, "vm-minutes"); 07658 } 07659 } 07660 return res; 07661 }
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 13383 of file app_voicemail_imapstorage.c.
References acceptdtmf, ast_channel_setoption(), ast_copy_string(), AST_DIGIT_ANY, ast_filedelete(), ast_filerename(), ast_log(), 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, maxsilence, silencethreshold, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
13386 { 13387 /* Record message & let caller review or re-record it, or set options if applicable */ 13388 int res = 0; 13389 int cmd = 0; 13390 int max_attempts = 3; 13391 int attempts = 0; 13392 int recorded = 0; 13393 int msg_exists = 0; 13394 signed char zero_gain = 0; 13395 char tempfile[PATH_MAX]; 13396 char *acceptdtmf = "#"; 13397 char *canceldtmf = ""; 13398 int canceleddtmf = 0; 13399 13400 /* Note that urgent and private are for flagging messages as such in the future */ 13401 13402 /* barf if no pointer passed to store duration in */ 13403 if (duration == NULL) { 13404 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13405 return -1; 13406 } 13407 13408 if (!outsidecaller) 13409 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13410 else 13411 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13412 13413 cmd = '3'; /* Want to start by recording */ 13414 13415 while ((cmd >= 0) && (cmd != 't')) { 13416 switch (cmd) { 13417 case '1': 13418 if (!msg_exists) { 13419 /* In this case, 1 is to record a message */ 13420 cmd = '3'; 13421 break; 13422 } else { 13423 /* Otherwise 1 is to save the existing message */ 13424 ast_verb(3, "Saving message as is\n"); 13425 if (!outsidecaller) 13426 ast_filerename(tempfile, recordfile, NULL); 13427 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13428 if (!outsidecaller) { 13429 /* Saves to IMAP server only if imapgreeting=yes */ 13430 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13431 DISPOSE(recordfile, -1); 13432 } 13433 cmd = 't'; 13434 return res; 13435 } 13436 case '2': 13437 /* Review */ 13438 ast_verb(3, "Reviewing the message\n"); 13439 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13440 break; 13441 case '3': 13442 msg_exists = 0; 13443 /* Record */ 13444 if (recorded == 1) 13445 ast_verb(3, "Re-recording the message\n"); 13446 else 13447 ast_verb(3, "Recording the message\n"); 13448 13449 if (recorded && outsidecaller) { 13450 cmd = ast_play_and_wait(chan, INTRO); 13451 cmd = ast_play_and_wait(chan, "beep"); 13452 } 13453 recorded = 1; 13454 /* 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 */ 13455 if (record_gain) 13456 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13457 if (ast_test_flag(vmu, VM_OPERATOR)) 13458 canceldtmf = "0"; 13459 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13460 if (strchr(canceldtmf, cmd)) { 13461 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13462 canceleddtmf = 1; 13463 } 13464 if (record_gain) 13465 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13466 if (cmd == -1) { 13467 /* User has hung up, no options to give */ 13468 if (!outsidecaller) { 13469 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13470 ast_filedelete(tempfile, NULL); 13471 } 13472 return cmd; 13473 } 13474 if (cmd == '0') { 13475 break; 13476 } else if (cmd == '*') { 13477 break; 13478 #if 0 13479 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13480 /* Message is too short */ 13481 ast_verb(3, "Message too short\n"); 13482 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13483 cmd = ast_filedelete(tempfile, NULL); 13484 break; 13485 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13486 /* Message is all silence */ 13487 ast_verb(3, "Nothing recorded\n"); 13488 cmd = ast_filedelete(tempfile, NULL); 13489 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13490 if (!cmd) 13491 cmd = ast_play_and_wait(chan, "vm-speakup"); 13492 break; 13493 #endif 13494 } else { 13495 /* If all is well, a message exists */ 13496 msg_exists = 1; 13497 cmd = 0; 13498 } 13499 break; 13500 case '4': 13501 if (outsidecaller) { /* only mark vm messages */ 13502 /* Mark Urgent */ 13503 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13504 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13505 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13506 strcpy(flag, "Urgent"); 13507 } else if (flag) { 13508 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13509 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13510 strcpy(flag, ""); 13511 } else { 13512 ast_play_and_wait(chan, "vm-sorry"); 13513 } 13514 cmd = 0; 13515 } else { 13516 cmd = ast_play_and_wait(chan, "vm-sorry"); 13517 } 13518 break; 13519 case '5': 13520 case '6': 13521 case '7': 13522 case '8': 13523 case '9': 13524 case '*': 13525 case '#': 13526 cmd = ast_play_and_wait(chan, "vm-sorry"); 13527 break; 13528 #if 0 13529 /* XXX Commented out for the moment because of the dangers of deleting 13530 a message while recording (can put the message numbers out of sync) */ 13531 case '*': 13532 /* Cancel recording, delete message, offer to take another message*/ 13533 cmd = ast_play_and_wait(chan, "vm-deleted"); 13534 cmd = ast_filedelete(tempfile, NULL); 13535 if (outsidecaller) { 13536 res = vm_exec(chan, NULL); 13537 return res; 13538 } 13539 else 13540 return 1; 13541 #endif 13542 case '0': 13543 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13544 cmd = ast_play_and_wait(chan, "vm-sorry"); 13545 break; 13546 } 13547 if (msg_exists || recorded) { 13548 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13549 if (!cmd) 13550 cmd = ast_waitfordigit(chan, 3000); 13551 if (cmd == '1') { 13552 ast_filerename(tempfile, recordfile, NULL); 13553 ast_play_and_wait(chan, "vm-msgsaved"); 13554 cmd = '0'; 13555 } else if (cmd == '4') { 13556 if (flag) { 13557 ast_play_and_wait(chan, "vm-marked-urgent"); 13558 strcpy(flag, "Urgent"); 13559 } 13560 ast_play_and_wait(chan, "vm-msgsaved"); 13561 cmd = '0'; 13562 } else { 13563 ast_play_and_wait(chan, "vm-deleted"); 13564 DELETE(tempfile, -1, tempfile, vmu); 13565 cmd = '0'; 13566 } 13567 } 13568 return cmd; 13569 default: 13570 /* If the caller is an ouside caller, and the review option is enabled, 13571 allow them to review the message, but let the owner of the box review 13572 their OGM's */ 13573 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13574 return cmd; 13575 if (msg_exists) { 13576 cmd = ast_play_and_wait(chan, "vm-review"); 13577 if (!cmd && outsidecaller) { 13578 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13579 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13580 } else if (flag) { 13581 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13582 } 13583 } 13584 } else { 13585 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13586 if (!cmd) 13587 cmd = ast_waitfordigit(chan, 600); 13588 } 13589 13590 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13591 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13592 if (!cmd) 13593 cmd = ast_waitfordigit(chan, 600); 13594 } 13595 #if 0 13596 if (!cmd) 13597 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13598 #endif 13599 if (!cmd) 13600 cmd = ast_waitfordigit(chan, 6000); 13601 if (!cmd) { 13602 attempts++; 13603 } 13604 if (attempts > max_attempts) { 13605 cmd = 't'; 13606 } 13607 } 13608 } 13609 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13610 /* Hang up or timeout, so delete the recording. */ 13611 ast_filedelete(tempfile, NULL); 13612 } 13613 13614 if (cmd != 't' && outsidecaller) 13615 ast_play_and_wait(chan, "vm-goodbye"); 13616 13617 return cmd; 13618 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11416 of file app_voicemail_imapstorage.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
11417 { 11418 int new = 0, old = 0, urgent = 0; 11419 11420 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11421 11422 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11423 mwi_sub->old_urgent = urgent; 11424 mwi_sub->old_new = new; 11425 mwi_sub->old_old = old; 11426 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11427 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11428 } 11429 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11431 of file app_voicemail_imapstorage.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), mwi_sub::entry, mwi_sub, and poll_subscribed_mailbox().
11432 { 11433 struct mwi_sub *mwi_sub; 11434 11435 AST_RWLIST_RDLOCK(&mwi_subs); 11436 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11437 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11438 poll_subscribed_mailbox(mwi_sub); 11439 } 11440 } 11441 AST_RWLIST_UNLOCK(&mwi_subs); 11442 }
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.
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, callcontext, dialcontext, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, exitcontext, globalflags, ast_vm_user::locale, ast_vm_user::maxdeletedmsg, ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, saydurationminfo, ast_vm_user::volgain, and ast_vm_user::zonetag.
01023 { 01024 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01025 vmu->passwordlocation = passwordlocation; 01026 if (saydurationminfo) { 01027 vmu->saydurationm = saydurationminfo; 01028 } 01029 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 01030 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 01031 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 01032 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 01033 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 01034 if (vmminsecs) { 01035 vmu->minsecs = vmminsecs; 01036 } 01037 if (vmmaxsecs) { 01038 vmu->maxsecs = vmmaxsecs; 01039 } 01040 if (maxmsg) { 01041 vmu->maxmsg = maxmsg; 01042 } 01043 if (maxdeletedmsg) { 01044 vmu->maxdeletedmsg = maxdeletedmsg; 01045 } 01046 vmu->volgain = volgain; 01047 ast_free(vmu->emailsubject); 01048 vmu->emailsubject = NULL; 01049 ast_free(vmu->emailbody); 01050 vmu->emailbody = NULL; 01051 #ifdef IMAP_STORAGE 01052 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 01053 #endif 01054 }
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 4333 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, config_flags, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
04334 { 04335 char callerid[256]; 04336 char num[12]; 04337 char fromdir[256], fromfile[256]; 04338 struct ast_config *msg_cfg; 04339 const char *origcallerid, *origtime; 04340 char origcidname[80], origcidnum[80], origdate[80]; 04341 int inttime; 04342 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04343 04344 /* Prepare variables for substitution in email body and subject */ 04345 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04346 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04347 snprintf(num, sizeof(num), "%d", msgnum); 04348 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04349 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04350 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04351 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04352 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04353 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04354 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04355 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04356 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04357 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04358 04359 /* Retrieve info from VM attribute file */ 04360 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04361 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04362 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04363 strcat(fromfile, ".txt"); 04364 } 04365 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04366 if (option_debug > 0) { 04367 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04368 } 04369 return; 04370 } 04371 04372 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04373 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04374 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04375 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04376 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04377 } 04378 04379 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04380 struct timeval tv = { inttime, }; 04381 struct ast_tm tm; 04382 ast_localtime(&tv, &tm, NULL); 04383 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04384 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04385 } 04386 ast_config_destroy(msg_cfg); 04387 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7003 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(), and strsep().
07004 { 07005 struct ast_event *event; 07006 char *mailbox, *context; 07007 07008 /* Strip off @default */ 07009 context = mailbox = ast_strdupa(box); 07010 strsep(&context, "@"); 07011 if (ast_strlen_zero(context)) 07012 context = "default"; 07013 07014 if (!(event = ast_event_new(AST_EVENT_MWI, 07015 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07016 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07017 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07018 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07019 AST_EVENT_IE_END))) { 07020 return; 07021 } 07022 07023 ast_event_queue_and_cache(event); 07024 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12509 of file app_voicemail_imapstorage.c.
References ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), config_flags, and LOG_NOTICE.
12509 { 12510 struct ast_config *pwconf; 12511 struct ast_flags config_flags = { 0 }; 12512 12513 pwconf = ast_config_load(secretfn, config_flags); 12514 if (pwconf) { 12515 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12516 if (val) { 12517 ast_copy_string(password, val, passwordlen); 12518 return; 12519 } 12520 } 12521 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12522 }
static int reload | ( | void | ) | [static] |
Definition at line 13030 of file app_voicemail_imapstorage.c.
References load_config().
13031 { 13032 return load_config(1); 13033 }
static void rename_file | ( | char * | sfn, | |
char * | dfn | |||
) | [static] |
Renames a message in a mailbox folder.
sfn | The path to the mailbox information and data file to be renamed. | |
dfn | The path for where the message data and information files will be renamed to. |
Definition at line 4002 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04003 { 04004 char stxt[PATH_MAX]; 04005 char dtxt[PATH_MAX]; 04006 ast_filerename(sfn, dfn, NULL); 04007 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04008 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04009 if (ast_check_realtime("voicemail_data")) { 04010 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04011 } 04012 rename(stxt, dtxt); 04013 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6145 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().
06146 { 06147 /* we know the actual number of messages, so stop process when number is hit */ 06148 06149 int x, dest; 06150 char sfn[PATH_MAX]; 06151 char dfn[PATH_MAX]; 06152 06153 if (vm_lock_path(dir)) { 06154 return ERROR_LOCK_PATH; 06155 } 06156 06157 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06158 make_file(sfn, sizeof(sfn), dir, x); 06159 if (EXISTS(dir, x, sfn, NULL)) { 06160 06161 if (x != dest) { 06162 make_file(dfn, sizeof(dfn), dir, dest); 06163 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06164 } 06165 06166 dest++; 06167 } 06168 } 06169 ast_unlock_path(dir); 06170 06171 return dest; 06172 }
static int reset_user_pw | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | newpass | |||
) | [static] |
Resets a user password to a specified password.
context | ||
mailbox | ||
newpass | This does the actual change password work, called by the vm_change_password() function. |
Definition at line 1488 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::list, ast_vm_user::mailbox, and ast_vm_user::password.
01489 { 01490 /* This function could be made to generate one from a database, too */ 01491 struct ast_vm_user *cur; 01492 int res = -1; 01493 AST_LIST_LOCK(&users); 01494 AST_LIST_TRAVERSE(&users, cur, list) { 01495 if ((!context || !strcasecmp(context, cur->context)) && 01496 (!strcasecmp(mailbox, cur->mailbox))) 01497 break; 01498 } 01499 if (cur) { 01500 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01501 res = 0; 01502 } 01503 AST_LIST_UNLOCK(&users); 01504 return res; 01505 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5518 of file app_voicemail_imapstorage.c.
References ast_app_has_voicemail(), ast_copy_string(), ast_debug, ast_log(), AST_LOG_ERROR, 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, externnotify, ast_smdi_mwi_message::fwd_st, inboxcount2(), smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
05519 { 05520 char arguments[255]; 05521 char ext_context[256] = ""; 05522 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05523 struct ast_smdi_mwi_message *mwi_msg; 05524 05525 if (!ast_strlen_zero(context)) 05526 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05527 else 05528 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05529 05530 if (smdi_iface) { 05531 if (ast_app_has_voicemail(ext_context, NULL)) 05532 ast_smdi_mwi_set(smdi_iface, extension); 05533 else 05534 ast_smdi_mwi_unset(smdi_iface, extension); 05535 05536 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05537 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05538 if (!strncmp(mwi_msg->cause, "INV", 3)) 05539 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05540 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05541 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05542 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05543 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05544 } else { 05545 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05546 } 05547 } 05548 05549 if (!ast_strlen_zero(externnotify)) { 05550 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05551 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05552 } else { 05553 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05554 ast_debug(1, "Executing %s\n", arguments); 05555 ast_safe_system(arguments); 05556 } 05557 } 05558 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6182 of file app_voicemail_imapstorage.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, ast_mutex_lock, ast_mutex_unlock, ast_unlock_path(), COPY, create_dirpath(), vm_state::curbox, vm_state::curdir, ERROR_LOCK_PATH, EXISTS, last_message_index(), make_file(), mbox(), NEW_FOLDER, OLD_FOLDER, RENAME, vm_state::username, and vm_lock_path().
06183 { 06184 #ifdef IMAP_STORAGE 06185 /* we must use mbox(x) folder names, and copy the message there */ 06186 /* simple. huh? */ 06187 char sequence[10]; 06188 char mailbox[256]; 06189 int res; 06190 06191 /* get the real IMAP message number for this message */ 06192 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06193 06194 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06195 ast_mutex_lock(&vms->lock); 06196 /* if save to Old folder, put in INBOX as read */ 06197 if (box == OLD_FOLDER) { 06198 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06199 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06200 } else if (box == NEW_FOLDER) { 06201 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06202 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06203 } 06204 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06205 ast_mutex_unlock(&vms->lock); 06206 return 0; 06207 } 06208 /* Create the folder if it don't exist */ 06209 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06210 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06211 if (mail_create(vms->mailstream, mailbox) == NIL) 06212 ast_debug(5, "Folder exists.\n"); 06213 else 06214 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06215 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06216 ast_mutex_unlock(&vms->lock); 06217 return res; 06218 #else 06219 char *dir = vms->curdir; 06220 char *username = vms->username; 06221 char *context = vmu->context; 06222 char sfn[PATH_MAX]; 06223 char dfn[PATH_MAX]; 06224 char ddir[PATH_MAX]; 06225 const char *dbox = mbox(vmu, box); 06226 int x, i; 06227 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06228 06229 if (vm_lock_path(ddir)) 06230 return ERROR_LOCK_PATH; 06231 06232 x = last_message_index(vmu, ddir) + 1; 06233 06234 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06235 x--; 06236 for (i = 1; i <= x; i++) { 06237 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06238 make_file(sfn, sizeof(sfn), ddir, i); 06239 make_file(dfn, sizeof(dfn), ddir, i - 1); 06240 if (EXISTS(ddir, i, sfn, NULL)) { 06241 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06242 } else 06243 break; 06244 } 06245 } else { 06246 if (x >= vmu->maxmsg) { 06247 ast_unlock_path(ddir); 06248 return -1; 06249 } 06250 } 06251 make_file(sfn, sizeof(sfn), dir, msg); 06252 make_file(dfn, sizeof(dfn), ddir, x); 06253 if (strcmp(sfn, dfn)) { 06254 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06255 } 06256 ast_unlock_path(ddir); 06257 #endif 06258 return 0; 06259 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6175 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, and ast_say_number().
06176 { 06177 int d; 06178 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06179 return d; 06180 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12495 of file app_voicemail_imapstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
12496 { 12497 int res = -1; 12498 char dir[PATH_MAX]; 12499 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12500 ast_debug(2, "About to try retrieving name file %s\n", dir); 12501 RETRIEVE(dir, -1, mailbox, context); 12502 if (ast_fileexists(dir, NULL, NULL)) { 12503 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12504 } 12505 DISPOSE(dir, -1); 12506 return res; 12507 }
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 4848 of file app_voicemail_imapstorage.c.
References ast_debug, ast_log(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_vm_user::email, globalflags, ast_vm_user::mailbox, mailcmd, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().
04849 { 04850 FILE *p = NULL; 04851 char tmp[80] = "/tmp/astmail-XXXXXX"; 04852 char tmp2[256]; 04853 char *stringp; 04854 04855 if (vmu && ast_strlen_zero(vmu->email)) { 04856 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04857 return(0); 04858 } 04859 04860 /* Mail only the first format */ 04861 format = ast_strdupa(format); 04862 stringp = format; 04863 strsep(&stringp, "|"); 04864 04865 if (!strcmp(format, "wav49")) 04866 format = "WAV"; 04867 ast_debug(3, "Attaching file '%s', format '%s', uservm is '%d', global is %d\n", attach, format, attach_user_voicemail, ast_test_flag((&globalflags), VM_ATTACH)); 04868 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04869 command hangs */ 04870 if ((p = vm_mkftemp(tmp)) == NULL) { 04871 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04872 return -1; 04873 } else { 04874 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04875 fclose(p); 04876 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04877 ast_safe_system(tmp2); 04878 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04879 } 04880 return 0; 04881 }
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 4883 of file app_voicemail_imapstorage.c.
References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_log(), 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_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, mailcmd, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
04884 { 04885 char enc_cidnum[256], enc_cidname[256]; 04886 char date[256]; 04887 char host[MAXHOSTNAMELEN] = ""; 04888 char who[256]; 04889 char dur[PATH_MAX]; 04890 char tmp[80] = "/tmp/astmail-XXXXXX"; 04891 char tmp2[PATH_MAX]; 04892 struct ast_tm tm; 04893 FILE *p; 04894 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04895 04896 if (!str1 || !str2) { 04897 ast_free(str1); 04898 ast_free(str2); 04899 return -1; 04900 } 04901 04902 if (cidnum) { 04903 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04904 } 04905 if (cidname) { 04906 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04907 } 04908 04909 if ((p = vm_mkftemp(tmp)) == NULL) { 04910 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04911 ast_free(str1); 04912 ast_free(str2); 04913 return -1; 04914 } 04915 gethostname(host, sizeof(host)-1); 04916 if (strchr(srcemail, '@')) { 04917 ast_copy_string(who, srcemail, sizeof(who)); 04918 } else { 04919 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04920 } 04921 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04922 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04923 fprintf(p, "Date: %s\n", date); 04924 04925 /* Reformat for custom pager format */ 04926 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04927 04928 if (!ast_strlen_zero(pagerfromstring)) { 04929 struct ast_channel *ast; 04930 if ((ast = ast_dummy_channel_alloc())) { 04931 char *ptr; 04932 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04933 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04934 04935 if (check_mime(ast_str_buffer(str1))) { 04936 int first_line = 1; 04937 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04938 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04939 *ptr = '\0'; 04940 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04941 first_line = 0; 04942 /* Substring is smaller, so this will never grow */ 04943 ast_str_set(&str2, 0, "%s", ptr + 1); 04944 } 04945 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04946 } else { 04947 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04948 } 04949 ast = ast_channel_unref(ast); 04950 } else { 04951 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04952 } 04953 } else { 04954 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04955 } 04956 04957 if (check_mime(vmu->fullname)) { 04958 int first_line = 1; 04959 char *ptr; 04960 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04961 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04962 *ptr = '\0'; 04963 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04964 first_line = 0; 04965 /* Substring is smaller, so this will never grow */ 04966 ast_str_set(&str2, 0, "%s", ptr + 1); 04967 } 04968 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04969 } else { 04970 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04971 } 04972 04973 if (!ast_strlen_zero(pagersubject)) { 04974 struct ast_channel *ast; 04975 if ((ast = ast_dummy_channel_alloc())) { 04976 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04977 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04978 if (check_mime(ast_str_buffer(str1))) { 04979 int first_line = 1; 04980 char *ptr; 04981 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04982 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04983 *ptr = '\0'; 04984 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04985 first_line = 0; 04986 /* Substring is smaller, so this will never grow */ 04987 ast_str_set(&str2, 0, "%s", ptr + 1); 04988 } 04989 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04990 } else { 04991 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04992 } 04993 ast = ast_channel_unref(ast); 04994 } else { 04995 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04996 } 04997 } else { 04998 if (ast_strlen_zero(flag)) { 04999 fprintf(p, "Subject: New VM\n\n"); 05000 } else { 05001 fprintf(p, "Subject: New %s VM\n\n", flag); 05002 } 05003 } 05004 05005 if (pagerbody) { 05006 struct ast_channel *ast; 05007 if ((ast = ast_dummy_channel_alloc())) { 05008 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05009 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05010 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05011 ast = ast_channel_unref(ast); 05012 } else { 05013 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05014 } 05015 } else { 05016 fprintf(p, "New %s long %s msg in box %s\n" 05017 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05018 } 05019 05020 fclose(p); 05021 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05022 ast_safe_system(tmp2); 05023 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05024 ast_free(str1); 05025 ast_free(str2); 05026 return 0; 05027 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11073 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, SENTINEL, and var.
11074 { 11075 struct ast_config *cfg; 11076 const char *cat = NULL; 11077 11078 if (!(cfg = ast_load_realtime_multientry("voicemail", 11079 "context", context, SENTINEL))) { 11080 return CLI_FAILURE; 11081 } 11082 11083 ast_cli(fd, 11084 "\n" 11085 "=============================================================\n" 11086 "=== Configured Voicemail Users ==============================\n" 11087 "=============================================================\n" 11088 "===\n"); 11089 11090 while ((cat = ast_category_browse(cfg, cat))) { 11091 struct ast_variable *var = NULL; 11092 ast_cli(fd, 11093 "=== Mailbox ...\n" 11094 "===\n"); 11095 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11096 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11097 ast_cli(fd, 11098 "===\n" 11099 "=== ---------------------------------------------------------\n" 11100 "===\n"); 11101 } 11102 11103 ast_cli(fd, 11104 "=============================================================\n" 11105 "\n"); 11106 11107 ast_config_destroy(cfg); 11108 11109 return CLI_SUCCESS; 11110 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11568 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_pthread_create, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), mwi_unsub_sub, poll_thread, and poll_thread_run.
11569 { 11570 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11571 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11572 AST_EVENT_IE_END); 11573 11574 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11575 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11576 AST_EVENT_IE_END); 11577 11578 if (mwi_sub_sub) 11579 ast_event_report_subs(mwi_sub_sub); 11580 11581 poll_thread_run = 1; 11582 11583 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11584 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11586 of file app_voicemail_imapstorage.c.
References ast_cond_signal, ast_event_unsubscribe(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, mwi_sub_sub, mwi_unsub_sub, poll_cond, poll_lock, poll_thread, and poll_thread_run.
11587 { 11588 poll_thread_run = 0; 11589 11590 if (mwi_sub_sub) { 11591 ast_event_unsubscribe(mwi_sub_sub); 11592 mwi_sub_sub = NULL; 11593 } 11594 11595 if (mwi_unsub_sub) { 11596 ast_event_unsubscribe(mwi_unsub_sub); 11597 mwi_unsub_sub = NULL; 11598 } 11599 11600 ast_mutex_lock(&poll_lock); 11601 ast_cond_signal(&poll_cond); 11602 ast_mutex_unlock(&poll_lock); 11603 11604 pthread_join(poll_thread, NULL); 11605 11606 poll_thread = AST_PTHREADT_NULL; 11607 }
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.
Definition at line 992 of file app_voicemail_imapstorage.c.
00993 { 00994 char *bufptr = buf; 00995 for (; *input; input++) { 00996 if (*input < 32) { 00997 continue; 00998 } 00999 *bufptr++ = *input; 01000 if (bufptr == buf + buflen - 1) { 01001 break; 01002 } 01003 } 01004 *bufptr = '\0'; 01005 return buf; 01006 }
static const char * substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11732 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), and str.
11733 { 11734 char *current; 11735 11736 /* Add 16 for fudge factor */ 11737 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11738 11739 ast_str_reset(str); 11740 11741 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11742 for (current = (char *) value; *current; current++) { 11743 if (*current == '\\') { 11744 current++; 11745 if (!*current) { 11746 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11747 break; 11748 } 11749 switch (*current) { 11750 case '\\': 11751 ast_str_append(&str, 0, "\\"); 11752 break; 11753 case 'r': 11754 ast_str_append(&str, 0, "\r"); 11755 break; 11756 case 'n': 11757 #ifdef IMAP_STORAGE 11758 if (!str->used || str->str[str->used - 1] != '\r') { 11759 ast_str_append(&str, 0, "\r"); 11760 } 11761 #endif 11762 ast_str_append(&str, 0, "\n"); 11763 break; 11764 case 't': 11765 ast_str_append(&str, 0, "\t"); 11766 break; 11767 default: 11768 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11769 break; 11770 } 11771 } else { 11772 ast_str_append(&str, 0, "%c", *current); 11773 } 11774 } 11775 11776 return ast_str_buffer(str); 11777 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13035 of file app_voicemail_imapstorage.c.
References ao2_ref, app, app2, app3, app4, 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(), cli_voicemail, free_vm_users(), free_vm_zones(), inprocess_container, mailbox_exists_acf, mwi_subscription_tps, poll_thread, sayname_app, and stop_poll_thread().
13036 { 13037 int res; 13038 13039 res = ast_unregister_application(app); 13040 res |= ast_unregister_application(app2); 13041 res |= ast_unregister_application(app3); 13042 res |= ast_unregister_application(app4); 13043 res |= ast_unregister_application(sayname_app); 13044 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13045 res |= ast_manager_unregister("VoicemailUsersList"); 13046 res |= ast_data_unregister(NULL); 13047 #ifdef TEST_FRAMEWORK 13048 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13049 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13050 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13051 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13052 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13053 #endif 13054 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13055 ast_uninstall_vm_functions(); 13056 ao2_ref(inprocess_container, -1); 13057 13058 if (poll_thread != AST_PTHREADT_NULL) 13059 stop_poll_thread(); 13060 13061 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13062 ast_unload_realtime("voicemail"); 13063 ast_unload_realtime("voicemail_data"); 13064 13065 free_vm_users(); 13066 free_vm_zones(); 13067 return res; 13068 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1758 of file app_voicemail_imapstorage.c.
References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
01758 { 01759 01760 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01761 if (!vms->dh_arraysize) { 01762 /* initial allocation */ 01763 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01764 return -1; 01765 } 01766 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01767 return -1; 01768 } 01769 vms->dh_arraysize = arraysize; 01770 } else if (vms->dh_arraysize < arraysize) { 01771 if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) { 01772 return -1; 01773 } 01774 if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) { 01775 return -1; 01776 } 01777 memset(vms->deleted, 0, arraysize * sizeof(int)); 01778 memset(vms->heard, 0, arraysize * sizeof(int)); 01779 vms->dh_arraysize = arraysize; 01780 } 01781 01782 return 0; 01783 }
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 9735 of file app_voicemail_imapstorage.c.
References adsi_begin(), adsi_login(), adsi_password(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, ast_waitstream(), find_user(), ast_vm_user::password, S_COR, and vm_password.
09738 { 09739 int useadsi = 0, valid = 0, logretries = 0; 09740 char password[AST_MAX_EXTENSION]="", *passptr; 09741 struct ast_vm_user vmus, *vmu = NULL; 09742 09743 /* If ADSI is supported, setup login screen */ 09744 adsi_begin(chan, &useadsi); 09745 if (!skipuser && useadsi) 09746 adsi_login(chan); 09747 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09748 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09749 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09750 return -1; 09751 } 09752 09753 /* Authenticate them and get their mailbox/password */ 09754 09755 while (!valid && (logretries < max_logins)) { 09756 /* Prompt for, and read in the username */ 09757 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09758 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09759 return -1; 09760 } 09761 if (ast_strlen_zero(mailbox)) { 09762 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09763 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09764 } else { 09765 ast_verb(3, "Username not entered\n"); 09766 return -1; 09767 } 09768 } else if (mailbox[0] == '*') { 09769 /* user entered '*' */ 09770 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09771 if (ast_exists_extension(chan, chan->context, "a", 1, 09772 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09773 return -1; 09774 } 09775 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09776 mailbox[0] = '\0'; 09777 } 09778 09779 if (useadsi) 09780 adsi_password(chan); 09781 09782 if (!ast_strlen_zero(prefix)) { 09783 char fullusername[80] = ""; 09784 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09785 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09786 ast_copy_string(mailbox, fullusername, mailbox_size); 09787 } 09788 09789 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09790 vmu = find_user(&vmus, context, mailbox); 09791 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09792 /* saved password is blank, so don't bother asking */ 09793 password[0] = '\0'; 09794 } else { 09795 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09796 if (ast_streamfile(chan, vm_password, chan->language)) { 09797 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09798 return -1; 09799 } 09800 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09801 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09802 return -1; 09803 } else if (password[0] == '*') { 09804 /* user entered '*' */ 09805 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09806 if (ast_exists_extension(chan, chan->context, "a", 1, 09807 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09808 mailbox[0] = '*'; 09809 return -1; 09810 } 09811 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09812 mailbox[0] = '\0'; 09813 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09814 vmu = NULL; 09815 } 09816 } 09817 09818 if (vmu) { 09819 passptr = vmu->password; 09820 if (passptr[0] == '-') passptr++; 09821 } 09822 if (vmu && !strcmp(passptr, password)) 09823 valid++; 09824 else { 09825 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09826 if (!ast_strlen_zero(prefix)) 09827 mailbox[0] = '\0'; 09828 } 09829 logretries++; 09830 if (!valid) { 09831 if (skipuser || logretries >= max_logins) { 09832 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09833 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09834 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09835 return -1; 09836 } 09837 } else { 09838 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09839 if (useadsi) 09840 adsi_login(chan); 09841 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09842 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09843 return -1; 09844 } 09845 } 09846 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09847 return -1; 09848 } 09849 } 09850 if (!valid && (logretries >= max_logins)) { 09851 ast_stopstream(chan); 09852 ast_play_and_wait(chan, "vm-goodbye"); 09853 return -1; 09854 } 09855 if (vmu && !skipuser) { 09856 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09857 } 09858 return 0; 09859 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10968 of file app_voicemail_imapstorage.c.
References args, AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_ERROR, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), find_user(), mbox(), and pbx_builtin_setvar_helper().
10969 { 10970 struct ast_vm_user svm; 10971 char *context, *box; 10972 AST_DECLARE_APP_ARGS(args, 10973 AST_APP_ARG(mbox); 10974 AST_APP_ARG(options); 10975 ); 10976 static int dep_warning = 0; 10977 10978 if (ast_strlen_zero(data)) { 10979 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10980 return -1; 10981 } 10982 10983 if (!dep_warning) { 10984 dep_warning = 1; 10985 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10986 } 10987 10988 box = ast_strdupa(data); 10989 10990 AST_STANDARD_APP_ARGS(args, box); 10991 10992 if (args.options) { 10993 } 10994 10995 if ((context = strchr(args.mbox, '@'))) { 10996 *context = '\0'; 10997 context++; 10998 } 10999 11000 if (find_user(&svm, context, args.mbox)) { 11001 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11002 } else 11003 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11004 11005 return 0; 11006 }
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.
chan | The channel for the current user. We read the language property from this. | |
vms | passed into the language-specific vm_browse_messages function. | |
vmu | passed into the language-specific vm_browse_messages function. |
Definition at line 9714 of file app_voicemail_imapstorage.c.
References ast_channel::language, vm_browse_messages_en(), vm_browse_messages_es(), vm_browse_messages_gr(), vm_browse_messages_he(), vm_browse_messages_it(), vm_browse_messages_pt(), vm_browse_messages_vi(), and vm_browse_messages_zh().
09715 { 09716 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09717 return vm_browse_messages_es(chan, vms, vmu); 09718 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09719 return vm_browse_messages_gr(chan, vms, vmu); 09720 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09721 return vm_browse_messages_he(chan, vms, vmu); 09722 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09723 return vm_browse_messages_it(chan, vms, vmu); 09724 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09725 return vm_browse_messages_pt(chan, vms, vmu); 09726 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09727 return vm_browse_messages_vi(chan, vms, vmu); 09728 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09729 return vm_browse_messages_zh(chan, vms, vmu); 09730 } else { /* Default to English syntax */ 09731 return vm_browse_messages_en(chan, vms, vmu); 09732 } 09733 }
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.
chan | ||
vms | ||
vmu |
Definition at line 9553 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09554 { 09555 int cmd = 0; 09556 09557 if (vms->lastmsg > -1) { 09558 cmd = play_message(chan, vmu, vms); 09559 } else { 09560 cmd = ast_play_and_wait(chan, "vm-youhave"); 09561 if (!cmd) 09562 cmd = ast_play_and_wait(chan, "vm-no"); 09563 if (!cmd) { 09564 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09565 cmd = ast_play_and_wait(chan, vms->fn); 09566 } 09567 if (!cmd) 09568 cmd = ast_play_and_wait(chan, "vm-messages"); 09569 } 09570 return cmd; 09571 }
static int vm_browse_messages_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Spanish syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9607 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09608 { 09609 int cmd; 09610 09611 if (vms->lastmsg > -1) { 09612 cmd = play_message(chan, vmu, vms); 09613 } else { 09614 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09615 if (!cmd) 09616 cmd = ast_play_and_wait(chan, "vm-messages"); 09617 if (!cmd) { 09618 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09619 cmd = ast_play_and_wait(chan, vms->fn); 09620 } 09621 } 09622 return cmd; 09623 }
static int vm_browse_messages_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Greek syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9501 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.
09502 { 09503 int cmd = 0; 09504 09505 if (vms->lastmsg > -1) { 09506 cmd = play_message(chan, vmu, vms); 09507 } else { 09508 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09509 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09510 if (!cmd) { 09511 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09512 cmd = ast_play_and_wait(chan, vms->fn); 09513 } 09514 if (!cmd) 09515 cmd = ast_play_and_wait(chan, "vm-messages"); 09516 } else { 09517 if (!cmd) 09518 cmd = ast_play_and_wait(chan, "vm-messages"); 09519 if (!cmd) { 09520 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09521 cmd = ast_play_and_wait(chan, vms->fn); 09522 } 09523 } 09524 } 09525 return cmd; 09526 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9529 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
09530 { 09531 int cmd = 0; 09532 09533 if (vms->lastmsg > -1) { 09534 cmd = play_message(chan, vmu, vms); 09535 } else { 09536 if (!strcasecmp(vms->fn, "INBOX")) { 09537 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09538 } else { 09539 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09540 } 09541 } 09542 return cmd; 09543 }
static int vm_browse_messages_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Italian syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9581 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09582 { 09583 int cmd; 09584 09585 if (vms->lastmsg > -1) { 09586 cmd = play_message(chan, vmu, vms); 09587 } else { 09588 cmd = ast_play_and_wait(chan, "vm-no"); 09589 if (!cmd) 09590 cmd = ast_play_and_wait(chan, "vm-message"); 09591 if (!cmd) { 09592 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09593 cmd = ast_play_and_wait(chan, vms->fn); 09594 } 09595 } 09596 return cmd; 09597 }
static int vm_browse_messages_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Portuguese syntax for 'You have N messages' greeting.
chan | ||
vms | ||
vmu |
Definition at line 9633 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09634 { 09635 int cmd; 09636 09637 if (vms->lastmsg > -1) { 09638 cmd = play_message(chan, vmu, vms); 09639 } else { 09640 cmd = ast_play_and_wait(chan, "vm-no"); 09641 if (!cmd) { 09642 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09643 cmd = ast_play_and_wait(chan, vms->fn); 09644 } 09645 if (!cmd) 09646 cmd = ast_play_and_wait(chan, "vm-messages"); 09647 } 09648 return cmd; 09649 }
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.
chan | ||
vms | ||
vmu |
Definition at line 9687 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09688 { 09689 int cmd = 0; 09690 09691 if (vms->lastmsg > -1) { 09692 cmd = play_message(chan, vmu, vms); 09693 } else { 09694 cmd = ast_play_and_wait(chan, "vm-no"); 09695 if (!cmd) { 09696 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09697 cmd = ast_play_and_wait(chan, vms->fn); 09698 } 09699 } 09700 return cmd; 09701 }
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.
chan | ||
vms | ||
vmu |
Definition at line 9659 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09660 { 09661 int cmd; 09662 09663 if (vms->lastmsg > -1) { 09664 cmd = play_message(chan, vmu, vms); 09665 } else { 09666 cmd = ast_play_and_wait(chan, "vm-you"); 09667 if (!cmd) 09668 cmd = ast_play_and_wait(chan, "vm-haveno"); 09669 if (!cmd) 09670 cmd = ast_play_and_wait(chan, "vm-messages"); 09671 if (!cmd) { 09672 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09673 cmd = ast_play_and_wait(chan, vms->fn); 09674 } 09675 } 09676 return cmd; 09677 }
static void vm_change_password | ( | struct ast_vm_user * | vmu, | |
const char * | newpassword | |||
) | [static] |
The handler for the change password option.
vmu | The voicemail user to work with. | |
newpassword | The 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 1514 of file app_voicemail_imapstorage.c.
References ast_category_browse(), ast_category_get(), 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, config_flags, CONFIG_STATUS_FILEINVALID, 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(), value, var, VM_SPOOL_DIR, VOICEMAIL_CONFIG, and write_password_to_file().
01515 { 01516 struct ast_config *cfg = NULL; 01517 struct ast_variable *var = NULL; 01518 struct ast_category *cat = NULL; 01519 char *category = NULL, *value = NULL, *new = NULL; 01520 const char *tmp = NULL; 01521 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01522 char secretfn[PATH_MAX] = ""; 01523 int found = 0; 01524 01525 if (!change_password_realtime(vmu, newpassword)) 01526 return; 01527 01528 /* check if we should store the secret in the spool directory next to the messages */ 01529 switch (vmu->passwordlocation) { 01530 case OPT_PWLOC_SPOOLDIR: 01531 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01532 if (write_password_to_file(secretfn, newpassword) == 0) { 01533 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: secret.conf updated with new password\r\nPasswordSource: secret.conf"); 01534 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01535 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01536 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01537 break; 01538 } else { 01539 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01540 } 01541 /* Fall-through */ 01542 case OPT_PWLOC_VOICEMAILCONF: 01543 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01544 while ((category = ast_category_browse(cfg, category))) { 01545 if (!strcasecmp(category, vmu->context)) { 01546 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01547 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01548 break; 01549 } 01550 value = strstr(tmp, ","); 01551 if (!value) { 01552 new = alloca(strlen(newpassword)+1); 01553 sprintf(new, "%s", newpassword); 01554 } else { 01555 new = alloca((strlen(value) + strlen(newpassword) + 1)); 01556 sprintf(new, "%s%s", newpassword, value); 01557 } 01558 if (!(cat = ast_category_get(cfg, category))) { 01559 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01560 break; 01561 } 01562 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01563 found = 1; 01564 } 01565 } 01566 /* save the results */ 01567 if (found) { 01568 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: voicemail.conf updated with new password\r\nPasswordSource: voicemail.conf"); 01569 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01570 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01571 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01572 break; 01573 } 01574 } 01575 /* Fall-through */ 01576 case OPT_PWLOC_USERSCONF: 01577 /* check users.conf and update the password stored for the mailbox */ 01578 /* if no vmsecret entry exists create one. */ 01579 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01580 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01581 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01582 ast_debug(4, "users.conf: %s\n", category); 01583 if (!strcasecmp(category, vmu->mailbox)) { 01584 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01585 ast_debug(3, "looks like we need to make vmsecret!\n"); 01586 var = ast_variable_new("vmsecret", newpassword, ""); 01587 } else { 01588 var = NULL; 01589 } 01590 new = alloca(strlen(newpassword) + 1); 01591 sprintf(new, "%s", newpassword); 01592 if (!(cat = ast_category_get(cfg, category))) { 01593 ast_debug(4, "failed to get category!\n"); 01594 ast_free(var); 01595 break; 01596 } 01597 if (!var) { 01598 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01599 } else { 01600 ast_variable_append(cat, var); 01601 } 01602 found = 1; 01603 break; 01604 } 01605 } 01606 /* save the results and clean things up */ 01607 if (found) { 01608 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: users.conf updated with new password\r\nPasswordSource: users.conf"); 01609 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01610 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01611 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01612 } 01613 } 01614 } 01615 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1617 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_debug, ast_safe_system(), ast_test_suite_event_notify, ast_vm_user::context, ext_pass_cmd, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
01618 { 01619 char buf[255]; 01620 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01621 ast_debug(1, "External password: %s\n",buf); 01622 if (!ast_safe_system(buf)) { 01623 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: external script updated with new password\r\nPasswordSource: external"); 01624 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01625 /* Reset the password in memory, too */ 01626 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01627 } 01628 }
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.
01190 { 01191 int fds[2], pid = 0; 01192 01193 memset(buf, 0, len); 01194 01195 if (pipe(fds)) { 01196 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01197 } else { 01198 /* good to go*/ 01199 pid = ast_safe_fork(0); 01200 01201 if (pid < 0) { 01202 /* ok maybe not */ 01203 close(fds[0]); 01204 close(fds[1]); 01205 snprintf(buf, len, "FAILURE: Fork failed"); 01206 } else if (pid) { 01207 /* parent */ 01208 close(fds[1]); 01209 if (read(fds[0], buf, len) < 0) { 01210 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01211 } 01212 close(fds[0]); 01213 } else { 01214 /* child */ 01215 AST_DECLARE_APP_ARGS(arg, 01216 AST_APP_ARG(v)[20]; 01217 ); 01218 char *mycmd = ast_strdupa(command); 01219 01220 close(fds[0]); 01221 dup2(fds[1], STDOUT_FILENO); 01222 close(fds[1]); 01223 ast_close_fds_above_n(STDOUT_FILENO); 01224 01225 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01226 01227 execv(arg.v[0], arg.v); 01228 printf("FAILURE: %s", strerror(errno)); 01229 _exit(0); 01230 } 01231 } 01232 return buf; 01233 }
static int vm_delete | ( | char * | file | ) | [static] |
Removes the voicemail sound and information file.
file | The path to the sound file. This will be the the folder and message index, without the extension. |
Definition at line 4187 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04188 { 04189 char *txt; 04190 int txtsize = 0; 04191 04192 txtsize = (strlen(file) + 5)*sizeof(char); 04193 txt = alloca(txtsize); 04194 /* Sprintf here would safe because we alloca'd exactly the right length, 04195 * but trying to eliminate all sprintf's anyhow 04196 */ 04197 if (ast_check_realtime("voicemail_data")) { 04198 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04199 } 04200 snprintf(txt, txtsize, "%s.txt", file); 04201 unlink(txt); 04202 return ast_filedelete(file, NULL); 04203 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10627 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_play_and_wait(), AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, ast_flags::flags, 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(), and vm_app_options.
10628 { 10629 int res = 0; 10630 char *tmp; 10631 struct leave_vm_options leave_options; 10632 struct ast_flags flags = { 0 }; 10633 char *opts[OPT_ARG_ARRAY_SIZE]; 10634 AST_DECLARE_APP_ARGS(args, 10635 AST_APP_ARG(argv0); 10636 AST_APP_ARG(argv1); 10637 ); 10638 10639 memset(&leave_options, 0, sizeof(leave_options)); 10640 10641 if (chan->_state != AST_STATE_UP) 10642 ast_answer(chan); 10643 10644 if (!ast_strlen_zero(data)) { 10645 tmp = ast_strdupa(data); 10646 AST_STANDARD_APP_ARGS(args, tmp); 10647 if (args.argc == 2) { 10648 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10649 return -1; 10650 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10651 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10652 int gain; 10653 10654 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10655 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10656 return -1; 10657 } else { 10658 leave_options.record_gain = (signed char) gain; 10659 } 10660 } 10661 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10662 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10663 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10664 } 10665 } 10666 } else { 10667 char temp[256]; 10668 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10669 if (res < 0) 10670 return res; 10671 if (ast_strlen_zero(temp)) 10672 return 0; 10673 args.argv0 = ast_strdupa(temp); 10674 } 10675 10676 res = leave_voicemail(chan, args.argv0, &leave_options); 10677 if (res == 't') { 10678 ast_play_and_wait(chan, "vm-goodbye"); 10679 res = 0; 10680 } 10681 10682 if (res == OPERATOR_EXIT) { 10683 res = 0; 10684 } 10685 10686 if (res == ERROR_LOCK_PATH) { 10687 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10688 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10689 res = 0; 10690 } 10691 10692 return res; 10693 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9861 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_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_goto_if_exists(), ast_log(), AST_LOG_ERROR, 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, ast_channel::context, dialout(), ast_vm_user::dialout, ERROR_LOCK_PATH, EVENT_FLAG_CALL, find_user(), ast_flags::flags, forward_message(), free_user(), get_folder2(), get_folder_by_name(), globalflags, has_voicemail(), language, ast_vm_user::language, ast_vm_user::mailbox, make_file(), maxlogins, ast_vm_user::maxmsg, mbox(), NEW_FOLDER, OLD_FOLDER, 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(), run_externnotify(), save_to_folder(), say_and_wait(), 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 vmfmts.
09862 { 09863 /* XXX This is, admittedly, some pretty horrendous code. For some 09864 reason it just seemed a lot easier to do with GOTO's. I feel 09865 like I'm back in my GWBASIC days. XXX */ 09866 int res = -1; 09867 int cmd = 0; 09868 int valid = 0; 09869 char prefixstr[80] =""; 09870 char ext_context[256]=""; 09871 int box; 09872 int useadsi = 0; 09873 int skipuser = 0; 09874 struct vm_state vms; 09875 struct ast_vm_user *vmu = NULL, vmus; 09876 char *context = NULL; 09877 int silentexit = 0; 09878 struct ast_flags flags = { 0 }; 09879 signed char record_gain = 0; 09880 int play_auto = 0; 09881 int play_folder = 0; 09882 int in_urgent = 0; 09883 #ifdef IMAP_STORAGE 09884 int deleted = 0; 09885 #endif 09886 09887 /* Add the vm_state to the active list and keep it active */ 09888 memset(&vms, 0, sizeof(vms)); 09889 09890 vms.lastmsg = -1; 09891 09892 memset(&vmus, 0, sizeof(vmus)); 09893 09894 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09895 if (chan->_state != AST_STATE_UP) { 09896 ast_debug(1, "Before ast_answer\n"); 09897 ast_answer(chan); 09898 } 09899 09900 if (!ast_strlen_zero(data)) { 09901 char *opts[OPT_ARG_ARRAY_SIZE]; 09902 char *parse; 09903 AST_DECLARE_APP_ARGS(args, 09904 AST_APP_ARG(argv0); 09905 AST_APP_ARG(argv1); 09906 ); 09907 09908 parse = ast_strdupa(data); 09909 09910 AST_STANDARD_APP_ARGS(args, parse); 09911 09912 if (args.argc == 2) { 09913 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09914 return -1; 09915 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09916 int gain; 09917 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09918 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09919 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09920 return -1; 09921 } else { 09922 record_gain = (signed char) gain; 09923 } 09924 } else { 09925 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09926 } 09927 } 09928 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09929 play_auto = 1; 09930 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09931 /* See if it is a folder name first */ 09932 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09933 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09934 play_folder = -1; 09935 } 09936 } else { 09937 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09938 } 09939 } else { 09940 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09941 } 09942 if (play_folder > 9 || play_folder < 0) { 09943 ast_log(AST_LOG_WARNING, 09944 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09945 opts[OPT_ARG_PLAYFOLDER]); 09946 play_folder = 0; 09947 } 09948 } 09949 } else { 09950 /* old style options parsing */ 09951 while (*(args.argv0)) { 09952 if (*(args.argv0) == 's') 09953 ast_set_flag(&flags, OPT_SILENT); 09954 else if (*(args.argv0) == 'p') 09955 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09956 else 09957 break; 09958 (args.argv0)++; 09959 } 09960 09961 } 09962 09963 valid = ast_test_flag(&flags, OPT_SILENT); 09964 09965 if ((context = strchr(args.argv0, '@'))) 09966 *context++ = '\0'; 09967 09968 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09969 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09970 else 09971 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09972 09973 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09974 skipuser++; 09975 else 09976 valid = 0; 09977 } 09978 09979 if (!valid) 09980 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09981 09982 ast_debug(1, "After vm_authenticate\n"); 09983 09984 if (vms.username[0] == '*') { 09985 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09986 09987 /* user entered '*' */ 09988 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09989 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 09990 res = 0; /* prevent hangup */ 09991 goto out; 09992 } 09993 } 09994 09995 if (!res) { 09996 valid = 1; 09997 if (!skipuser) 09998 vmu = &vmus; 09999 } else { 10000 res = 0; 10001 } 10002 10003 /* If ADSI is supported, setup login screen */ 10004 adsi_begin(chan, &useadsi); 10005 10006 ast_test_suite_assert(valid); 10007 if (!valid) { 10008 goto out; 10009 } 10010 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10011 10012 #ifdef IMAP_STORAGE 10013 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10014 pthread_setspecific(ts_vmstate.key, &vms); 10015 10016 vms.interactive = 1; 10017 vms.updated = 1; 10018 if (vmu) 10019 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10020 vmstate_insert(&vms); 10021 init_vm_state(&vms); 10022 #endif 10023 /* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */ 10024 if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 10025 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 10026 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 10027 return -1; 10028 } 10029 if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 10030 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 10031 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 10032 return -1; 10033 } 10034 10035 /* Set language from config to override channel language */ 10036 if (!ast_strlen_zero(vmu->language)) 10037 ast_string_field_set(chan, language, vmu->language); 10038 10039 /* Retrieve urgent, old and new message counts */ 10040 ast_debug(1, "Before open_mailbox\n"); 10041 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10042 if (res < 0) 10043 goto out; 10044 vms.oldmessages = vms.lastmsg + 1; 10045 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10046 /* check INBOX */ 10047 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10048 if (res < 0) 10049 goto out; 10050 vms.newmessages = vms.lastmsg + 1; 10051 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10052 /* Start in Urgent */ 10053 in_urgent = 1; 10054 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10055 if (res < 0) 10056 goto out; 10057 vms.urgentmessages = vms.lastmsg + 1; 10058 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10059 10060 /* Select proper mailbox FIRST!! */ 10061 if (play_auto) { 10062 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10063 if (vms.urgentmessages) { 10064 in_urgent = 1; 10065 res = open_mailbox(&vms, vmu, 11); 10066 } else { 10067 in_urgent = 0; 10068 res = open_mailbox(&vms, vmu, play_folder); 10069 } 10070 if (res < 0) 10071 goto out; 10072 10073 /* If there are no new messages, inform the user and hangup */ 10074 if (vms.lastmsg == -1) { 10075 in_urgent = 0; 10076 cmd = vm_browse_messages(chan, &vms, vmu); 10077 res = 0; 10078 goto out; 10079 } 10080 } else { 10081 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10082 /* If we only have old messages start here */ 10083 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10084 in_urgent = 0; 10085 play_folder = 1; 10086 if (res < 0) 10087 goto out; 10088 } else if (!vms.urgentmessages && vms.newmessages) { 10089 /* If we have new messages but none are urgent */ 10090 in_urgent = 0; 10091 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10092 if (res < 0) 10093 goto out; 10094 } 10095 } 10096 10097 if (useadsi) 10098 adsi_status(chan, &vms); 10099 res = 0; 10100 10101 /* Check to see if this is a new user */ 10102 if (!strcasecmp(vmu->mailbox, vmu->password) && 10103 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10104 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10105 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10106 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10107 if ((cmd == 't') || (cmd == '#')) { 10108 /* Timeout */ 10109 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10110 res = 0; 10111 goto out; 10112 } else if (cmd < 0) { 10113 /* Hangup */ 10114 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10115 res = -1; 10116 goto out; 10117 } 10118 } 10119 #ifdef IMAP_STORAGE 10120 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10121 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10122 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10123 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10124 } 10125 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10126 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10127 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10128 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10129 } 10130 #endif 10131 10132 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10133 if (play_auto) { 10134 cmd = '1'; 10135 } else { 10136 cmd = vm_intro(chan, vmu, &vms); 10137 } 10138 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10139 10140 vms.repeats = 0; 10141 vms.starting = 1; 10142 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10143 /* Run main menu */ 10144 switch (cmd) { 10145 case '1': /* First message */ 10146 vms.curmsg = 0; 10147 /* Fall through */ 10148 case '5': /* Play current message */ 10149 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10150 cmd = vm_browse_messages(chan, &vms, vmu); 10151 break; 10152 case '2': /* Change folders */ 10153 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10154 if (useadsi) 10155 adsi_folders(chan, 0, "Change to folder..."); 10156 10157 cmd = get_folder2(chan, "vm-changeto", 0); 10158 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10159 if (cmd == '#') { 10160 cmd = 0; 10161 } else if (cmd > 0) { 10162 cmd = cmd - '0'; 10163 res = close_mailbox(&vms, vmu); 10164 if (res == ERROR_LOCK_PATH) 10165 goto out; 10166 /* If folder is not urgent, set in_urgent to zero! */ 10167 if (cmd != 11) in_urgent = 0; 10168 res = open_mailbox(&vms, vmu, cmd); 10169 if (res < 0) 10170 goto out; 10171 play_folder = cmd; 10172 cmd = 0; 10173 } 10174 if (useadsi) 10175 adsi_status2(chan, &vms); 10176 10177 if (!cmd) { 10178 cmd = vm_play_folder_name(chan, vms.vmbox); 10179 } 10180 10181 vms.starting = 1; 10182 break; 10183 case '3': /* Advanced options */ 10184 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10185 cmd = 0; 10186 vms.repeats = 0; 10187 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10188 switch (cmd) { 10189 case '1': /* Reply */ 10190 if (vms.lastmsg > -1 && !vms.starting) { 10191 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10192 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10193 res = cmd; 10194 goto out; 10195 } 10196 } else { 10197 cmd = ast_play_and_wait(chan, "vm-sorry"); 10198 } 10199 cmd = 't'; 10200 break; 10201 case '2': /* Callback */ 10202 if (!vms.starting) 10203 ast_verb(3, "Callback Requested\n"); 10204 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10205 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10206 if (cmd == 9) { 10207 silentexit = 1; 10208 goto out; 10209 } else if (cmd == ERROR_LOCK_PATH) { 10210 res = cmd; 10211 goto out; 10212 } 10213 } else { 10214 cmd = ast_play_and_wait(chan, "vm-sorry"); 10215 } 10216 cmd = 't'; 10217 break; 10218 case '3': /* Envelope */ 10219 if (vms.lastmsg > -1 && !vms.starting) { 10220 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10221 if (cmd == ERROR_LOCK_PATH) { 10222 res = cmd; 10223 goto out; 10224 } 10225 } else { 10226 cmd = ast_play_and_wait(chan, "vm-sorry"); 10227 } 10228 cmd = 't'; 10229 break; 10230 case '4': /* Dialout */ 10231 if (!ast_strlen_zero(vmu->dialout)) { 10232 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10233 if (cmd == 9) { 10234 silentexit = 1; 10235 goto out; 10236 } 10237 } else { 10238 cmd = ast_play_and_wait(chan, "vm-sorry"); 10239 } 10240 cmd = 't'; 10241 break; 10242 10243 case '5': /* Leave VoiceMail */ 10244 if (ast_test_flag(vmu, VM_SVMAIL)) { 10245 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10246 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10247 res = cmd; 10248 goto out; 10249 } 10250 } else { 10251 cmd = ast_play_and_wait(chan, "vm-sorry"); 10252 } 10253 cmd = 't'; 10254 break; 10255 10256 case '*': /* Return to main menu */ 10257 cmd = 't'; 10258 break; 10259 10260 default: 10261 cmd = 0; 10262 if (!vms.starting) { 10263 cmd = ast_play_and_wait(chan, "vm-toreply"); 10264 } 10265 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10266 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10267 } 10268 if (!cmd && !vms.starting) { 10269 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10270 } 10271 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10272 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10273 } 10274 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10275 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10276 } 10277 if (!cmd) { 10278 cmd = ast_play_and_wait(chan, "vm-starmain"); 10279 } 10280 if (!cmd) { 10281 cmd = ast_waitfordigit(chan, 6000); 10282 } 10283 if (!cmd) { 10284 vms.repeats++; 10285 } 10286 if (vms.repeats > 3) { 10287 cmd = 't'; 10288 } 10289 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10290 } 10291 } 10292 if (cmd == 't') { 10293 cmd = 0; 10294 vms.repeats = 0; 10295 } 10296 break; 10297 case '4': /* Go to the previous message */ 10298 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10299 if (vms.curmsg > 0) { 10300 vms.curmsg--; 10301 cmd = play_message(chan, vmu, &vms); 10302 } else { 10303 /* Check if we were listening to new 10304 messages. If so, go to Urgent messages 10305 instead of saying "no more messages" 10306 */ 10307 if (in_urgent == 0 && vms.urgentmessages > 0) { 10308 /* Check for Urgent messages */ 10309 in_urgent = 1; 10310 res = close_mailbox(&vms, vmu); 10311 if (res == ERROR_LOCK_PATH) 10312 goto out; 10313 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10314 if (res < 0) 10315 goto out; 10316 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10317 vms.curmsg = vms.lastmsg; 10318 if (vms.lastmsg < 0) { 10319 cmd = ast_play_and_wait(chan, "vm-nomore"); 10320 } 10321 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10322 vms.curmsg = vms.lastmsg; 10323 cmd = play_message(chan, vmu, &vms); 10324 } else { 10325 cmd = ast_play_and_wait(chan, "vm-nomore"); 10326 } 10327 } 10328 break; 10329 case '6': /* Go to the next message */ 10330 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10331 if (vms.curmsg < vms.lastmsg) { 10332 vms.curmsg++; 10333 cmd = play_message(chan, vmu, &vms); 10334 } else { 10335 if (in_urgent && vms.newmessages > 0) { 10336 /* Check if we were listening to urgent 10337 * messages. If so, go to regular new messages 10338 * instead of saying "no more messages" 10339 */ 10340 in_urgent = 0; 10341 res = close_mailbox(&vms, vmu); 10342 if (res == ERROR_LOCK_PATH) 10343 goto out; 10344 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10345 if (res < 0) 10346 goto out; 10347 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10348 vms.curmsg = -1; 10349 if (vms.lastmsg < 0) { 10350 cmd = ast_play_and_wait(chan, "vm-nomore"); 10351 } 10352 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10353 vms.curmsg = 0; 10354 cmd = play_message(chan, vmu, &vms); 10355 } else { 10356 cmd = ast_play_and_wait(chan, "vm-nomore"); 10357 } 10358 } 10359 break; 10360 case '7': /* Delete the current message */ 10361 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10362 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10363 if (useadsi) 10364 adsi_delete(chan, &vms); 10365 if (vms.deleted[vms.curmsg]) { 10366 if (play_folder == 0) { 10367 if (in_urgent) { 10368 vms.urgentmessages--; 10369 } else { 10370 vms.newmessages--; 10371 } 10372 } 10373 else if (play_folder == 1) 10374 vms.oldmessages--; 10375 cmd = ast_play_and_wait(chan, "vm-deleted"); 10376 } else { 10377 if (play_folder == 0) { 10378 if (in_urgent) { 10379 vms.urgentmessages++; 10380 } else { 10381 vms.newmessages++; 10382 } 10383 } 10384 else if (play_folder == 1) 10385 vms.oldmessages++; 10386 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10387 } 10388 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10389 if (vms.curmsg < vms.lastmsg) { 10390 vms.curmsg++; 10391 cmd = play_message(chan, vmu, &vms); 10392 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10393 vms.curmsg = 0; 10394 cmd = play_message(chan, vmu, &vms); 10395 } else { 10396 /* Check if we were listening to urgent 10397 messages. If so, go to regular new messages 10398 instead of saying "no more messages" 10399 */ 10400 if (in_urgent == 1) { 10401 /* Check for new messages */ 10402 in_urgent = 0; 10403 res = close_mailbox(&vms, vmu); 10404 if (res == ERROR_LOCK_PATH) 10405 goto out; 10406 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10407 if (res < 0) 10408 goto out; 10409 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10410 vms.curmsg = -1; 10411 if (vms.lastmsg < 0) { 10412 cmd = ast_play_and_wait(chan, "vm-nomore"); 10413 } 10414 } else { 10415 cmd = ast_play_and_wait(chan, "vm-nomore"); 10416 } 10417 } 10418 } 10419 } else /* Delete not valid if we haven't selected a message */ 10420 cmd = 0; 10421 #ifdef IMAP_STORAGE 10422 deleted = 1; 10423 #endif 10424 break; 10425 10426 case '8': /* Forward the current message */ 10427 if (vms.lastmsg > -1) { 10428 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10429 if (cmd == ERROR_LOCK_PATH) { 10430 res = cmd; 10431 goto out; 10432 } 10433 } else { 10434 /* Check if we were listening to urgent 10435 messages. If so, go to regular new messages 10436 instead of saying "no more messages" 10437 */ 10438 if (in_urgent == 1 && vms.newmessages > 0) { 10439 /* Check for new messages */ 10440 in_urgent = 0; 10441 res = close_mailbox(&vms, vmu); 10442 if (res == ERROR_LOCK_PATH) 10443 goto out; 10444 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10445 if (res < 0) 10446 goto out; 10447 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10448 vms.curmsg = -1; 10449 if (vms.lastmsg < 0) { 10450 cmd = ast_play_and_wait(chan, "vm-nomore"); 10451 } 10452 } else { 10453 cmd = ast_play_and_wait(chan, "vm-nomore"); 10454 } 10455 } 10456 break; 10457 case '9': /* Save message to folder */ 10458 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10459 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10460 /* No message selected */ 10461 cmd = 0; 10462 break; 10463 } 10464 if (useadsi) 10465 adsi_folders(chan, 1, "Save to folder..."); 10466 cmd = get_folder2(chan, "vm-savefolder", 1); 10467 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10468 box = 0; /* Shut up compiler */ 10469 if (cmd == '#') { 10470 cmd = 0; 10471 break; 10472 } else if (cmd > 0) { 10473 box = cmd = cmd - '0'; 10474 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10475 if (cmd == ERROR_LOCK_PATH) { 10476 res = cmd; 10477 goto out; 10478 #ifndef IMAP_STORAGE 10479 } else if (!cmd) { 10480 vms.deleted[vms.curmsg] = 1; 10481 #endif 10482 } else { 10483 vms.deleted[vms.curmsg] = 0; 10484 vms.heard[vms.curmsg] = 0; 10485 } 10486 } 10487 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10488 if (useadsi) 10489 adsi_message(chan, &vms); 10490 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10491 if (!cmd) { 10492 cmd = ast_play_and_wait(chan, "vm-message"); 10493 if (!cmd) 10494 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10495 if (!cmd) 10496 cmd = ast_play_and_wait(chan, "vm-savedto"); 10497 if (!cmd) 10498 cmd = vm_play_folder_name(chan, vms.fn); 10499 } else { 10500 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10501 } 10502 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10503 if (vms.curmsg < vms.lastmsg) { 10504 vms.curmsg++; 10505 cmd = play_message(chan, vmu, &vms); 10506 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10507 vms.curmsg = 0; 10508 cmd = play_message(chan, vmu, &vms); 10509 } else { 10510 /* Check if we were listening to urgent 10511 messages. If so, go to regular new messages 10512 instead of saying "no more messages" 10513 */ 10514 if (in_urgent == 1 && vms.newmessages > 0) { 10515 /* Check for new messages */ 10516 in_urgent = 0; 10517 res = close_mailbox(&vms, vmu); 10518 if (res == ERROR_LOCK_PATH) 10519 goto out; 10520 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10521 if (res < 0) 10522 goto out; 10523 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10524 vms.curmsg = -1; 10525 if (vms.lastmsg < 0) { 10526 cmd = ast_play_and_wait(chan, "vm-nomore"); 10527 } 10528 } else { 10529 cmd = ast_play_and_wait(chan, "vm-nomore"); 10530 } 10531 } 10532 } 10533 break; 10534 case '*': /* Help */ 10535 if (!vms.starting) { 10536 cmd = ast_play_and_wait(chan, "vm-onefor"); 10537 if (!strncasecmp(chan->language, "he", 2)) { 10538 cmd = ast_play_and_wait(chan, "vm-for"); 10539 } 10540 if (!cmd) 10541 cmd = vm_play_folder_name(chan, vms.vmbox); 10542 if (!cmd) 10543 cmd = ast_play_and_wait(chan, "vm-opts"); 10544 if (!cmd) 10545 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10546 } else 10547 cmd = 0; 10548 break; 10549 case '0': /* Mailbox options */ 10550 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10551 if (useadsi) 10552 adsi_status(chan, &vms); 10553 break; 10554 default: /* Nothing */ 10555 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10556 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10557 break; 10558 } 10559 } 10560 if ((cmd == 't') || (cmd == '#')) { 10561 /* Timeout */ 10562 res = 0; 10563 } else { 10564 /* Hangup */ 10565 res = -1; 10566 } 10567 10568 out: 10569 if (res > -1) { 10570 ast_stopstream(chan); 10571 adsi_goodbye(chan); 10572 if (valid && res != OPERATOR_EXIT) { 10573 if (silentexit) 10574 res = ast_play_and_wait(chan, "vm-dialout"); 10575 else 10576 res = ast_play_and_wait(chan, "vm-goodbye"); 10577 } 10578 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10579 res = 0; 10580 } 10581 if (useadsi) 10582 ast_adsi_unload_session(chan); 10583 } 10584 if (vmu) 10585 close_mailbox(&vms, vmu); 10586 if (valid) { 10587 int new = 0, old = 0, urgent = 0; 10588 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10589 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10590 /* Urgent flag not passwd to externnotify here */ 10591 run_externnotify(vmu->context, vmu->mailbox, NULL); 10592 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10593 queue_mwi_event(ext_context, urgent, new, old); 10594 } 10595 #ifdef IMAP_STORAGE 10596 /* expunge message - use UID Expunge if supported on IMAP server*/ 10597 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10598 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10599 ast_mutex_lock(&vms.lock); 10600 #ifdef HAVE_IMAP_TK2006 10601 if (LEVELUIDPLUS (vms.mailstream)) { 10602 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10603 } else 10604 #endif 10605 mail_expunge(vms.mailstream); 10606 ast_mutex_unlock(&vms.lock); 10607 } 10608 /* before we delete the state, we should copy pertinent info 10609 * back to the persistent model */ 10610 if (vmu) { 10611 vmstate_delete(&vms); 10612 } 10613 #endif 10614 if (vmu) 10615 free_user(vmu); 10616 if (vms.deleted) 10617 ast_free(vms.deleted); 10618 if (vms.heard) 10619 ast_free(vms.heard); 10620 10621 #ifdef IMAP_STORAGE 10622 pthread_setspecific(ts_vmstate.key, NULL); 10623 #endif 10624 return res; 10625 }
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.
chan | ||
vmu | ||
curdir | ||
curmsg | ||
vm_fmts | ||
context | ||
record_gain | ||
duration | ||
vms | ||
flag |
This is invoked from forward_message() when performing a forward operation (option 8 from main menu).
Definition at line 6850 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, config_flags, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, maxsilence, play_record_review(), silencethreshold, vm_pls_try_again, and vm_prepend_timeout.
06852 { 06853 int cmd = 0; 06854 int retries = 0, prepend_duration = 0, already_recorded = 0; 06855 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06856 char textfile[PATH_MAX]; 06857 struct ast_config *msg_cfg; 06858 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06859 #ifndef IMAP_STORAGE 06860 signed char zero_gain = 0; 06861 #endif 06862 const char *duration_str; 06863 06864 /* Must always populate duration correctly */ 06865 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06866 strcpy(textfile, msgfile); 06867 strcpy(backup, msgfile); 06868 strcpy(backup_textfile, msgfile); 06869 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06870 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06871 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06872 06873 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06874 *duration = atoi(duration_str); 06875 } else { 06876 *duration = 0; 06877 } 06878 06879 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06880 if (cmd) 06881 retries = 0; 06882 switch (cmd) { 06883 case '1': 06884 06885 #ifdef IMAP_STORAGE 06886 /* Record new intro file */ 06887 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06888 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06889 ast_play_and_wait(chan, INTRO); 06890 ast_play_and_wait(chan, "beep"); 06891 play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06892 cmd = 't'; 06893 #else 06894 06895 /* prepend a message to the current message, update the metadata and return */ 06896 06897 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06898 strcpy(textfile, msgfile); 06899 strncat(textfile, ".txt", sizeof(textfile) - 1); 06900 *duration = 0; 06901 06902 /* if we can't read the message metadata, stop now */ 06903 if (!msg_cfg) { 06904 cmd = 0; 06905 break; 06906 } 06907 06908 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06909 #ifndef IMAP_STORAGE 06910 if (already_recorded) { 06911 ast_filecopy(backup, msgfile, NULL); 06912 copy(backup_textfile, textfile); 06913 } 06914 else { 06915 ast_filecopy(msgfile, backup, NULL); 06916 copy(textfile, backup_textfile); 06917 } 06918 #endif 06919 already_recorded = 1; 06920 06921 if (record_gain) 06922 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06923 06924 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06925 06926 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06927 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06928 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06929 ast_filerename(backup, msgfile, NULL); 06930 } 06931 06932 if (record_gain) 06933 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06934 06935 06936 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06937 *duration = atoi(duration_str); 06938 06939 if (prepend_duration) { 06940 struct ast_category *msg_cat; 06941 /* need enough space for a maximum-length message duration */ 06942 char duration_buf[12]; 06943 06944 *duration += prepend_duration; 06945 msg_cat = ast_category_get(msg_cfg, "message"); 06946 snprintf(duration_buf, 11, "%ld", *duration); 06947 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06948 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06949 } 06950 } 06951 06952 #endif 06953 break; 06954 case '2': 06955 /* NULL out introfile so we know there is no intro! */ 06956 #ifdef IMAP_STORAGE 06957 *vms->introfn = '\0'; 06958 #endif 06959 cmd = 't'; 06960 break; 06961 case '*': 06962 cmd = '*'; 06963 break; 06964 default: 06965 /* If time_out and return to menu, reset already_recorded */ 06966 already_recorded = 0; 06967 06968 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06969 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06970 if (!cmd) { 06971 cmd = ast_play_and_wait(chan, "vm-starmain"); 06972 /* "press star to return to the main menu" */ 06973 } 06974 if (!cmd) { 06975 cmd = ast_waitfordigit(chan, 6000); 06976 } 06977 if (!cmd) { 06978 retries++; 06979 } 06980 if (retries > 3) { 06981 cmd = '*'; /* Let's cancel this beast */ 06982 } 06983 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 06984 } 06985 } 06986 06987 if (msg_cfg) 06988 ast_config_destroy(msg_cfg); 06989 if (prepend_duration) 06990 *duration = prepend_duration; 06991 06992 if (already_recorded && cmd == -1) { 06993 /* restore original message if prepention cancelled */ 06994 ast_filerename(backup, msgfile, NULL); 06995 rename(backup_textfile, textfile); 06996 } 06997 06998 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 06999 cmd = 0; 07000 return cmd; 07001 }
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 9179 of file app_voicemail_imapstorage.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
09180 { 09181 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09182 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09183 } else { /* Default to ENGLISH */ 09184 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09185 } 09186 }
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 9078 of file app_voicemail_imapstorage.c.
References 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.
09079 { 09080 int res = 0; 09081 /* Play instructions and wait for new command */ 09082 while (!res) { 09083 if (vms->starting) { 09084 if (vms->lastmsg > -1) { 09085 if (skipadvanced) 09086 res = ast_play_and_wait(chan, "vm-onefor-full"); 09087 else 09088 res = ast_play_and_wait(chan, "vm-onefor"); 09089 if (!res) 09090 res = vm_play_folder_name(chan, vms->vmbox); 09091 } 09092 if (!res) { 09093 if (skipadvanced) 09094 res = ast_play_and_wait(chan, "vm-opts-full"); 09095 else 09096 res = ast_play_and_wait(chan, "vm-opts"); 09097 } 09098 } else { 09099 /* Added for additional help */ 09100 if (skipadvanced) { 09101 res = ast_play_and_wait(chan, "vm-onefor-full"); 09102 if (!res) 09103 res = vm_play_folder_name(chan, vms->vmbox); 09104 res = ast_play_and_wait(chan, "vm-opts-full"); 09105 } 09106 /* Logic: 09107 * If the current message is not the first OR 09108 * if we're listening to the first new message and there are 09109 * also urgent messages, then prompt for navigation to the 09110 * previous message 09111 */ 09112 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09113 res = ast_play_and_wait(chan, "vm-prev"); 09114 } 09115 if (!res && !skipadvanced) 09116 res = ast_play_and_wait(chan, "vm-advopts"); 09117 if (!res) 09118 res = ast_play_and_wait(chan, "vm-repeat"); 09119 /* Logic: 09120 * If we're not listening to the last message OR 09121 * we're listening to the last urgent message and there are 09122 * also new non-urgent messages, then prompt for navigation 09123 * to the next message 09124 */ 09125 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09126 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09127 res = ast_play_and_wait(chan, "vm-next"); 09128 } 09129 if (!res) { 09130 if (!vms->deleted[vms->curmsg]) 09131 res = ast_play_and_wait(chan, "vm-delete"); 09132 else 09133 res = ast_play_and_wait(chan, "vm-undelete"); 09134 if (!res) 09135 res = ast_play_and_wait(chan, "vm-toforward"); 09136 if (!res) 09137 res = ast_play_and_wait(chan, "vm-savemessage"); 09138 } 09139 } 09140 if (!res) { 09141 res = ast_play_and_wait(chan, "vm-helpexit"); 09142 } 09143 if (!res) 09144 res = ast_waitfordigit(chan, 6000); 09145 if (!res) { 09146 vms->repeats++; 09147 if (vms->repeats > 2) { 09148 res = 't'; 09149 } 09150 } 09151 } 09152 return res; 09153 }
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 9155 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.
09156 { 09157 int res = 0; 09158 /* Play instructions and wait for new command */ 09159 while (!res) { 09160 if (vms->lastmsg > -1) { 09161 res = ast_play_and_wait(chan, "vm-listen"); 09162 if (!res) 09163 res = vm_play_folder_name(chan, vms->vmbox); 09164 if (!res) 09165 res = ast_play_and_wait(chan, "press"); 09166 if (!res) 09167 res = ast_play_and_wait(chan, "digits/1"); 09168 } 09169 if (!res) 09170 res = ast_play_and_wait(chan, "vm-opts"); 09171 if (!res) { 09172 vms->starting = 0; 09173 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09174 } 09175 } 09176 return res; 09177 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9016 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(), VM_SPOOL_DIR, and VM_TEMPGREETWARN.
09017 { 09018 char prefile[256]; 09019 09020 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09021 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09022 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09023 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09024 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09025 ast_play_and_wait(chan, "vm-tempgreetactive"); 09026 } 09027 DISPOSE(prefile, -1); 09028 } 09029 09030 /* Play voicemail intro - syntax is different for different languages */ 09031 if (0) { 09032 return 0; 09033 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09034 return vm_intro_cs(chan, vms); 09035 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09036 static int deprecation_warning = 0; 09037 if (deprecation_warning++ % 10 == 0) { 09038 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09039 } 09040 return vm_intro_cs(chan, vms); 09041 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09042 return vm_intro_de(chan, vms); 09043 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09044 return vm_intro_es(chan, vms); 09045 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09046 return vm_intro_fr(chan, vms); 09047 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09048 return vm_intro_gr(chan, vms); 09049 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09050 return vm_intro_he(chan, vms); 09051 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09052 return vm_intro_it(chan, vms); 09053 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09054 return vm_intro_nl(chan, vms); 09055 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09056 return vm_intro_no(chan, vms); 09057 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09058 return vm_intro_pl(chan, vms); 09059 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09060 return vm_intro_pt_BR(chan, vms); 09061 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09062 return vm_intro_pt(chan, vms); 09063 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09064 return vm_intro_multilang(chan, vms, "n"); 09065 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09066 return vm_intro_se(chan, vms); 09067 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09068 return vm_intro_multilang(chan, vms, "n"); 09069 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09070 return vm_intro_vi(chan, vms); 09071 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09072 return vm_intro_zh(chan, vms); 09073 } else { /* Default to ENGLISH */ 09074 return vm_intro_en(chan, vms); 09075 } 09076 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8886 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.
08887 { 08888 int res; 08889 res = ast_play_and_wait(chan, "vm-youhave"); 08890 if (!res) { 08891 if (vms->newmessages) { 08892 if (vms->newmessages == 1) { 08893 res = ast_play_and_wait(chan, "digits/jednu"); 08894 } else { 08895 res = say_and_wait(chan, vms->newmessages, chan->language); 08896 } 08897 if (!res) { 08898 if ((vms->newmessages == 1)) 08899 res = ast_play_and_wait(chan, "vm-novou"); 08900 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08901 res = ast_play_and_wait(chan, "vm-nove"); 08902 if (vms->newmessages > 4) 08903 res = ast_play_and_wait(chan, "vm-novych"); 08904 } 08905 if (vms->oldmessages && !res) 08906 res = ast_play_and_wait(chan, "vm-and"); 08907 else if (!res) { 08908 if ((vms->newmessages == 1)) 08909 res = ast_play_and_wait(chan, "vm-zpravu"); 08910 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08911 res = ast_play_and_wait(chan, "vm-zpravy"); 08912 if (vms->newmessages > 4) 08913 res = ast_play_and_wait(chan, "vm-zprav"); 08914 } 08915 } 08916 if (!res && vms->oldmessages) { 08917 res = say_and_wait(chan, vms->oldmessages, chan->language); 08918 if (!res) { 08919 if ((vms->oldmessages == 1)) 08920 res = ast_play_and_wait(chan, "vm-starou"); 08921 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08922 res = ast_play_and_wait(chan, "vm-stare"); 08923 if (vms->oldmessages > 4) 08924 res = ast_play_and_wait(chan, "vm-starych"); 08925 } 08926 if (!res) { 08927 if ((vms->oldmessages == 1)) 08928 res = ast_play_and_wait(chan, "vm-zpravu"); 08929 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08930 res = ast_play_and_wait(chan, "vm-zpravy"); 08931 if (vms->oldmessages > 4) 08932 res = ast_play_and_wait(chan, "vm-zprav"); 08933 } 08934 } 08935 if (!res) { 08936 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08937 res = ast_play_and_wait(chan, "vm-no"); 08938 if (!res) 08939 res = ast_play_and_wait(chan, "vm-zpravy"); 08940 } 08941 } 08942 } 08943 return res; 08944 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8582 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.
08583 { 08584 /* Introduce messages they have */ 08585 int res; 08586 res = ast_play_and_wait(chan, "vm-youhave"); 08587 if (!res) { 08588 if (vms->newmessages) { 08589 if ((vms->newmessages == 1)) 08590 res = ast_play_and_wait(chan, "digits/1F"); 08591 else 08592 res = say_and_wait(chan, vms->newmessages, chan->language); 08593 if (!res) 08594 res = ast_play_and_wait(chan, "vm-INBOX"); 08595 if (vms->oldmessages && !res) 08596 res = ast_play_and_wait(chan, "vm-and"); 08597 else if (!res) { 08598 if ((vms->newmessages == 1)) 08599 res = ast_play_and_wait(chan, "vm-message"); 08600 else 08601 res = ast_play_and_wait(chan, "vm-messages"); 08602 } 08603 08604 } 08605 if (!res && vms->oldmessages) { 08606 if (vms->oldmessages == 1) 08607 res = ast_play_and_wait(chan, "digits/1F"); 08608 else 08609 res = say_and_wait(chan, vms->oldmessages, chan->language); 08610 if (!res) 08611 res = ast_play_and_wait(chan, "vm-Old"); 08612 if (!res) { 08613 if (vms->oldmessages == 1) 08614 res = ast_play_and_wait(chan, "vm-message"); 08615 else 08616 res = ast_play_and_wait(chan, "vm-messages"); 08617 } 08618 } 08619 if (!res) { 08620 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08621 res = ast_play_and_wait(chan, "vm-no"); 08622 if (!res) 08623 res = ast_play_and_wait(chan, "vm-messages"); 08624 } 08625 } 08626 } 08627 return res; 08628 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8331 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.
08332 { 08333 int res; 08334 08335 /* Introduce messages they have */ 08336 res = ast_play_and_wait(chan, "vm-youhave"); 08337 if (!res) { 08338 if (vms->urgentmessages) { 08339 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08340 if (!res) 08341 res = ast_play_and_wait(chan, "vm-Urgent"); 08342 if ((vms->oldmessages || vms->newmessages) && !res) { 08343 res = ast_play_and_wait(chan, "vm-and"); 08344 } else if (!res) { 08345 if ((vms->urgentmessages == 1)) 08346 res = ast_play_and_wait(chan, "vm-message"); 08347 else 08348 res = ast_play_and_wait(chan, "vm-messages"); 08349 } 08350 } 08351 if (vms->newmessages) { 08352 res = say_and_wait(chan, vms->newmessages, chan->language); 08353 if (!res) 08354 res = ast_play_and_wait(chan, "vm-INBOX"); 08355 if (vms->oldmessages && !res) 08356 res = ast_play_and_wait(chan, "vm-and"); 08357 else if (!res) { 08358 if ((vms->newmessages == 1)) 08359 res = ast_play_and_wait(chan, "vm-message"); 08360 else 08361 res = ast_play_and_wait(chan, "vm-messages"); 08362 } 08363 08364 } 08365 if (!res && vms->oldmessages) { 08366 res = say_and_wait(chan, vms->oldmessages, chan->language); 08367 if (!res) 08368 res = ast_play_and_wait(chan, "vm-Old"); 08369 if (!res) { 08370 if (vms->oldmessages == 1) 08371 res = ast_play_and_wait(chan, "vm-message"); 08372 else 08373 res = ast_play_and_wait(chan, "vm-messages"); 08374 } 08375 } 08376 if (!res) { 08377 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08378 res = ast_play_and_wait(chan, "vm-no"); 08379 if (!res) 08380 res = ast_play_and_wait(chan, "vm-messages"); 08381 } 08382 } 08383 } 08384 return res; 08385 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8631 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.
08632 { 08633 /* Introduce messages they have */ 08634 int res; 08635 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08636 res = ast_play_and_wait(chan, "vm-youhaveno"); 08637 if (!res) 08638 res = ast_play_and_wait(chan, "vm-messages"); 08639 } else { 08640 res = ast_play_and_wait(chan, "vm-youhave"); 08641 } 08642 if (!res) { 08643 if (vms->newmessages) { 08644 if (!res) { 08645 if ((vms->newmessages == 1)) { 08646 res = ast_play_and_wait(chan, "digits/1M"); 08647 if (!res) 08648 res = ast_play_and_wait(chan, "vm-message"); 08649 if (!res) 08650 res = ast_play_and_wait(chan, "vm-INBOXs"); 08651 } else { 08652 res = say_and_wait(chan, vms->newmessages, chan->language); 08653 if (!res) 08654 res = ast_play_and_wait(chan, "vm-messages"); 08655 if (!res) 08656 res = ast_play_and_wait(chan, "vm-INBOX"); 08657 } 08658 } 08659 if (vms->oldmessages && !res) 08660 res = ast_play_and_wait(chan, "vm-and"); 08661 } 08662 if (vms->oldmessages) { 08663 if (!res) { 08664 if (vms->oldmessages == 1) { 08665 res = ast_play_and_wait(chan, "digits/1M"); 08666 if (!res) 08667 res = ast_play_and_wait(chan, "vm-message"); 08668 if (!res) 08669 res = ast_play_and_wait(chan, "vm-Olds"); 08670 } else { 08671 res = say_and_wait(chan, vms->oldmessages, chan->language); 08672 if (!res) 08673 res = ast_play_and_wait(chan, "vm-messages"); 08674 if (!res) 08675 res = ast_play_and_wait(chan, "vm-Old"); 08676 } 08677 } 08678 } 08679 } 08680 return res; 08681 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8729 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.
08730 { 08731 /* Introduce messages they have */ 08732 int res; 08733 res = ast_play_and_wait(chan, "vm-youhave"); 08734 if (!res) { 08735 if (vms->newmessages) { 08736 res = say_and_wait(chan, vms->newmessages, chan->language); 08737 if (!res) 08738 res = ast_play_and_wait(chan, "vm-INBOX"); 08739 if (vms->oldmessages && !res) 08740 res = ast_play_and_wait(chan, "vm-and"); 08741 else if (!res) { 08742 if ((vms->newmessages == 1)) 08743 res = ast_play_and_wait(chan, "vm-message"); 08744 else 08745 res = ast_play_and_wait(chan, "vm-messages"); 08746 } 08747 08748 } 08749 if (!res && vms->oldmessages) { 08750 res = say_and_wait(chan, vms->oldmessages, chan->language); 08751 if (!res) 08752 res = ast_play_and_wait(chan, "vm-Old"); 08753 if (!res) { 08754 if (vms->oldmessages == 1) 08755 res = ast_play_and_wait(chan, "vm-message"); 08756 else 08757 res = ast_play_and_wait(chan, "vm-messages"); 08758 } 08759 } 08760 if (!res) { 08761 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08762 res = ast_play_and_wait(chan, "vm-no"); 08763 if (!res) 08764 res = ast_play_and_wait(chan, "vm-messages"); 08765 } 08766 } 08767 } 08768 return res; 08769 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8130 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.
08131 { 08132 int res = 0; 08133 08134 if (vms->newmessages) { 08135 res = ast_play_and_wait(chan, "vm-youhave"); 08136 if (!res) 08137 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08138 if (!res) { 08139 if ((vms->newmessages == 1)) { 08140 res = ast_play_and_wait(chan, "vm-INBOX"); 08141 if (!res) 08142 res = ast_play_and_wait(chan, "vm-message"); 08143 } else { 08144 res = ast_play_and_wait(chan, "vm-INBOXs"); 08145 if (!res) 08146 res = ast_play_and_wait(chan, "vm-messages"); 08147 } 08148 } 08149 } else if (vms->oldmessages){ 08150 res = ast_play_and_wait(chan, "vm-youhave"); 08151 if (!res) 08152 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08153 if ((vms->oldmessages == 1)){ 08154 res = ast_play_and_wait(chan, "vm-Old"); 08155 if (!res) 08156 res = ast_play_and_wait(chan, "vm-message"); 08157 } else { 08158 res = ast_play_and_wait(chan, "vm-Olds"); 08159 if (!res) 08160 res = ast_play_and_wait(chan, "vm-messages"); 08161 } 08162 } else if (!vms->oldmessages && !vms->newmessages) 08163 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08164 return res; 08165 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8264 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.
08265 { 08266 int res = 0; 08267 08268 /* Introduce messages they have */ 08269 if (!res) { 08270 if ((vms->newmessages) || (vms->oldmessages)) { 08271 res = ast_play_and_wait(chan, "vm-youhave"); 08272 } 08273 /* 08274 * The word "shtei" refers to the number 2 in hebrew when performing a count 08275 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08276 * an element, this is one of them. 08277 */ 08278 if (vms->newmessages) { 08279 if (!res) { 08280 if (vms->newmessages == 1) { 08281 res = ast_play_and_wait(chan, "vm-INBOX1"); 08282 } else { 08283 if (vms->newmessages == 2) { 08284 res = ast_play_and_wait(chan, "vm-shtei"); 08285 } else { 08286 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08287 } 08288 res = ast_play_and_wait(chan, "vm-INBOX"); 08289 } 08290 } 08291 if (vms->oldmessages && !res) { 08292 res = ast_play_and_wait(chan, "vm-and"); 08293 if (vms->oldmessages == 1) { 08294 res = ast_play_and_wait(chan, "vm-Old1"); 08295 } else { 08296 if (vms->oldmessages == 2) { 08297 res = ast_play_and_wait(chan, "vm-shtei"); 08298 } else { 08299 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08300 } 08301 res = ast_play_and_wait(chan, "vm-Old"); 08302 } 08303 } 08304 } 08305 if (!res && vms->oldmessages && !vms->newmessages) { 08306 if (!res) { 08307 if (vms->oldmessages == 1) { 08308 res = ast_play_and_wait(chan, "vm-Old1"); 08309 } else { 08310 if (vms->oldmessages == 2) { 08311 res = ast_play_and_wait(chan, "vm-shtei"); 08312 } else { 08313 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08314 } 08315 res = ast_play_and_wait(chan, "vm-Old"); 08316 } 08317 } 08318 } 08319 if (!res) { 08320 if (!vms->oldmessages && !vms->newmessages) { 08321 if (!res) { 08322 res = ast_play_and_wait(chan, "vm-nomessages"); 08323 } 08324 } 08325 } 08326 } 08327 return res; 08328 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8388 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.
08389 { 08390 /* Introduce messages they have */ 08391 int res; 08392 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08393 res = ast_play_and_wait(chan, "vm-no") || 08394 ast_play_and_wait(chan, "vm-message"); 08395 else 08396 res = ast_play_and_wait(chan, "vm-youhave"); 08397 if (!res && vms->newmessages) { 08398 res = (vms->newmessages == 1) ? 08399 ast_play_and_wait(chan, "digits/un") || 08400 ast_play_and_wait(chan, "vm-nuovo") || 08401 ast_play_and_wait(chan, "vm-message") : 08402 /* 2 or more new messages */ 08403 say_and_wait(chan, vms->newmessages, chan->language) || 08404 ast_play_and_wait(chan, "vm-nuovi") || 08405 ast_play_and_wait(chan, "vm-messages"); 08406 if (!res && vms->oldmessages) 08407 res = ast_play_and_wait(chan, "vm-and"); 08408 } 08409 if (!res && vms->oldmessages) { 08410 res = (vms->oldmessages == 1) ? 08411 ast_play_and_wait(chan, "digits/un") || 08412 ast_play_and_wait(chan, "vm-vecchio") || 08413 ast_play_and_wait(chan, "vm-message") : 08414 /* 2 or more old messages */ 08415 say_and_wait(chan, vms->oldmessages, chan->language) || 08416 ast_play_and_wait(chan, "vm-vecchi") || 08417 ast_play_and_wait(chan, "vm-messages"); 08418 } 08419 return res; 08420 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8224 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.
08225 { 08226 int res; 08227 int lastnum = 0; 08228 08229 res = ast_play_and_wait(chan, "vm-youhave"); 08230 08231 if (!res && vms->newmessages) { 08232 lastnum = vms->newmessages; 08233 08234 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08235 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08236 } 08237 08238 if (!res && vms->oldmessages) { 08239 res = ast_play_and_wait(chan, "vm-and"); 08240 } 08241 } 08242 08243 if (!res && vms->oldmessages) { 08244 lastnum = vms->oldmessages; 08245 08246 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08247 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08248 } 08249 } 08250 08251 if (!res) { 08252 if (lastnum == 0) { 08253 res = ast_play_and_wait(chan, "vm-no"); 08254 } 08255 if (!res) { 08256 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08257 } 08258 } 08259 08260 return res; 08261 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8772 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.
08773 { 08774 /* Introduce messages they have */ 08775 int res; 08776 res = ast_play_and_wait(chan, "vm-youhave"); 08777 if (!res) { 08778 if (vms->newmessages) { 08779 res = say_and_wait(chan, vms->newmessages, chan->language); 08780 if (!res) { 08781 if (vms->newmessages == 1) 08782 res = ast_play_and_wait(chan, "vm-INBOXs"); 08783 else 08784 res = ast_play_and_wait(chan, "vm-INBOX"); 08785 } 08786 if (vms->oldmessages && !res) 08787 res = ast_play_and_wait(chan, "vm-and"); 08788 else if (!res) { 08789 if ((vms->newmessages == 1)) 08790 res = ast_play_and_wait(chan, "vm-message"); 08791 else 08792 res = ast_play_and_wait(chan, "vm-messages"); 08793 } 08794 08795 } 08796 if (!res && vms->oldmessages) { 08797 res = say_and_wait(chan, vms->oldmessages, chan->language); 08798 if (!res) { 08799 if (vms->oldmessages == 1) 08800 res = ast_play_and_wait(chan, "vm-Olds"); 08801 else 08802 res = ast_play_and_wait(chan, "vm-Old"); 08803 } 08804 if (!res) { 08805 if (vms->oldmessages == 1) 08806 res = ast_play_and_wait(chan, "vm-message"); 08807 else 08808 res = ast_play_and_wait(chan, "vm-messages"); 08809 } 08810 } 08811 if (!res) { 08812 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08813 res = ast_play_and_wait(chan, "vm-no"); 08814 if (!res) 08815 res = ast_play_and_wait(chan, "vm-messages"); 08816 } 08817 } 08818 } 08819 return res; 08820 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8538 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.
08539 { 08540 /* Introduce messages they have */ 08541 int res; 08542 08543 res = ast_play_and_wait(chan, "vm-youhave"); 08544 if (res) 08545 return res; 08546 08547 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08548 res = ast_play_and_wait(chan, "vm-no"); 08549 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08550 return res; 08551 } 08552 08553 if (vms->newmessages) { 08554 if ((vms->newmessages == 1)) { 08555 res = ast_play_and_wait(chan, "digits/1"); 08556 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08557 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08558 } else { 08559 res = say_and_wait(chan, vms->newmessages, chan->language); 08560 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08561 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08562 } 08563 if (!res && vms->oldmessages) 08564 res = ast_play_and_wait(chan, "vm-and"); 08565 } 08566 if (!res && vms->oldmessages) { 08567 if (vms->oldmessages == 1) { 08568 res = ast_play_and_wait(chan, "digits/1"); 08569 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08570 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08571 } else { 08572 res = say_and_wait(chan, vms->oldmessages, chan->language); 08573 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08574 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08575 } 08576 } 08577 08578 return res; 08579 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8423 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08424 { 08425 /* Introduce messages they have */ 08426 int res; 08427 div_t num; 08428 08429 if (!vms->oldmessages && !vms->newmessages) { 08430 res = ast_play_and_wait(chan, "vm-no"); 08431 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08432 return res; 08433 } else { 08434 res = ast_play_and_wait(chan, "vm-youhave"); 08435 } 08436 08437 if (vms->newmessages) { 08438 num = div(vms->newmessages, 10); 08439 if (vms->newmessages == 1) { 08440 res = ast_play_and_wait(chan, "digits/1-a"); 08441 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08442 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08443 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08444 if (num.rem == 2) { 08445 if (!num.quot) { 08446 res = ast_play_and_wait(chan, "digits/2-ie"); 08447 } else { 08448 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08449 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08450 } 08451 } else { 08452 res = say_and_wait(chan, vms->newmessages, chan->language); 08453 } 08454 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08455 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08456 } else { 08457 res = say_and_wait(chan, vms->newmessages, chan->language); 08458 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08459 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08460 } 08461 if (!res && vms->oldmessages) 08462 res = ast_play_and_wait(chan, "vm-and"); 08463 } 08464 if (!res && vms->oldmessages) { 08465 num = div(vms->oldmessages, 10); 08466 if (vms->oldmessages == 1) { 08467 res = ast_play_and_wait(chan, "digits/1-a"); 08468 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08469 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08470 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08471 if (num.rem == 2) { 08472 if (!num.quot) { 08473 res = ast_play_and_wait(chan, "digits/2-ie"); 08474 } else { 08475 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08476 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08477 } 08478 } else { 08479 res = say_and_wait(chan, vms->oldmessages, chan->language); 08480 } 08481 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08482 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08483 } else { 08484 res = say_and_wait(chan, vms->oldmessages, chan->language); 08485 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08486 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08487 } 08488 } 08489 08490 return res; 08491 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8823 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.
08824 { 08825 /* Introduce messages they have */ 08826 int res; 08827 res = ast_play_and_wait(chan, "vm-youhave"); 08828 if (!res) { 08829 if (vms->newmessages) { 08830 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08831 if (!res) { 08832 if ((vms->newmessages == 1)) { 08833 res = ast_play_and_wait(chan, "vm-message"); 08834 if (!res) 08835 res = ast_play_and_wait(chan, "vm-INBOXs"); 08836 } else { 08837 res = ast_play_and_wait(chan, "vm-messages"); 08838 if (!res) 08839 res = ast_play_and_wait(chan, "vm-INBOX"); 08840 } 08841 } 08842 if (vms->oldmessages && !res) 08843 res = ast_play_and_wait(chan, "vm-and"); 08844 } 08845 if (!res && vms->oldmessages) { 08846 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08847 if (!res) { 08848 if (vms->oldmessages == 1) { 08849 res = ast_play_and_wait(chan, "vm-message"); 08850 if (!res) 08851 res = ast_play_and_wait(chan, "vm-Olds"); 08852 } else { 08853 res = ast_play_and_wait(chan, "vm-messages"); 08854 if (!res) 08855 res = ast_play_and_wait(chan, "vm-Old"); 08856 } 08857 } 08858 } 08859 if (!res) { 08860 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08861 res = ast_play_and_wait(chan, "vm-no"); 08862 if (!res) 08863 res = ast_play_and_wait(chan, "vm-messages"); 08864 } 08865 } 08866 } 08867 return res; 08868 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8684 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.
08684 { 08685 /* Introduce messages they have */ 08686 int res; 08687 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08688 res = ast_play_and_wait(chan, "vm-nomessages"); 08689 return res; 08690 } else { 08691 res = ast_play_and_wait(chan, "vm-youhave"); 08692 } 08693 if (vms->newmessages) { 08694 if (!res) 08695 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08696 if ((vms->newmessages == 1)) { 08697 if (!res) 08698 res = ast_play_and_wait(chan, "vm-message"); 08699 if (!res) 08700 res = ast_play_and_wait(chan, "vm-INBOXs"); 08701 } else { 08702 if (!res) 08703 res = ast_play_and_wait(chan, "vm-messages"); 08704 if (!res) 08705 res = ast_play_and_wait(chan, "vm-INBOX"); 08706 } 08707 if (vms->oldmessages && !res) 08708 res = ast_play_and_wait(chan, "vm-and"); 08709 } 08710 if (vms->oldmessages) { 08711 if (!res) 08712 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08713 if (vms->oldmessages == 1) { 08714 if (!res) 08715 res = ast_play_and_wait(chan, "vm-message"); 08716 if (!res) 08717 res = ast_play_and_wait(chan, "vm-Olds"); 08718 } else { 08719 if (!res) 08720 res = ast_play_and_wait(chan, "vm-messages"); 08721 if (!res) 08722 res = ast_play_and_wait(chan, "vm-Old"); 08723 } 08724 } 08725 return res; 08726 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8494 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.
08495 { 08496 /* Introduce messages they have */ 08497 int res; 08498 08499 res = ast_play_and_wait(chan, "vm-youhave"); 08500 if (res) 08501 return res; 08502 08503 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08504 res = ast_play_and_wait(chan, "vm-no"); 08505 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08506 return res; 08507 } 08508 08509 if (vms->newmessages) { 08510 if ((vms->newmessages == 1)) { 08511 res = ast_play_and_wait(chan, "digits/ett"); 08512 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08513 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08514 } else { 08515 res = say_and_wait(chan, vms->newmessages, chan->language); 08516 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08517 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08518 } 08519 if (!res && vms->oldmessages) 08520 res = ast_play_and_wait(chan, "vm-and"); 08521 } 08522 if (!res && vms->oldmessages) { 08523 if (vms->oldmessages == 1) { 08524 res = ast_play_and_wait(chan, "digits/ett"); 08525 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08526 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08527 } else { 08528 res = say_and_wait(chan, vms->oldmessages, chan->language); 08529 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08530 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08531 } 08532 } 08533 08534 return res; 08535 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8986 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08987 { 08988 int res; 08989 08990 /* Introduce messages they have */ 08991 res = ast_play_and_wait(chan, "vm-youhave"); 08992 if (!res) { 08993 if (vms->newmessages) { 08994 res = say_and_wait(chan, vms->newmessages, chan->language); 08995 if (!res) 08996 res = ast_play_and_wait(chan, "vm-INBOX"); 08997 if (vms->oldmessages && !res) 08998 res = ast_play_and_wait(chan, "vm-and"); 08999 } 09000 if (!res && vms->oldmessages) { 09001 res = say_and_wait(chan, vms->oldmessages, chan->language); 09002 if (!res) 09003 res = ast_play_and_wait(chan, "vm-Old"); 09004 } 09005 if (!res) { 09006 if (!vms->oldmessages && !vms->newmessages) { 09007 res = ast_play_and_wait(chan, "vm-no"); 09008 if (!res) 09009 res = ast_play_and_wait(chan, "vm-message"); 09010 } 09011 } 09012 } 09013 return res; 09014 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8947 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08948 { 08949 int res; 08950 /* Introduce messages they have */ 08951 res = ast_play_and_wait(chan, "vm-you"); 08952 08953 if (!res && vms->newmessages) { 08954 res = ast_play_and_wait(chan, "vm-have"); 08955 if (!res) 08956 res = say_and_wait(chan, vms->newmessages, chan->language); 08957 if (!res) 08958 res = ast_play_and_wait(chan, "vm-tong"); 08959 if (!res) 08960 res = ast_play_and_wait(chan, "vm-INBOX"); 08961 if (vms->oldmessages && !res) 08962 res = ast_play_and_wait(chan, "vm-and"); 08963 else if (!res) 08964 res = ast_play_and_wait(chan, "vm-messages"); 08965 } 08966 if (!res && vms->oldmessages) { 08967 res = ast_play_and_wait(chan, "vm-have"); 08968 if (!res) 08969 res = say_and_wait(chan, vms->oldmessages, chan->language); 08970 if (!res) 08971 res = ast_play_and_wait(chan, "vm-tong"); 08972 if (!res) 08973 res = ast_play_and_wait(chan, "vm-Old"); 08974 if (!res) 08975 res = ast_play_and_wait(chan, "vm-messages"); 08976 } 08977 if (!res && !vms->oldmessages && !vms->newmessages) { 08978 res = ast_play_and_wait(chan, "vm-haveno"); 08979 if (!res) 08980 res = ast_play_and_wait(chan, "vm-messages"); 08981 } 08982 return res; 08983 }
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 3264 of file app_voicemail_imapstorage.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03265 { 03266 switch (ast_lock_path(path)) { 03267 case AST_LOCK_TIMEOUT: 03268 return -1; 03269 default: 03270 return 0; 03271 } 03272 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1666 of file app_voicemail_imapstorage.c.
References my_umask, and VOICEMAIL_FILE_MODE.
01667 { 01668 FILE *p = NULL; 01669 int pfd = mkstemp(template); 01670 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01671 if (pfd > -1) { 01672 p = fdopen(pfd, "w+"); 01673 if (!p) { 01674 close(pfd); 01675 pfd = -1; 01676 } 01677 } 01678 return p; 01679 }
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 9189 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, ext_pass_cmd, maxgreet, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, vm_state::username, vm_change_password(), vm_change_password_shell(), VM_FORCEGREET, VM_FORCENAME, vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, and VM_SPOOL_DIR.
09190 { 09191 int cmd = 0; 09192 int duration = 0; 09193 int tries = 0; 09194 char newpassword[80] = ""; 09195 char newpassword2[80] = ""; 09196 char prefile[PATH_MAX] = ""; 09197 unsigned char buf[256]; 09198 int bytes = 0; 09199 09200 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09201 if (ast_adsi_available(chan)) { 09202 bytes += adsi_logo(buf + bytes); 09203 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09204 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09205 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09206 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09207 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09208 } 09209 09210 /* If forcename is set, have the user record their name */ 09211 if (ast_test_flag(vmu, VM_FORCENAME)) { 09212 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09213 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09214 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09215 if (cmd < 0 || cmd == 't' || cmd == '#') 09216 return cmd; 09217 } 09218 } 09219 09220 /* If forcegreetings is set, have the user record their greetings */ 09221 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09222 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09223 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09224 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09225 if (cmd < 0 || cmd == 't' || cmd == '#') 09226 return cmd; 09227 } 09228 09229 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09230 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09231 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09232 if (cmd < 0 || cmd == 't' || cmd == '#') 09233 return cmd; 09234 } 09235 } 09236 09237 /* 09238 * Change the password last since new users will be able to skip over any steps this one comes before 09239 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09240 */ 09241 for (;;) { 09242 newpassword[1] = '\0'; 09243 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09244 if (cmd == '#') 09245 newpassword[0] = '\0'; 09246 if (cmd < 0 || cmd == 't' || cmd == '#') 09247 return cmd; 09248 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09249 if (cmd < 0 || cmd == 't' || cmd == '#') 09250 return cmd; 09251 cmd = check_password(vmu, newpassword); /* perform password validation */ 09252 if (cmd != 0) { 09253 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09254 cmd = ast_play_and_wait(chan, vm_invalid_password); 09255 } else { 09256 newpassword2[1] = '\0'; 09257 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09258 if (cmd == '#') 09259 newpassword2[0] = '\0'; 09260 if (cmd < 0 || cmd == 't' || cmd == '#') 09261 return cmd; 09262 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09263 if (cmd < 0 || cmd == 't' || cmd == '#') 09264 return cmd; 09265 if (!strcmp(newpassword, newpassword2)) 09266 break; 09267 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09268 cmd = ast_play_and_wait(chan, vm_mismatch); 09269 } 09270 if (++tries == 3) 09271 return -1; 09272 if (cmd != 0) { 09273 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09274 } 09275 } 09276 if (pwdchange & PWDCHANGE_INTERNAL) 09277 vm_change_password(vmu, newpassword); 09278 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09279 vm_change_password_shell(vmu, newpassword); 09280 09281 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09282 cmd = ast_play_and_wait(chan, vm_passchanged); 09283 09284 return cmd; 09285 }
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 9287 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, ext_pass_cmd, ast_vm_user::mailbox, maxgreet, ast_vm_user::password, play_record_review(), pwdchange, PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, RETRIEVE, vm_state::username, vm_change_password(), vm_change_password_shell(), vm_invalid_password, vm_mismatch, vm_newpassword, vm_passchanged, vm_pls_try_again, vm_reenterpassword, VM_SPOOL_DIR, and vm_tempgreeting().
09288 { 09289 int cmd = 0; 09290 int retries = 0; 09291 int duration = 0; 09292 char newpassword[80] = ""; 09293 char newpassword2[80] = ""; 09294 char prefile[PATH_MAX] = ""; 09295 unsigned char buf[256]; 09296 int bytes = 0; 09297 09298 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09299 if (ast_adsi_available(chan)) { 09300 bytes += adsi_logo(buf + bytes); 09301 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09302 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09303 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09304 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09305 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09306 } 09307 while ((cmd >= 0) && (cmd != 't')) { 09308 if (cmd) 09309 retries = 0; 09310 switch (cmd) { 09311 case '1': /* Record your unavailable message */ 09312 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09313 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09314 break; 09315 case '2': /* Record your busy message */ 09316 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09317 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09318 break; 09319 case '3': /* Record greeting */ 09320 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09321 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09322 break; 09323 case '4': /* manage the temporary greeting */ 09324 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09325 break; 09326 case '5': /* change password */ 09327 if (vmu->password[0] == '-') { 09328 cmd = ast_play_and_wait(chan, "vm-no"); 09329 break; 09330 } 09331 newpassword[1] = '\0'; 09332 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09333 if (cmd == '#') 09334 newpassword[0] = '\0'; 09335 else { 09336 if (cmd < 0) 09337 break; 09338 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09339 break; 09340 } 09341 } 09342 cmd = check_password(vmu, newpassword); /* perform password validation */ 09343 if (cmd != 0) { 09344 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09345 cmd = ast_play_and_wait(chan, vm_invalid_password); 09346 if (!cmd) { 09347 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09348 } 09349 break; 09350 } 09351 newpassword2[1] = '\0'; 09352 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09353 if (cmd == '#') 09354 newpassword2[0] = '\0'; 09355 else { 09356 if (cmd < 0) 09357 break; 09358 09359 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09360 break; 09361 } 09362 } 09363 if (strcmp(newpassword, newpassword2)) { 09364 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09365 cmd = ast_play_and_wait(chan, vm_mismatch); 09366 if (!cmd) { 09367 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09368 } 09369 break; 09370 } 09371 09372 if (pwdchange & PWDCHANGE_INTERNAL) { 09373 vm_change_password(vmu, newpassword); 09374 } 09375 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09376 vm_change_password_shell(vmu, newpassword); 09377 } 09378 09379 ast_debug(1, "User %s set password to %s of length %d\n", 09380 vms->username, newpassword, (int) strlen(newpassword)); 09381 cmd = ast_play_and_wait(chan, vm_passchanged); 09382 break; 09383 case '*': 09384 cmd = 't'; 09385 break; 09386 default: 09387 cmd = 0; 09388 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09389 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09390 if (ast_fileexists(prefile, NULL, NULL)) { 09391 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09392 } 09393 DISPOSE(prefile, -1); 09394 if (!cmd) { 09395 cmd = ast_play_and_wait(chan, "vm-options"); 09396 } 09397 if (!cmd) { 09398 cmd = ast_waitfordigit(chan, 6000); 09399 } 09400 if (!cmd) { 09401 retries++; 09402 } 09403 if (retries > 3) { 09404 cmd = 't'; 09405 } 09406 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09407 } 09408 } 09409 if (cmd == 't') 09410 cmd = 0; 09411 return cmd; 09412 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8093 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().
08094 { 08095 int cmd; 08096 08097 if ( !strncasecmp(chan->language, "it", 2) || 08098 !strncasecmp(chan->language, "es", 2) || 08099 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08100 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08101 return cmd ? cmd : ast_play_and_wait(chan, box); 08102 } else if (!strncasecmp(chan->language, "gr", 2)) { 08103 return vm_play_folder_name_gr(chan, box); 08104 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08105 return ast_play_and_wait(chan, box); 08106 } else if (!strncasecmp(chan->language, "pl", 2)) { 08107 return vm_play_folder_name_pl(chan, box); 08108 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08109 return vm_play_folder_name_ua(chan, box); 08110 } else if (!strncasecmp(chan->language, "vi", 2)) { 08111 return ast_play_and_wait(chan, box); 08112 } else { /* Default English */ 08113 cmd = ast_play_and_wait(chan, box); 08114 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08115 } 08116 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8046 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
08047 { 08048 int cmd; 08049 char *buf; 08050 08051 buf = alloca(strlen(box) + 2); 08052 strcpy(buf, box); 08053 strcat(buf, "s"); 08054 08055 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08056 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08057 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08058 } else { 08059 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08060 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08061 } 08062 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8064 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
08065 { 08066 int cmd; 08067 08068 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08069 if (!strcasecmp(box, "vm-INBOX")) 08070 cmd = ast_play_and_wait(chan, "vm-new-e"); 08071 else 08072 cmd = ast_play_and_wait(chan, "vm-old-e"); 08073 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08074 } else { 08075 cmd = ast_play_and_wait(chan, "vm-messages"); 08076 return cmd ? cmd : ast_play_and_wait(chan, box); 08077 } 08078 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8080 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
08081 { 08082 int cmd; 08083 08084 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08085 cmd = ast_play_and_wait(chan, "vm-messages"); 08086 return cmd ? cmd : ast_play_and_wait(chan, box); 08087 } else { 08088 cmd = ast_play_and_wait(chan, box); 08089 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08090 } 08091 }
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'.
chan | ||
vmu | ||
vms | ||
fmtc | ||
record_gain | This 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. |
Definition at line 9430 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, maxgreet, play_record_review(), RETRIEVE, vm_state::username, and VM_SPOOL_DIR.
09431 { 09432 int cmd = 0; 09433 int retries = 0; 09434 int duration = 0; 09435 char prefile[PATH_MAX] = ""; 09436 unsigned char buf[256]; 09437 int bytes = 0; 09438 09439 if (ast_adsi_available(chan)) { 09440 bytes += adsi_logo(buf + bytes); 09441 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09442 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09443 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09444 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09445 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09446 } 09447 09448 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09449 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09450 while ((cmd >= 0) && (cmd != 't')) { 09451 if (cmd) 09452 retries = 0; 09453 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09454 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09455 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09456 cmd = 't'; 09457 } else { 09458 switch (cmd) { 09459 case '1': 09460 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09461 break; 09462 case '2': 09463 DELETE(prefile, -1, prefile, vmu); 09464 ast_play_and_wait(chan, "vm-tempremoved"); 09465 cmd = 't'; 09466 break; 09467 case '*': 09468 cmd = 't'; 09469 break; 09470 default: 09471 cmd = ast_play_and_wait(chan, 09472 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09473 "vm-tempgreeting2" : "vm-tempgreeting"); 09474 if (!cmd) { 09475 cmd = ast_waitfordigit(chan, 6000); 09476 } 09477 if (!cmd) { 09478 retries++; 09479 } 09480 if (retries > 3) { 09481 cmd = 't'; 09482 } 09483 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09484 } 09485 } 09486 DISPOSE(prefile, -1); 09487 } 09488 if (cmd == 't') 09489 cmd = 0; 09490 return cmd; 09491 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11393 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_vm_user::list, user, and vm_users_data_provider_get_helper().
11395 { 11396 struct ast_vm_user *user; 11397 11398 AST_LIST_LOCK(&users); 11399 AST_LIST_TRAVERSE(&users, user, list) { 11400 vm_users_data_provider_get_helper(search, data_root, user); 11401 } 11402 AST_LIST_UNLOCK(&users); 11403 11404 return 0; 11405 }
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 11346 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, inboxcount2(), vm_zone::list, vm_zone::name, and user.
11348 { 11349 struct ast_data *data_user, *data_zone; 11350 struct ast_data *data_state; 11351 struct vm_zone *zone = NULL; 11352 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11353 char ext_context[256] = ""; 11354 11355 data_user = ast_data_add_node(data_root, "user"); 11356 if (!data_user) { 11357 return -1; 11358 } 11359 11360 ast_data_add_structure(ast_vm_user, data_user, user); 11361 11362 AST_LIST_LOCK(&zones); 11363 AST_LIST_TRAVERSE(&zones, zone, list) { 11364 if (!strcmp(zone->name, user->zonetag)) { 11365 break; 11366 } 11367 } 11368 AST_LIST_UNLOCK(&zones); 11369 11370 /* state */ 11371 data_state = ast_data_add_node(data_user, "state"); 11372 if (!data_state) { 11373 return -1; 11374 } 11375 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11376 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11377 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11378 ast_data_add_int(data_state, "newmsg", newmsg); 11379 ast_data_add_int(data_state, "oldmsg", oldmsg); 11380 11381 if (zone) { 11382 data_zone = ast_data_add_node(data_user, "zone"); 11383 ast_data_add_structure(vm_zone, data_zone, zone); 11384 } 11385 11386 if (!ast_data_search_match(search, data_user)) { 11387 ast_data_remove_node(data_root, data_user); 11388 } 11389 11390 return 0; 11391 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11032 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_channel::context, ast_vm_user::context, pbx_builtin_setvar_helper(), strsep(), and vm_authenticate().
11033 { 11034 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11035 struct ast_vm_user vmus; 11036 char *options = NULL; 11037 int silent = 0, skipuser = 0; 11038 int res = -1; 11039 11040 if (data) { 11041 s = ast_strdupa(data); 11042 user = strsep(&s, ","); 11043 options = strsep(&s, ","); 11044 if (user) { 11045 s = user; 11046 user = strsep(&s, "@"); 11047 context = strsep(&s, ""); 11048 if (!ast_strlen_zero(user)) 11049 skipuser++; 11050 ast_copy_string(mailbox, user, sizeof(mailbox)); 11051 } 11052 } 11053 11054 if (options) { 11055 silent = (strchr(options, 's')) != NULL; 11056 } 11057 11058 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11059 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11060 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11061 ast_play_and_wait(chan, "auth-thankyou"); 11062 res = 0; 11063 } else if (mailbox[0] == '*') { 11064 /* user entered '*' */ 11065 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11066 res = 0; /* prevent hangup */ 11067 } 11068 } 11069 11070 return res; 11071 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12550 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(), ast_channel::language, LOG_WARNING, and sayname().
12551 { 12552 char *context; 12553 char *args_copy; 12554 int res; 12555 12556 if (ast_strlen_zero(data)) { 12557 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12558 return -1; 12559 } 12560 12561 args_copy = ast_strdupa(data); 12562 if ((context = strchr(args_copy, '@'))) { 12563 *context++ = '\0'; 12564 } else { 12565 context = "default"; 12566 } 12567 12568 if ((res = sayname(chan, args_copy, context) < 0)) { 12569 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12570 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12571 if (!res) { 12572 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12573 } 12574 } 12575 12576 return res; 12577 }
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.
Definition at line 4419 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.
04420 { 04421 const struct vm_zone *z = NULL; 04422 struct timeval t = ast_tvnow(); 04423 04424 /* Does this user have a timezone specified? */ 04425 if (!ast_strlen_zero(vmu->zonetag)) { 04426 /* Find the zone in the list */ 04427 AST_LIST_LOCK(&zones); 04428 AST_LIST_TRAVERSE(&zones, z, list) { 04429 if (!strcmp(z->name, vmu->zonetag)) 04430 break; 04431 } 04432 AST_LIST_UNLOCK(&zones); 04433 } 04434 ast_localtime(&t, tm, z ? z->timezone : NULL); 04435 return tm; 04436 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7454 of file app_voicemail_imapstorage.c.
References ast_control_streamfile(), ast_test_suite_event_notify, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, and skipms.
07455 { 07456 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07457 return ast_control_streamfile(chan, file, listen_control_forward_key, listen_control_reverse_key, listen_control_stop_key, listen_control_pause_key, listen_control_restart_key, skipms, NULL); 07458 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7446 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, ast_log(), and ast_stream_and_wait().
07447 { 07448 int res; 07449 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07450 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07451 return res; 07452 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12524 of file app_voicemail_imapstorage.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
12524 { 12525 struct ast_config *conf; 12526 struct ast_category *cat; 12527 struct ast_variable *var; 12528 12529 if (!(conf=ast_config_new())) { 12530 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12531 return -1; 12532 } 12533 if (!(cat=ast_category_new("general","",1))) { 12534 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12535 return -1; 12536 } 12537 if (!(var=ast_variable_new("password",password,""))) { 12538 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12539 return -1; 12540 } 12541 ast_category_append(conf,cat); 12542 ast_variable_append(cat,var); 12543 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12544 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12545 return -1; 12546 } 12547 return 0; 12548 }
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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13629 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.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13629 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:
{ { .handler = handle_voicemail_show_users , .summary = "List defined voicemail boxes" ,__VA_ARGS__ }, { .handler = handle_voicemail_show_zones , .summary = "List zone message formats" ,__VA_ARGS__ }, { .handler = handle_voicemail_reload , .summary = "Reload voicemail configuration" ,__VA_ARGS__ }, }
Definition at line 11269 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.
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.
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", .read = acf_mailbox_exists, }
Definition at line 11027 of file app_voicemail_imapstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1702 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.
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.
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 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.
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.
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.
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.
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.
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.
struct ast_data_entry vm_data_providers[] [static] |
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:
{ .version = AST_DATA_HANDLER_VERSION, .get = vm_users_data_provider_get }
Definition at line 11407 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.
int vmminsecs [static] |
Definition at line 804 of file app_voicemail_imapstorage.c.
double volgain [static] |
Definition at line 803 of file app_voicemail_imapstorage.c.
char zonetag[80] [static] |
Definition at line 792 of file app_voicemail_imapstorage.c.