#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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } |
static char * | addesc = "Comedian Mail" |
static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
static int | adsiver = 1 |
static char * | app = "VoiceMail" |
static char * | app2 = "VoiceMailMain" |
static char * | app3 = "MailboxExists" |
static char * | app4 = "VMAuthenticate" |
static struct ast_module_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 11341 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 11369 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 5385 of file app_voicemail_imapstorage.c.
References ast_strlen_zero(), and VM_SPOOL_DIR.
05386 { 05387 DIR *dir; 05388 struct dirent *de; 05389 char fn[256]; 05390 int ret = 0; 05391 05392 /* If no mailbox, return immediately */ 05393 if (ast_strlen_zero(mailbox)) 05394 return 0; 05395 05396 if (ast_strlen_zero(folder)) 05397 folder = "INBOX"; 05398 if (ast_strlen_zero(context)) 05399 context = "default"; 05400 05401 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05402 05403 if (!(dir = opendir(fn))) 05404 return 0; 05405 05406 while ((de = readdir(dir))) { 05407 if (!strncasecmp(de->d_name, "msg", 3)) { 05408 if (shortcircuit) { 05409 ret = 1; 05410 break; 05411 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05412 ret++; 05413 } 05414 } 05415 } 05416 05417 closedir(dir); 05418 05419 return ret; 05420 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13688 of file app_voicemail_imapstorage.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13688 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 11043 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().
11044 { 11045 struct ast_vm_user svm; 11046 AST_DECLARE_APP_ARGS(arg, 11047 AST_APP_ARG(mbox); 11048 AST_APP_ARG(context); 11049 ); 11050 11051 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11052 11053 if (ast_strlen_zero(arg.mbox)) { 11054 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 11055 return -1; 11056 } 11057 11058 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 11059 return 0; 11060 }
static int actual_load_config | ( | int | reload, | |
struct ast_config * | cfg, | |||
struct ast_config * | ucfg | |||
) | [static] |
Definition at line 11879 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.
11880 { 11881 struct ast_vm_user *current; 11882 char *cat; 11883 struct ast_variable *var; 11884 const char *val; 11885 char *q, *stringp, *tmp; 11886 int x; 11887 int tmpadsi[4]; 11888 char secretfn[PATH_MAX] = ""; 11889 11890 #ifdef IMAP_STORAGE 11891 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11892 #endif 11893 /* set audio control prompts */ 11894 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11895 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11896 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11897 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11898 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11899 11900 /* Free all the users structure */ 11901 free_vm_users(); 11902 11903 /* Free all the zones structure */ 11904 free_vm_zones(); 11905 11906 AST_LIST_LOCK(&users); 11907 11908 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11909 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11910 11911 if (cfg) { 11912 /* General settings */ 11913 11914 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11915 val = "default"; 11916 ast_copy_string(userscontext, val, sizeof(userscontext)); 11917 /* Attach voice message to mail message ? */ 11918 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11919 val = "yes"; 11920 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11921 11922 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11923 val = "no"; 11924 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11925 11926 volgain = 0.0; 11927 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11928 sscanf(val, "%30lf", &volgain); 11929 11930 #ifdef ODBC_STORAGE 11931 strcpy(odbc_database, "asterisk"); 11932 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11933 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11934 } 11935 strcpy(odbc_table, "voicemessages"); 11936 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11937 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11938 } 11939 #endif 11940 /* Mail command */ 11941 strcpy(mailcmd, SENDMAIL); 11942 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11943 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11944 11945 maxsilence = 0; 11946 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11947 maxsilence = atoi(val); 11948 if (maxsilence > 0) 11949 maxsilence *= 1000; 11950 } 11951 11952 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11953 maxmsg = MAXMSG; 11954 } else { 11955 maxmsg = atoi(val); 11956 if (maxmsg < 0) { 11957 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11958 maxmsg = MAXMSG; 11959 } else if (maxmsg > MAXMSGLIMIT) { 11960 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11961 maxmsg = MAXMSGLIMIT; 11962 } 11963 } 11964 11965 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11966 maxdeletedmsg = 0; 11967 } else { 11968 if (sscanf(val, "%30d", &x) == 1) 11969 maxdeletedmsg = x; 11970 else if (ast_true(val)) 11971 maxdeletedmsg = MAXMSG; 11972 else 11973 maxdeletedmsg = 0; 11974 11975 if (maxdeletedmsg < 0) { 11976 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11977 maxdeletedmsg = MAXMSG; 11978 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11979 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11980 maxdeletedmsg = MAXMSGLIMIT; 11981 } 11982 } 11983 11984 /* Load date format config for voicemail mail */ 11985 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11986 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11987 } 11988 11989 /* Load date format config for voicemail pager mail */ 11990 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11991 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11992 } 11993 11994 /* External password changing command */ 11995 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11996 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11997 pwdchange = PWDCHANGE_EXTERNAL; 11998 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11999 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 12000 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 12001 } 12002 12003 /* External password validation command */ 12004 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 12005 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 12006 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 12007 } 12008 12009 #ifdef IMAP_STORAGE 12010 /* IMAP server address */ 12011 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 12012 ast_copy_string(imapserver, val, sizeof(imapserver)); 12013 } else { 12014 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 12015 } 12016 /* IMAP server port */ 12017 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 12018 ast_copy_string(imapport, val, sizeof(imapport)); 12019 } else { 12020 ast_copy_string(imapport, "143", sizeof(imapport)); 12021 } 12022 /* IMAP server flags */ 12023 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 12024 ast_copy_string(imapflags, val, sizeof(imapflags)); 12025 } 12026 /* IMAP server master username */ 12027 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 12028 ast_copy_string(authuser, val, sizeof(authuser)); 12029 } 12030 /* IMAP server master password */ 12031 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 12032 ast_copy_string(authpassword, val, sizeof(authpassword)); 12033 } 12034 /* Expunge on exit */ 12035 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 12036 if (ast_false(val)) 12037 expungeonhangup = 0; 12038 else 12039 expungeonhangup = 1; 12040 } else { 12041 expungeonhangup = 1; 12042 } 12043 /* IMAP voicemail folder */ 12044 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 12045 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 12046 } else { 12047 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 12048 } 12049 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 12050 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 12051 } 12052 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 12053 imapgreetings = ast_true(val); 12054 } else { 12055 imapgreetings = 0; 12056 } 12057 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 12058 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12059 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 12060 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 12061 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 12062 } else { 12063 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 12064 } 12065 12066 /* There is some very unorthodox casting done here. This is due 12067 * to the way c-client handles the argument passed in. It expects a 12068 * void pointer and casts the pointer directly to a long without 12069 * first dereferencing it. */ 12070 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 12071 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 12072 } else { 12073 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 12074 } 12075 12076 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 12077 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 12078 } else { 12079 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 12080 } 12081 12082 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 12083 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 12084 } else { 12085 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 12086 } 12087 12088 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 12089 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 12090 } else { 12091 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 12092 } 12093 12094 /* Increment configuration version */ 12095 imapversion++; 12096 #endif 12097 /* External voicemail notify application */ 12098 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 12099 ast_copy_string(externnotify, val, sizeof(externnotify)); 12100 ast_debug(1, "found externnotify: %s\n", externnotify); 12101 } else { 12102 externnotify[0] = '\0'; 12103 } 12104 12105 /* SMDI voicemail notification */ 12106 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 12107 ast_debug(1, "Enabled SMDI voicemail notification\n"); 12108 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 12109 smdi_iface = ast_smdi_interface_find(val); 12110 } else { 12111 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 12112 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 12113 } 12114 if (!smdi_iface) { 12115 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 12116 } 12117 } 12118 12119 /* Silence treshold */ 12120 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 12121 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 12122 silencethreshold = atoi(val); 12123 12124 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 12125 val = ASTERISK_USERNAME; 12126 ast_copy_string(serveremail, val, sizeof(serveremail)); 12127 12128 vmmaxsecs = 0; 12129 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 12130 if (sscanf(val, "%30d", &x) == 1) { 12131 vmmaxsecs = x; 12132 } else { 12133 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12134 } 12135 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 12136 static int maxmessage_deprecate = 0; 12137 if (maxmessage_deprecate == 0) { 12138 maxmessage_deprecate = 1; 12139 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 12140 } 12141 if (sscanf(val, "%30d", &x) == 1) { 12142 vmmaxsecs = x; 12143 } else { 12144 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 12145 } 12146 } 12147 12148 vmminsecs = 0; 12149 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 12150 if (sscanf(val, "%30d", &x) == 1) { 12151 vmminsecs = x; 12152 if (maxsilence / 1000 >= vmminsecs) { 12153 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 12154 } 12155 } else { 12156 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12157 } 12158 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 12159 static int maxmessage_deprecate = 0; 12160 if (maxmessage_deprecate == 0) { 12161 maxmessage_deprecate = 1; 12162 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 12163 } 12164 if (sscanf(val, "%30d", &x) == 1) { 12165 vmminsecs = x; 12166 if (maxsilence / 1000 >= vmminsecs) { 12167 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 12168 } 12169 } else { 12170 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 12171 } 12172 } 12173 12174 val = ast_variable_retrieve(cfg, "general", "format"); 12175 if (!val) { 12176 val = "wav"; 12177 } else { 12178 tmp = ast_strdupa(val); 12179 val = ast_format_str_reduce(tmp); 12180 if (!val) { 12181 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 12182 val = "wav"; 12183 } 12184 } 12185 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 12186 12187 skipms = 3000; 12188 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 12189 if (sscanf(val, "%30d", &x) == 1) { 12190 maxgreet = x; 12191 } else { 12192 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 12193 } 12194 } 12195 12196 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 12197 if (sscanf(val, "%30d", &x) == 1) { 12198 skipms = x; 12199 } else { 12200 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 12201 } 12202 } 12203 12204 maxlogins = 3; 12205 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 12206 if (sscanf(val, "%30d", &x) == 1) { 12207 maxlogins = x; 12208 } else { 12209 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 12210 } 12211 } 12212 12213 minpassword = MINPASSWORD; 12214 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 12215 if (sscanf(val, "%30d", &x) == 1) { 12216 minpassword = x; 12217 } else { 12218 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 12219 } 12220 } 12221 12222 /* Force new user to record name ? */ 12223 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 12224 val = "no"; 12225 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 12226 12227 /* Force new user to record greetings ? */ 12228 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 12229 val = "no"; 12230 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 12231 12232 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 12233 ast_debug(1, "VM_CID Internal context string: %s\n", val); 12234 stringp = ast_strdupa(val); 12235 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 12236 if (!ast_strlen_zero(stringp)) { 12237 q = strsep(&stringp, ","); 12238 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 12239 q++; 12240 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 12241 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 12242 } else { 12243 cidinternalcontexts[x][0] = '\0'; 12244 } 12245 } 12246 } 12247 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 12248 ast_debug(1, "VM Review Option disabled globally\n"); 12249 val = "no"; 12250 } 12251 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 12252 12253 /* Temporary greeting reminder */ 12254 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 12255 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 12256 val = "no"; 12257 } else { 12258 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 12259 } 12260 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 12261 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 12262 ast_debug(1, "VM next message wrap disabled globally\n"); 12263 val = "no"; 12264 } 12265 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 12266 12267 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 12268 ast_debug(1, "VM Operator break disabled globally\n"); 12269 val = "no"; 12270 } 12271 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 12272 12273 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 12274 ast_debug(1, "VM CID Info before msg disabled globally\n"); 12275 val = "no"; 12276 } 12277 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 12278 12279 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 12280 ast_debug(1, "Send Voicemail msg disabled globally\n"); 12281 val = "no"; 12282 } 12283 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 12284 12285 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 12286 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 12287 val = "yes"; 12288 } 12289 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 12290 12291 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 12292 ast_debug(1, "Move Heard enabled globally\n"); 12293 val = "yes"; 12294 } 12295 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 12296 12297 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 12298 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 12299 val = "no"; 12300 } 12301 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 12302 12303 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 12304 ast_debug(1, "Duration info before msg enabled globally\n"); 12305 val = "yes"; 12306 } 12307 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 12308 12309 saydurationminfo = 2; 12310 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 12311 if (sscanf(val, "%30d", &x) == 1) { 12312 saydurationminfo = x; 12313 } else { 12314 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 12315 } 12316 } 12317 12318 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 12319 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 12320 val = "no"; 12321 } 12322 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 12323 12324 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 12325 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 12326 ast_debug(1, "found dialout context: %s\n", dialcontext); 12327 } else { 12328 dialcontext[0] = '\0'; 12329 } 12330 12331 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 12332 ast_copy_string(callcontext, val, sizeof(callcontext)); 12333 ast_debug(1, "found callback context: %s\n", callcontext); 12334 } else { 12335 callcontext[0] = '\0'; 12336 } 12337 12338 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12339 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12340 ast_debug(1, "found operator context: %s\n", exitcontext); 12341 } else { 12342 exitcontext[0] = '\0'; 12343 } 12344 12345 /* load password sounds configuration */ 12346 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12347 ast_copy_string(vm_password, val, sizeof(vm_password)); 12348 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12349 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12350 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12351 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12352 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12353 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12354 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12355 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12356 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12357 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12358 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12359 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12360 } 12361 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 12362 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 12363 } 12364 /* load configurable audio prompts */ 12365 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12366 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12367 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12368 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12369 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12370 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12371 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12372 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12373 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12374 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12375 12376 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12377 val = "no"; 12378 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12379 12380 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12381 val = "voicemail.conf"; 12382 } 12383 if (!(strcmp(val, "spooldir"))) { 12384 passwordlocation = OPT_PWLOC_SPOOLDIR; 12385 } else { 12386 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12387 } 12388 12389 poll_freq = DEFAULT_POLL_FREQ; 12390 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12391 if (sscanf(val, "%30u", &poll_freq) != 1) { 12392 poll_freq = DEFAULT_POLL_FREQ; 12393 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12394 } 12395 } 12396 12397 poll_mailboxes = 0; 12398 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12399 poll_mailboxes = ast_true(val); 12400 12401 memset(fromstring, 0, sizeof(fromstring)); 12402 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12403 strcpy(charset, "ISO-8859-1"); 12404 if (emailbody) { 12405 ast_free(emailbody); 12406 emailbody = NULL; 12407 } 12408 if (emailsubject) { 12409 ast_free(emailsubject); 12410 emailsubject = NULL; 12411 } 12412 if (pagerbody) { 12413 ast_free(pagerbody); 12414 pagerbody = NULL; 12415 } 12416 if (pagersubject) { 12417 ast_free(pagersubject); 12418 pagersubject = NULL; 12419 } 12420 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12421 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12422 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12423 ast_copy_string(fromstring, val, sizeof(fromstring)); 12424 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12425 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12426 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12427 ast_copy_string(charset, val, sizeof(charset)); 12428 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12429 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12430 for (x = 0; x < 4; x++) { 12431 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12432 } 12433 } 12434 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12435 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12436 for (x = 0; x < 4; x++) { 12437 memcpy(&adsisec[x], &tmpadsi[x], 1); 12438 } 12439 } 12440 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12441 if (atoi(val)) { 12442 adsiver = atoi(val); 12443 } 12444 } 12445 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12446 ast_copy_string(zonetag, val, sizeof(zonetag)); 12447 } 12448 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12449 ast_copy_string(locale, val, sizeof(locale)); 12450 } 12451 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12452 emailsubject = ast_strdup(substitute_escapes(val)); 12453 } 12454 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12455 emailbody = ast_strdup(substitute_escapes(val)); 12456 } 12457 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12458 pagersubject = ast_strdup(substitute_escapes(val)); 12459 } 12460 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12461 pagerbody = ast_strdup(substitute_escapes(val)); 12462 } 12463 12464 /* load mailboxes from users.conf */ 12465 if (ucfg) { 12466 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12467 if (!strcasecmp(cat, "general")) { 12468 continue; 12469 } 12470 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12471 continue; 12472 if ((current = find_or_create(userscontext, cat))) { 12473 populate_defaults(current); 12474 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12475 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12476 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12477 current->passwordlocation = OPT_PWLOC_USERSCONF; 12478 } 12479 12480 switch (current->passwordlocation) { 12481 case OPT_PWLOC_SPOOLDIR: 12482 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12483 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12484 } 12485 } 12486 } 12487 } 12488 12489 /* load mailboxes from voicemail.conf */ 12490 cat = ast_category_browse(cfg, NULL); 12491 while (cat) { 12492 if (strcasecmp(cat, "general")) { 12493 var = ast_variable_browse(cfg, cat); 12494 if (strcasecmp(cat, "zonemessages")) { 12495 /* Process mailboxes in this context */ 12496 while (var) { 12497 append_mailbox(cat, var->name, var->value); 12498 var = var->next; 12499 } 12500 } else { 12501 /* Timezones in this context */ 12502 while (var) { 12503 struct vm_zone *z; 12504 if ((z = ast_malloc(sizeof(*z)))) { 12505 char *msg_format, *tzone; 12506 msg_format = ast_strdupa(var->value); 12507 tzone = strsep(&msg_format, "|,"); 12508 if (msg_format) { 12509 ast_copy_string(z->name, var->name, sizeof(z->name)); 12510 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12511 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12512 AST_LIST_LOCK(&zones); 12513 AST_LIST_INSERT_HEAD(&zones, z, list); 12514 AST_LIST_UNLOCK(&zones); 12515 } else { 12516 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12517 ast_free(z); 12518 } 12519 } else { 12520 AST_LIST_UNLOCK(&users); 12521 return -1; 12522 } 12523 var = var->next; 12524 } 12525 } 12526 } 12527 cat = ast_category_browse(cfg, cat); 12528 } 12529 12530 AST_LIST_UNLOCK(&users); 12531 12532 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12533 start_poll_thread(); 12534 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12535 stop_poll_thread();; 12536 12537 return 0; 12538 } else { 12539 AST_LIST_UNLOCK(&users); 12540 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12541 return 0; 12542 } 12543 }
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 4799 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.
04800 { 04801 char tmpdir[256], newtmp[256]; 04802 char fname[256]; 04803 char tmpcmd[256]; 04804 int tmpfd = -1; 04805 int soxstatus = 0; 04806 04807 /* Eww. We want formats to tell us their own MIME type */ 04808 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04809 04810 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04811 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04812 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04813 tmpfd = mkstemp(newtmp); 04814 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04815 ast_debug(3, "newtmp: %s\n", newtmp); 04816 if (tmpfd > -1) { 04817 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04818 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04819 attach = newtmp; 04820 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04821 } else { 04822 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04823 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04824 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04825 } 04826 } 04827 } 04828 fprintf(p, "--%s" ENDL, bound); 04829 if (msgnum > -1) 04830 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04831 else 04832 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04833 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04834 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04835 if (msgnum > -1) 04836 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04837 else 04838 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04839 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04840 base_encode(fname, p); 04841 if (last) 04842 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04843 if (tmpfd > -1) { 04844 if (soxstatus == 0) { 04845 unlink(fname); 04846 } 04847 close(tmpfd); 04848 unlink(newtmp); 04849 } 04850 return 0; 04851 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6405 of file app_voicemail_imapstorage.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), and ast_log().
06406 { 06407 int x; 06408 if (!ast_adsi_available(chan)) 06409 return; 06410 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06411 if (x < 0) 06412 return; 06413 if (!x) { 06414 if (adsi_load_vmail(chan, useadsi)) { 06415 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06416 return; 06417 } 06418 } else 06419 *useadsi = 1; 06420 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6600 of file app_voicemail_imapstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
06601 { 06602 int bytes = 0; 06603 unsigned char buf[256]; 06604 unsigned char keys[8]; 06605 06606 int x; 06607 06608 if (!ast_adsi_available(chan)) 06609 return; 06610 06611 /* New meaning for keys */ 06612 for (x = 0; x < 5; x++) 06613 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06614 06615 keys[6] = 0x0; 06616 keys[7] = 0x0; 06617 06618 if (!vms->curmsg) { 06619 /* No prev key, provide "Folder" instead */ 06620 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06621 } 06622 if (vms->curmsg >= vms->lastmsg) { 06623 /* If last message ... */ 06624 if (vms->curmsg) { 06625 /* but not only message, provide "Folder" instead */ 06626 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06627 } else { 06628 /* Otherwise if only message, leave blank */ 06629 keys[3] = 1; 06630 } 06631 } 06632 06633 /* If deleted, show "undeleted" */ 06634 #ifdef IMAP_STORAGE 06635 ast_mutex_lock(&vms->lock); 06636 #endif 06637 if (vms->deleted[vms->curmsg]) { 06638 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06639 } 06640 #ifdef IMAP_STORAGE 06641 ast_mutex_unlock(&vms->lock); 06642 #endif 06643 06644 /* Except "Exit" */ 06645 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06646 bytes += ast_adsi_set_keys(buf + bytes, keys); 06647 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06648 06649 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06650 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6470 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().
06471 { 06472 unsigned char buf[256]; 06473 int bytes = 0; 06474 unsigned char keys[8]; 06475 int x, y; 06476 06477 if (!ast_adsi_available(chan)) 06478 return; 06479 06480 for (x = 0; x < 5; x++) { 06481 y = ADSI_KEY_APPS + 12 + start + x; 06482 if (y > ADSI_KEY_APPS + 12 + 4) 06483 y = 0; 06484 keys[x] = ADSI_KEY_SKT | y; 06485 } 06486 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06487 keys[6] = 0; 06488 keys[7] = 0; 06489 06490 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06491 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06492 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06493 bytes += ast_adsi_set_keys(buf + bytes, keys); 06494 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06495 06496 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06497 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6755 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().
06756 { 06757 unsigned char buf[256]; 06758 int bytes = 0; 06759 06760 if (!ast_adsi_available(chan)) 06761 return; 06762 bytes += adsi_logo(buf + bytes); 06763 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06764 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06765 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06766 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06767 06768 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06769 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6276 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().
06277 { 06278 unsigned char buf[256]; 06279 int bytes = 0; 06280 int x; 06281 char num[5]; 06282 06283 *useadsi = 0; 06284 bytes += ast_adsi_data_mode(buf + bytes); 06285 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06286 06287 bytes = 0; 06288 bytes += adsi_logo(buf); 06289 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06290 #ifdef DISPLAY 06291 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06292 #endif 06293 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06294 bytes += ast_adsi_data_mode(buf + bytes); 06295 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06296 06297 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06298 bytes = 0; 06299 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06300 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06301 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06302 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06303 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06304 return 0; 06305 } 06306 06307 #ifdef DISPLAY 06308 /* Add a dot */ 06309 bytes = 0; 06310 bytes += ast_adsi_logo(buf); 06311 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06312 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06313 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06314 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06315 #endif 06316 bytes = 0; 06317 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06318 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06319 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06320 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06321 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06322 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06323 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06324 06325 #ifdef DISPLAY 06326 /* Add another dot */ 06327 bytes = 0; 06328 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06329 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06330 06331 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06332 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06333 #endif 06334 06335 bytes = 0; 06336 /* These buttons we load but don't use yet */ 06337 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06338 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06339 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06340 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06341 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06342 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06343 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06344 06345 #ifdef DISPLAY 06346 /* Add another dot */ 06347 bytes = 0; 06348 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06349 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06350 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06351 #endif 06352 06353 bytes = 0; 06354 for (x = 0; x < 5; x++) { 06355 snprintf(num, sizeof(num), "%d", x); 06356 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06357 } 06358 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06359 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06360 06361 #ifdef DISPLAY 06362 /* Add another dot */ 06363 bytes = 0; 06364 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06365 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06366 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06367 #endif 06368 06369 if (ast_adsi_end_download(chan)) { 06370 bytes = 0; 06371 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06372 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06373 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06374 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06375 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06376 return 0; 06377 } 06378 bytes = 0; 06379 bytes += ast_adsi_download_disconnect(buf + bytes); 06380 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06381 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06382 06383 ast_debug(1, "Done downloading scripts...\n"); 06384 06385 #ifdef DISPLAY 06386 /* Add last dot */ 06387 bytes = 0; 06388 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06389 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06390 #endif 06391 ast_debug(1, "Restarting session...\n"); 06392 06393 bytes = 0; 06394 /* Load the session now */ 06395 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06396 *useadsi = 1; 06397 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06398 } else 06399 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06400 06401 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06402 return 0; 06403 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6422 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().
06423 { 06424 unsigned char buf[256]; 06425 int bytes = 0; 06426 unsigned char keys[8]; 06427 int x; 06428 if (!ast_adsi_available(chan)) 06429 return; 06430 06431 for (x = 0; x < 8; x++) 06432 keys[x] = 0; 06433 /* Set one key for next */ 06434 keys[3] = ADSI_KEY_APPS + 3; 06435 06436 bytes += adsi_logo(buf + bytes); 06437 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06438 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06439 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06440 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06441 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06442 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06443 bytes += ast_adsi_set_keys(buf + bytes, keys); 06444 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06445 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06446 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6268 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().
06269 { 06270 int bytes = 0; 06271 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06272 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06273 return bytes; 06274 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6499 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().
06500 { 06501 int bytes = 0; 06502 unsigned char buf[256]; 06503 char buf1[256], buf2[256]; 06504 char fn2[PATH_MAX]; 06505 06506 char cid[256] = ""; 06507 char *val; 06508 char *name, *num; 06509 char datetime[21] = ""; 06510 FILE *f; 06511 06512 unsigned char keys[8]; 06513 06514 int x; 06515 06516 if (!ast_adsi_available(chan)) 06517 return; 06518 06519 /* Retrieve important info */ 06520 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06521 f = fopen(fn2, "r"); 06522 if (f) { 06523 while (!feof(f)) { 06524 if (!fgets((char *) buf, sizeof(buf), f)) { 06525 continue; 06526 } 06527 if (!feof(f)) { 06528 char *stringp = NULL; 06529 stringp = (char *) buf; 06530 strsep(&stringp, "="); 06531 val = strsep(&stringp, "="); 06532 if (!ast_strlen_zero(val)) { 06533 if (!strcmp((char *) buf, "callerid")) 06534 ast_copy_string(cid, val, sizeof(cid)); 06535 if (!strcmp((char *) buf, "origdate")) 06536 ast_copy_string(datetime, val, sizeof(datetime)); 06537 } 06538 } 06539 } 06540 fclose(f); 06541 } 06542 /* New meaning for keys */ 06543 for (x = 0; x < 5; x++) 06544 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06545 keys[6] = 0x0; 06546 keys[7] = 0x0; 06547 06548 if (!vms->curmsg) { 06549 /* No prev key, provide "Folder" instead */ 06550 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06551 } 06552 if (vms->curmsg >= vms->lastmsg) { 06553 /* If last message ... */ 06554 if (vms->curmsg) { 06555 /* but not only message, provide "Folder" instead */ 06556 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06557 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06558 06559 } else { 06560 /* Otherwise if only message, leave blank */ 06561 keys[3] = 1; 06562 } 06563 } 06564 06565 if (!ast_strlen_zero(cid)) { 06566 ast_callerid_parse(cid, &name, &num); 06567 if (!name) 06568 name = num; 06569 } else 06570 name = "Unknown Caller"; 06571 06572 /* If deleted, show "undeleted" */ 06573 #ifdef IMAP_STORAGE 06574 ast_mutex_lock(&vms->lock); 06575 #endif 06576 if (vms->deleted[vms->curmsg]) { 06577 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06578 } 06579 #ifdef IMAP_STORAGE 06580 ast_mutex_unlock(&vms->lock); 06581 #endif 06582 06583 /* Except "Exit" */ 06584 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06585 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06586 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06587 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06588 06589 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06590 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06591 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06592 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06593 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06594 bytes += ast_adsi_set_keys(buf + bytes, keys); 06595 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06596 06597 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06598 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6448 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().
06449 { 06450 unsigned char buf[256]; 06451 int bytes = 0; 06452 unsigned char keys[8]; 06453 int x; 06454 if (!ast_adsi_available(chan)) 06455 return; 06456 06457 for (x = 0; x < 8; x++) 06458 keys[x] = 0; 06459 /* Set one key for next */ 06460 keys[3] = ADSI_KEY_APPS + 3; 06461 06462 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06463 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06464 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06465 bytes += ast_adsi_set_keys(buf + bytes, keys); 06466 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06467 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06468 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6652 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(), buf2, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
06653 { 06654 unsigned char buf[256] = ""; 06655 char buf1[256] = "", buf2[256] = ""; 06656 int bytes = 0; 06657 unsigned char keys[8]; 06658 int x; 06659 06660 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06661 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06662 if (!ast_adsi_available(chan)) 06663 return; 06664 if (vms->newmessages) { 06665 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06666 if (vms->oldmessages) { 06667 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06668 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06669 } else { 06670 snprintf(buf2, sizeof(buf2), "%s.", newm); 06671 } 06672 } else if (vms->oldmessages) { 06673 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06674 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06675 } else { 06676 strcpy(buf1, "You have no messages."); 06677 buf2[0] = ' '; 06678 buf2[1] = '\0'; 06679 } 06680 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06681 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06682 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06683 06684 for (x = 0; x < 6; x++) 06685 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06686 keys[6] = 0; 06687 keys[7] = 0; 06688 06689 /* Don't let them listen if there are none */ 06690 if (vms->lastmsg < 0) 06691 keys[0] = 1; 06692 bytes += ast_adsi_set_keys(buf + bytes, keys); 06693 06694 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06695 06696 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06697 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6699 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(), buf2, vm_state::curbox, and vm_state::lastmsg.
06700 { 06701 unsigned char buf[256] = ""; 06702 char buf1[256] = "", buf2[256] = ""; 06703 int bytes = 0; 06704 unsigned char keys[8]; 06705 int x; 06706 06707 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06708 06709 if (!ast_adsi_available(chan)) 06710 return; 06711 06712 /* Original command keys */ 06713 for (x = 0; x < 6; x++) 06714 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06715 06716 keys[6] = 0; 06717 keys[7] = 0; 06718 06719 if ((vms->lastmsg + 1) < 1) 06720 keys[0] = 0; 06721 06722 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06723 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06724 06725 if (vms->lastmsg + 1) 06726 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06727 else 06728 strcpy(buf2, "no messages."); 06729 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06730 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06731 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06732 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06733 bytes += ast_adsi_set_keys(buf + bytes, keys); 06734 06735 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06736 06737 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06738 06739 }
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 13250 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_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().
13251 { 13252 int res = 0; 13253 char filename[PATH_MAX]; 13254 struct ast_config *msg_cfg = NULL; 13255 const char *origtime, *context; 13256 char *name, *num; 13257 int retries = 0; 13258 char *cid; 13259 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 13260 13261 vms->starting = 0; 13262 13263 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13264 13265 /* Retrieve info from VM attribute file */ 13266 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 13267 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 13268 msg_cfg = ast_config_load(filename, config_flags); 13269 DISPOSE(vms->curdir, vms->curmsg); 13270 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 13271 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 13272 return 0; 13273 } 13274 13275 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 13276 ast_config_destroy(msg_cfg); 13277 return 0; 13278 } 13279 13280 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 13281 13282 context = ast_variable_retrieve(msg_cfg, "message", "context"); 13283 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 13284 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 13285 switch (option) { 13286 case 3: /* Play message envelope */ 13287 if (!res) 13288 res = play_message_datetime(chan, vmu, origtime, filename); 13289 if (!res) 13290 res = play_message_callerid(chan, vms, cid, context, 0); 13291 13292 res = 't'; 13293 break; 13294 13295 case 2: /* Call back */ 13296 13297 if (ast_strlen_zero(cid)) 13298 break; 13299 13300 ast_callerid_parse(cid, &name, &num); 13301 while ((res > -1) && (res != 't')) { 13302 switch (res) { 13303 case '1': 13304 if (num) { 13305 /* Dial the CID number */ 13306 res = dialout(chan, vmu, num, vmu->callback); 13307 if (res) { 13308 ast_config_destroy(msg_cfg); 13309 return 9; 13310 } 13311 } else { 13312 res = '2'; 13313 } 13314 break; 13315 13316 case '2': 13317 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 13318 if (!ast_strlen_zero(vmu->dialout)) { 13319 res = dialout(chan, vmu, NULL, vmu->dialout); 13320 if (res) { 13321 ast_config_destroy(msg_cfg); 13322 return 9; 13323 } 13324 } else { 13325 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 13326 res = ast_play_and_wait(chan, "vm-sorry"); 13327 } 13328 ast_config_destroy(msg_cfg); 13329 return res; 13330 case '*': 13331 res = 't'; 13332 break; 13333 case '3': 13334 case '4': 13335 case '5': 13336 case '6': 13337 case '7': 13338 case '8': 13339 case '9': 13340 case '0': 13341 13342 res = ast_play_and_wait(chan, "vm-sorry"); 13343 retries++; 13344 break; 13345 default: 13346 if (num) { 13347 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 13348 res = ast_play_and_wait(chan, "vm-num-i-have"); 13349 if (!res) 13350 res = play_message_callerid(chan, vms, num, vmu->context, 1); 13351 if (!res) 13352 res = ast_play_and_wait(chan, "vm-tocallnum"); 13353 /* Only prompt for a caller-specified number if there is a dialout context specified */ 13354 if (!ast_strlen_zero(vmu->dialout)) { 13355 if (!res) 13356 res = ast_play_and_wait(chan, "vm-calldiffnum"); 13357 } 13358 } else { 13359 res = ast_play_and_wait(chan, "vm-nonumber"); 13360 if (!ast_strlen_zero(vmu->dialout)) { 13361 if (!res) 13362 res = ast_play_and_wait(chan, "vm-toenternumber"); 13363 } 13364 } 13365 if (!res) { 13366 res = ast_play_and_wait(chan, "vm-star-cancel"); 13367 } 13368 if (!res) { 13369 res = ast_waitfordigit(chan, 6000); 13370 } 13371 if (!res) { 13372 retries++; 13373 if (retries > 3) { 13374 res = 't'; 13375 } 13376 } 13377 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 13378 break; 13379 13380 } 13381 if (res == 't') 13382 res = 0; 13383 else if (res == '*') 13384 res = -1; 13385 } 13386 break; 13387 13388 case 1: /* Reply */ 13389 /* Send reply directly to sender */ 13390 if (ast_strlen_zero(cid)) 13391 break; 13392 13393 ast_callerid_parse(cid, &name, &num); 13394 if (!num) { 13395 ast_verb(3, "No CID number available, no reply sent\n"); 13396 if (!res) 13397 res = ast_play_and_wait(chan, "vm-nonumber"); 13398 ast_config_destroy(msg_cfg); 13399 return res; 13400 } else { 13401 struct ast_vm_user vmu2; 13402 if (find_user(&vmu2, vmu->context, num)) { 13403 struct leave_vm_options leave_options; 13404 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 13405 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 13406 13407 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 13408 13409 memset(&leave_options, 0, sizeof(leave_options)); 13410 leave_options.record_gain = record_gain; 13411 res = leave_voicemail(chan, mailbox, &leave_options); 13412 if (!res) 13413 res = 't'; 13414 ast_config_destroy(msg_cfg); 13415 return res; 13416 } else { 13417 /* Sender has no mailbox, can't reply */ 13418 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 13419 ast_play_and_wait(chan, "vm-nobox"); 13420 res = 't'; 13421 ast_config_destroy(msg_cfg); 13422 return res; 13423 } 13424 } 13425 res = 0; 13426 13427 break; 13428 } 13429 13430 #ifndef IMAP_STORAGE 13431 ast_config_destroy(msg_cfg); 13432 13433 if (!res) { 13434 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 13435 vms->heard[msg] = 1; 13436 res = wait_file(chan, vms, vms->fn); 13437 } 13438 #endif 13439 return res; 13440 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10770 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.
10771 { 10772 /* Assumes lock is already held */ 10773 char *tmp; 10774 char *stringp; 10775 char *s; 10776 struct ast_vm_user *vmu; 10777 char *mailbox_full; 10778 int new = 0, old = 0, urgent = 0; 10779 char secretfn[PATH_MAX] = ""; 10780 10781 tmp = ast_strdupa(data); 10782 10783 if (!(vmu = find_or_create(context, box))) 10784 return -1; 10785 10786 populate_defaults(vmu); 10787 10788 stringp = tmp; 10789 if ((s = strsep(&stringp, ","))) { 10790 if (!ast_strlen_zero(s) && s[0] == '*') { 10791 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 10792 "\n\tmust be reset in voicemail.conf.\n", box); 10793 } 10794 /* assign password regardless of validity to prevent NULL password from being assigned */ 10795 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10796 } 10797 if (stringp && (s = strsep(&stringp, ","))) { 10798 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10799 } 10800 if (stringp && (s = strsep(&stringp, ","))) { 10801 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10802 } 10803 if (stringp && (s = strsep(&stringp, ","))) { 10804 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10805 } 10806 if (stringp && (s = strsep(&stringp, ","))) { 10807 apply_options(vmu, s); 10808 } 10809 10810 switch (vmu->passwordlocation) { 10811 case OPT_PWLOC_SPOOLDIR: 10812 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10813 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10814 } 10815 10816 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10817 strcpy(mailbox_full, box); 10818 strcat(mailbox_full, "@"); 10819 strcat(mailbox_full, context); 10820 10821 inboxcount2(mailbox_full, &urgent, &new, &old); 10822 queue_mwi_event(mailbox_full, urgent, new, old); 10823 10824 return 0; 10825 }
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 4474 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.
04475 { 04476 struct ast_str *tmp = ast_str_alloca(80); 04477 int first_section = 1; 04478 04479 ast_str_reset(*end); 04480 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04481 for (; *start; start++) { 04482 int need_encoding = 0; 04483 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04484 need_encoding = 1; 04485 } 04486 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04487 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04488 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04489 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04490 /* Start new line */ 04491 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04492 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04493 first_section = 0; 04494 } 04495 if (need_encoding && *start == ' ') { 04496 ast_str_append(&tmp, -1, "_"); 04497 } else if (need_encoding) { 04498 ast_str_append(&tmp, -1, "=%hhX", *start); 04499 } else { 04500 ast_str_append(&tmp, -1, "%c", *start); 04501 } 04502 } 04503 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04504 return ast_str_buffer(*end); 04505 }
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 4402 of file app_voicemail_imapstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04403 { 04404 const char *ptr; 04405 04406 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04407 ast_str_set(buf, maxlen, "\""); 04408 for (ptr = from; *ptr; ptr++) { 04409 if (*ptr == '"' || *ptr == '\\') { 04410 ast_str_append(buf, maxlen, "\\%c", *ptr); 04411 } else { 04412 ast_str_append(buf, maxlen, "%c", *ptr); 04413 } 04414 } 04415 ast_str_append(buf, maxlen, "\""); 04416 04417 return ast_str_buffer(*buf); 04418 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10827 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.
10828 { 10829 int res = 0; 10830 struct ast_vm_user *vmu; 10831 /* language parameter seems to only be used for display in manager action */ 10832 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10833 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10834 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10835 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10836 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10837 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10838 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 10839 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 10840 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 10841 #ifdef IMAP_STORAGE 10842 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10843 "imapfolder=INBOX|imapvmshareid=6000"; 10844 #endif 10845 10846 switch (cmd) { 10847 case TEST_INIT: 10848 info->name = "vmuser"; 10849 info->category = "/apps/app_voicemail/"; 10850 info->summary = "Vmuser unit test"; 10851 info->description = 10852 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10853 return AST_TEST_NOT_RUN; 10854 case TEST_EXECUTE: 10855 break; 10856 } 10857 10858 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10859 return AST_TEST_NOT_RUN; 10860 } 10861 ast_set_flag(vmu, VM_ALLOCED); 10862 populate_defaults(vmu); 10863 10864 apply_options(vmu, options_string); 10865 10866 if (!ast_test_flag(vmu, VM_ATTACH)) { 10867 ast_test_status_update(test, "Parse failure for attach option\n"); 10868 res = 1; 10869 } 10870 if (strcasecmp(vmu->attachfmt, "wav49")) { 10871 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10872 res = 1; 10873 } 10874 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10875 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10876 res = 1; 10877 } 10878 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 10879 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 10880 res = 1; 10881 } 10882 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 10883 ast_test_status_update(test, "Parse failure for emailbody option\n"); 10884 res = 1; 10885 } 10886 if (strcasecmp(vmu->zonetag, "central")) { 10887 ast_test_status_update(test, "Parse failure for tz option\n"); 10888 res = 1; 10889 } 10890 if (!ast_test_flag(vmu, VM_DELETE)) { 10891 ast_test_status_update(test, "Parse failure for delete option\n"); 10892 res = 1; 10893 } 10894 if (!ast_test_flag(vmu, VM_SAYCID)) { 10895 ast_test_status_update(test, "Parse failure for saycid option\n"); 10896 res = 1; 10897 } 10898 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10899 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10900 res = 1; 10901 } 10902 if (!ast_test_flag(vmu, VM_REVIEW)) { 10903 ast_test_status_update(test, "Parse failure for review option\n"); 10904 res = 1; 10905 } 10906 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10907 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10908 res = 1; 10909 } 10910 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10911 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10912 res = 1; 10913 } 10914 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10915 ast_test_status_update(test, "Parse failure for operator option\n"); 10916 res = 1; 10917 } 10918 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10919 ast_test_status_update(test, "Parse failure for envelope option\n"); 10920 res = 1; 10921 } 10922 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10923 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10924 res = 1; 10925 } 10926 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10927 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10928 res = 1; 10929 } 10930 if (vmu->saydurationm != 5) { 10931 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10932 res = 1; 10933 } 10934 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10935 ast_test_status_update(test, "Parse failure for forcename option\n"); 10936 res = 1; 10937 } 10938 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10939 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10940 res = 1; 10941 } 10942 if (strcasecmp(vmu->callback, "somecontext")) { 10943 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10944 res = 1; 10945 } 10946 if (strcasecmp(vmu->dialout, "somecontext2")) { 10947 ast_test_status_update(test, "Parse failure for dialout option\n"); 10948 res = 1; 10949 } 10950 if (strcasecmp(vmu->exit, "somecontext3")) { 10951 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10952 res = 1; 10953 } 10954 if (vmu->minsecs != 10) { 10955 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10956 res = 1; 10957 } 10958 if (vmu->maxsecs != 100) { 10959 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10960 res = 1; 10961 } 10962 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10963 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10964 res = 1; 10965 } 10966 if (vmu->maxdeletedmsg != 50) { 10967 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10968 res = 1; 10969 } 10970 if (vmu->volgain != 1.3) { 10971 ast_test_status_update(test, "Parse failure for volgain option\n"); 10972 res = 1; 10973 } 10974 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10975 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10976 res = 1; 10977 } 10978 #ifdef IMAP_STORAGE 10979 apply_options(vmu, option_string2); 10980 10981 if (strcasecmp(vmu->imapuser, "imapuser")) { 10982 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10983 res = 1; 10984 } 10985 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10986 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10987 res = 1; 10988 } 10989 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10990 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10991 res = 1; 10992 } 10993 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10994 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10995 res = 1; 10996 } 10997 #endif 10998 10999 free_user(vmu); 11000 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11001 }
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 4278 of file app_voicemail_imapstorage.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04279 { 04280 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04281 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04282 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04283 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04284 int i, hiteof = 0; 04285 FILE *fi; 04286 struct baseio bio; 04287 04288 memset(&bio, 0, sizeof(bio)); 04289 bio.iocp = BASEMAXINLINE; 04290 04291 if (!(fi = fopen(filename, "rb"))) { 04292 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04293 return -1; 04294 } 04295 04296 while (!hiteof){ 04297 unsigned char igroup[3], ogroup[4]; 04298 int c, n; 04299 04300 memset(igroup, 0, sizeof(igroup)); 04301 04302 for (n = 0; n < 3; n++) { 04303 if ((c = inchar(&bio, fi)) == EOF) { 04304 hiteof = 1; 04305 break; 04306 } 04307 04308 igroup[n] = (unsigned char) c; 04309 } 04310 04311 if (n > 0) { 04312 ogroup[0]= dtable[igroup[0] >> 2]; 04313 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04314 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04315 ogroup[3]= dtable[igroup[2] & 0x3F]; 04316 04317 if (n < 3) { 04318 ogroup[3] = '='; 04319 04320 if (n < 2) 04321 ogroup[2] = '='; 04322 } 04323 04324 for (i = 0; i < 4; i++) 04325 ochar(&bio, ogroup[i], so); 04326 } 04327 } 04328 04329 fclose(fi); 04330 04331 if (fputs(ENDL, so) == EOF) { 04332 return 0; 04333 } 04334 04335 return 1; 04336 }
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 4447 of file app_voicemail_imapstorage.c.
04448 { 04449 for (; *str; str++) { 04450 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04451 return 1; 04452 } 04453 } 04454 return 0; 04455 }
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 7965 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.
07966 { 07967 int x = 0; 07968 int last_msg_idx = 0; 07969 07970 #ifndef IMAP_STORAGE 07971 int res = 0, nummsg; 07972 char fn2[PATH_MAX]; 07973 #endif 07974 07975 if (vms->lastmsg <= -1) { 07976 goto done; 07977 } 07978 07979 vms->curmsg = -1; 07980 #ifndef IMAP_STORAGE 07981 /* Get the deleted messages fixed */ 07982 if (vm_lock_path(vms->curdir)) { 07983 return ERROR_LOCK_PATH; 07984 } 07985 07986 /* update count as message may have arrived while we've got mailbox open */ 07987 last_msg_idx = last_message_index(vmu, vms->curdir); 07988 if (last_msg_idx != vms->lastmsg) { 07989 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 07990 } 07991 07992 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07993 for (x = 0; x < last_msg_idx + 1; x++) { 07994 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07995 /* Save this message. It's not in INBOX or hasn't been heard */ 07996 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07997 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07998 break; 07999 } 08000 vms->curmsg++; 08001 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08002 if (strcmp(vms->fn, fn2)) { 08003 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08004 } 08005 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08006 /* Move to old folder before deleting */ 08007 res = save_to_folder(vmu, vms, x, 1); 08008 if (res == ERROR_LOCK_PATH) { 08009 /* If save failed do not delete the message */ 08010 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08011 vms->deleted[x] = 0; 08012 vms->heard[x] = 0; 08013 --x; 08014 } 08015 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08016 /* Move to deleted folder */ 08017 res = save_to_folder(vmu, vms, x, 10); 08018 if (res == ERROR_LOCK_PATH) { 08019 /* If save failed do not delete the message */ 08020 vms->deleted[x] = 0; 08021 vms->heard[x] = 0; 08022 --x; 08023 } 08024 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08025 /* If realtime storage enabled - we should explicitly delete this message, 08026 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08027 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08028 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08029 DELETE(vms->curdir, x, vms->fn, vmu); 08030 } 08031 } 08032 } 08033 08034 /* Delete ALL remaining messages */ 08035 nummsg = x - 1; 08036 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08037 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08038 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08039 DELETE(vms->curdir, x, vms->fn, vmu); 08040 } 08041 } 08042 ast_unlock_path(vms->curdir); 08043 #else /* defined(IMAP_STORAGE) */ 08044 ast_mutex_lock(&vms->lock); 08045 if (vms->deleted) { 08046 /* Since we now expunge after each delete, deleting in reverse order 08047 * ensures that no reordering occurs between each step. */ 08048 last_msg_idx = vms->dh_arraysize; 08049 for (x = last_msg_idx - 1; x >= 0; x--) { 08050 if (vms->deleted[x]) { 08051 ast_debug(3, "IMAP delete of %d\n", x); 08052 DELETE(vms->curdir, x, vms->fn, vmu); 08053 } 08054 } 08055 } 08056 #endif 08057 08058 done: 08059 if (vms->deleted) { 08060 ast_free(vms->deleted); 08061 vms->deleted = NULL; 08062 } 08063 if (vms->heard) { 08064 ast_free(vms->heard); 08065 vms->heard = NULL; 08066 } 08067 vms->dh_arraysize = 0; 08068 #ifdef IMAP_STORAGE 08069 ast_mutex_unlock(&vms->lock); 08070 #endif 08071 08072 return 0; 08073 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 11147 of file app_voicemail_imapstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.
11148 { 11149 int which = 0; 11150 int wordlen; 11151 struct ast_vm_user *vmu; 11152 const char *context = ""; 11153 11154 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 11155 if (pos > 4) 11156 return NULL; 11157 if (pos == 3) 11158 return (state == 0) ? ast_strdup("for") : NULL; 11159 wordlen = strlen(word); 11160 AST_LIST_TRAVERSE(&users, vmu, list) { 11161 if (!strncasecmp(word, vmu->context, wordlen)) { 11162 if (context && strcmp(context, vmu->context) && ++which > state) 11163 return ast_strdup(vmu->context); 11164 /* ignore repeated contexts ? */ 11165 context = vmu->context; 11166 } 11167 } 11168 return NULL; 11169 }
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 4083 of file app_voicemail_imapstorage.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
04084 { 04085 int ifd; 04086 int ofd; 04087 int res; 04088 int len; 04089 char buf[4096]; 04090 04091 #ifdef HARDLINK_WHEN_POSSIBLE 04092 /* Hard link if possible; saves disk space & is faster */ 04093 if (link(infile, outfile)) { 04094 #endif 04095 if ((ifd = open(infile, O_RDONLY)) < 0) { 04096 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04097 return -1; 04098 } 04099 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04100 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04101 close(ifd); 04102 return -1; 04103 } 04104 do { 04105 len = read(ifd, buf, sizeof(buf)); 04106 if (len < 0) { 04107 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04108 close(ifd); 04109 close(ofd); 04110 unlink(outfile); 04111 } else if (len) { 04112 res = write(ofd, buf, len); 04113 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04114 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04115 close(ifd); 04116 close(ofd); 04117 unlink(outfile); 04118 } 04119 } 04120 } while (len); 04121 close(ifd); 04122 close(ofd); 04123 return 0; 04124 #ifdef HARDLINK_WHEN_POSSIBLE 04125 } else { 04126 /* Hard link succeeded */ 04127 return 0; 04128 } 04129 #endif 04130 }
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 5319 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().
05320 { 05321 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05322 const char *frombox = mbox(vmu, imbox); 05323 const char *userfolder; 05324 int recipmsgnum; 05325 int res = 0; 05326 05327 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05328 05329 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05330 userfolder = "Urgent"; 05331 } else { 05332 userfolder = "INBOX"; 05333 } 05334 05335 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05336 05337 if (!dir) 05338 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05339 else 05340 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05341 05342 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05343 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05344 05345 if (vm_lock_path(todir)) 05346 return ERROR_LOCK_PATH; 05347 05348 recipmsgnum = last_message_index(recip, todir) + 1; 05349 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05350 make_file(topath, sizeof(topath), todir, recipmsgnum); 05351 #ifndef ODBC_STORAGE 05352 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05353 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05354 } else { 05355 #endif 05356 /* If we are prepending a message for ODBC, then the message already 05357 * exists in the database, but we want to force copying from the 05358 * filesystem (since only the FS contains the prepend). */ 05359 copy_plain_file(frompath, topath); 05360 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05361 vm_delete(topath); 05362 #ifndef ODBC_STORAGE 05363 } 05364 #endif 05365 } else { 05366 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05367 res = -1; 05368 } 05369 ast_unlock_path(todir); 05370 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05371 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05372 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05373 flag); 05374 05375 return res; 05376 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4141 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.
04142 { 04143 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04144 struct ast_variable *tmp,*var = NULL; 04145 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04146 ast_filecopy(frompath, topath, NULL); 04147 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04148 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04149 if (ast_check_realtime("voicemail_data")) { 04150 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04151 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04152 for (tmp = var; tmp; tmp = tmp->next) { 04153 if (!strcasecmp(tmp->name, "origmailbox")) { 04154 origmailbox = tmp->value; 04155 } else if (!strcasecmp(tmp->name, "context")) { 04156 context = tmp->value; 04157 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04158 macrocontext = tmp->value; 04159 } else if (!strcasecmp(tmp->name, "exten")) { 04160 exten = tmp->value; 04161 } else if (!strcasecmp(tmp->name, "priority")) { 04162 priority = tmp->value; 04163 } else if (!strcasecmp(tmp->name, "callerchan")) { 04164 callerchan = tmp->value; 04165 } else if (!strcasecmp(tmp->name, "callerid")) { 04166 callerid = tmp->value; 04167 } else if (!strcasecmp(tmp->name, "origdate")) { 04168 origdate = tmp->value; 04169 } else if (!strcasecmp(tmp->name, "origtime")) { 04170 origtime = tmp->value; 04171 } else if (!strcasecmp(tmp->name, "category")) { 04172 category = tmp->value; 04173 } else if (!strcasecmp(tmp->name, "duration")) { 04174 duration = tmp->value; 04175 } 04176 } 04177 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); 04178 } 04179 copy(frompath2, topath2); 04180 ast_variables_destroy(var); 04181 }
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 3978 of file app_voicemail_imapstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
03979 { 03980 03981 int vmcount = 0; 03982 DIR *vmdir = NULL; 03983 struct dirent *vment = NULL; 03984 03985 if (vm_lock_path(dir)) 03986 return ERROR_LOCK_PATH; 03987 03988 if ((vmdir = opendir(dir))) { 03989 while ((vment = readdir(vmdir))) { 03990 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03991 vmcount++; 03992 } 03993 } 03994 closedir(vmdir); 03995 } 03996 ast_unlock_path(dir); 03997 03998 return vmcount; 03999 }
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 13177 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.
13178 { 13179 int cmd = 0; 13180 char destination[80] = ""; 13181 int retries = 0; 13182 13183 if (!num) { 13184 ast_verb(3, "Destination number will be entered manually\n"); 13185 while (retries < 3 && cmd != 't') { 13186 destination[1] = '\0'; 13187 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 13188 if (!cmd) 13189 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 13190 if (!cmd) 13191 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 13192 if (!cmd) { 13193 cmd = ast_waitfordigit(chan, 6000); 13194 if (cmd) 13195 destination[0] = cmd; 13196 } 13197 if (!cmd) { 13198 retries++; 13199 } else { 13200 13201 if (cmd < 0) 13202 return 0; 13203 if (cmd == '*') { 13204 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 13205 return 0; 13206 } 13207 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 13208 retries++; 13209 else 13210 cmd = 't'; 13211 } 13212 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 13213 } 13214 if (retries >= 3) { 13215 return 0; 13216 } 13217 13218 } else { 13219 if (option_verbose > 2) 13220 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 13221 ast_copy_string(destination, num, sizeof(destination)); 13222 } 13223 13224 if (!ast_strlen_zero(destination)) { 13225 if (destination[strlen(destination) -1 ] == '*') 13226 return 0; 13227 if (option_verbose > 2) 13228 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 13229 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 13230 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 13231 chan->priority = 0; 13232 return 9; 13233 } 13234 return 0; 13235 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10730 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.
10731 { 10732 struct ast_vm_user *vmu; 10733 10734 if (!ast_strlen_zero(box) && box[0] == '*') { 10735 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 10736 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 10737 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 10738 "\n\tand will be ignored.\n", box, context); 10739 return NULL; 10740 } 10741 10742 AST_LIST_TRAVERSE(&users, vmu, list) { 10743 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10744 if (strcasecmp(vmu->context, context)) { 10745 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10746 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10747 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10748 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10749 } 10750 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10751 return NULL; 10752 } 10753 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10754 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10755 return NULL; 10756 } 10757 } 10758 10759 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10760 return NULL; 10761 10762 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10763 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10764 10765 AST_LIST_INSERT_TAIL(&users, vmu, list); 10766 10767 return vmu; 10768 }
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 7166 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.
07167 { 07168 #ifdef IMAP_STORAGE 07169 int todircount = 0; 07170 struct vm_state *dstvms; 07171 #endif 07172 char username[70]=""; 07173 char fn[PATH_MAX]; /* for playback of name greeting */ 07174 char ecodes[16] = "#"; 07175 int res = 0, cmd = 0; 07176 struct ast_vm_user *receiver = NULL, *vmtmp; 07177 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07178 char *stringp; 07179 const char *s; 07180 int saved_messages = 0; 07181 int valid_extensions = 0; 07182 char *dir; 07183 int curmsg; 07184 char urgent_str[7] = ""; 07185 int prompt_played = 0; 07186 #ifndef IMAP_STORAGE 07187 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07188 #endif 07189 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07190 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07191 } 07192 07193 if (vms == NULL) return -1; 07194 dir = vms->curdir; 07195 curmsg = vms->curmsg; 07196 07197 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07198 while (!res && !valid_extensions) { 07199 int use_directory = 0; 07200 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07201 int done = 0; 07202 int retries = 0; 07203 cmd = 0; 07204 while ((cmd >= 0) && !done ){ 07205 if (cmd) 07206 retries = 0; 07207 switch (cmd) { 07208 case '1': 07209 use_directory = 0; 07210 done = 1; 07211 break; 07212 case '2': 07213 use_directory = 1; 07214 done = 1; 07215 break; 07216 case '*': 07217 cmd = 't'; 07218 done = 1; 07219 break; 07220 default: 07221 /* Press 1 to enter an extension press 2 to use the directory */ 07222 cmd = ast_play_and_wait(chan, "vm-forward"); 07223 if (!cmd) { 07224 cmd = ast_waitfordigit(chan, 3000); 07225 } 07226 if (!cmd) { 07227 retries++; 07228 } 07229 if (retries > 3) { 07230 cmd = 't'; 07231 done = 1; 07232 } 07233 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07234 } 07235 } 07236 if (cmd < 0 || cmd == 't') 07237 break; 07238 } 07239 07240 if (use_directory) { 07241 /* use app_directory */ 07242 07243 char old_context[sizeof(chan->context)]; 07244 char old_exten[sizeof(chan->exten)]; 07245 int old_priority; 07246 struct ast_app* directory_app; 07247 07248 directory_app = pbx_findapp("Directory"); 07249 if (directory_app) { 07250 char vmcontext[256]; 07251 /* make backup copies */ 07252 memcpy(old_context, chan->context, sizeof(chan->context)); 07253 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07254 old_priority = chan->priority; 07255 07256 /* call the the Directory, changes the channel */ 07257 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07258 res = pbx_exec(chan, directory_app, vmcontext); 07259 07260 ast_copy_string(username, chan->exten, sizeof(username)); 07261 07262 /* restore the old context, exten, and priority */ 07263 memcpy(chan->context, old_context, sizeof(chan->context)); 07264 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07265 chan->priority = old_priority; 07266 } else { 07267 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07268 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07269 } 07270 } else { 07271 /* Ask for an extension */ 07272 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07273 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07274 prompt_played++; 07275 if (res || prompt_played > 4) 07276 break; 07277 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07278 break; 07279 } 07280 07281 /* start all over if no username */ 07282 if (ast_strlen_zero(username)) 07283 continue; 07284 stringp = username; 07285 s = strsep(&stringp, "*"); 07286 /* start optimistic */ 07287 valid_extensions = 1; 07288 while (s) { 07289 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07290 int oldmsgs; 07291 int newmsgs; 07292 int capacity; 07293 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07294 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07295 /* Shouldn't happen, but allow trying another extension if it does */ 07296 res = ast_play_and_wait(chan, "pbx-invalid"); 07297 valid_extensions = 0; 07298 break; 07299 } 07300 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07301 if ((newmsgs + oldmsgs) >= capacity) { 07302 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07303 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07304 valid_extensions = 0; 07305 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07306 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07307 free_user(vmtmp); 07308 } 07309 inprocess_count(receiver->mailbox, receiver->context, -1); 07310 break; 07311 } 07312 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07313 } else { 07314 /* XXX Optimization for the future. When we encounter a single bad extension, 07315 * bailing out on all of the extensions may not be the way to go. We should 07316 * probably just bail on that single extension, then allow the user to enter 07317 * several more. XXX 07318 */ 07319 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07320 free_user(receiver); 07321 } 07322 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07323 /* "I am sorry, that's not a valid extension. Please try again." */ 07324 res = ast_play_and_wait(chan, "pbx-invalid"); 07325 valid_extensions = 0; 07326 break; 07327 } 07328 07329 /* play name if available, else play extension number */ 07330 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07331 RETRIEVE(fn, -1, s, receiver->context); 07332 if (ast_fileexists(fn, NULL, NULL) > 0) { 07333 res = ast_stream_and_wait(chan, fn, ecodes); 07334 if (res) { 07335 DISPOSE(fn, -1); 07336 return res; 07337 } 07338 } else { 07339 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07340 } 07341 DISPOSE(fn, -1); 07342 07343 s = strsep(&stringp, "*"); 07344 } 07345 /* break from the loop of reading the extensions */ 07346 if (valid_extensions) 07347 break; 07348 } 07349 /* check if we're clear to proceed */ 07350 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07351 return res; 07352 if (is_new_message == 1) { 07353 struct leave_vm_options leave_options; 07354 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07355 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07356 07357 /* Send VoiceMail */ 07358 memset(&leave_options, 0, sizeof(leave_options)); 07359 leave_options.record_gain = record_gain; 07360 cmd = leave_voicemail(chan, mailbox, &leave_options); 07361 } else { 07362 /* Forward VoiceMail */ 07363 long duration = 0; 07364 struct vm_state vmstmp; 07365 int copy_msg_result = 0; 07366 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07367 07368 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07369 07370 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07371 if (!cmd) { 07372 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07373 #ifdef IMAP_STORAGE 07374 int attach_user_voicemail; 07375 char *myserveremail = serveremail; 07376 07377 /* get destination mailbox */ 07378 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07379 if (!dstvms) { 07380 dstvms = create_vm_state_from_user(vmtmp); 07381 } 07382 if (dstvms) { 07383 init_mailstream(dstvms, 0); 07384 if (!dstvms->mailstream) { 07385 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07386 } else { 07387 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07388 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07389 } 07390 } else { 07391 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07392 } 07393 if (!ast_strlen_zero(vmtmp->serveremail)) 07394 myserveremail = vmtmp->serveremail; 07395 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07396 /* NULL category for IMAP storage */ 07397 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07398 dstvms->curbox, 07399 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07400 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07401 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07402 NULL, urgent_str); 07403 #else 07404 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07405 #endif 07406 saved_messages++; 07407 AST_LIST_REMOVE_CURRENT(list); 07408 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07409 free_user(vmtmp); 07410 if (res) 07411 break; 07412 } 07413 AST_LIST_TRAVERSE_SAFE_END; 07414 if (saved_messages > 0 && !copy_msg_result) { 07415 /* give confirmation that the message was saved */ 07416 /* commented out since we can't forward batches yet 07417 if (saved_messages == 1) 07418 res = ast_play_and_wait(chan, "vm-message"); 07419 else 07420 res = ast_play_and_wait(chan, "vm-messages"); 07421 if (!res) 07422 res = ast_play_and_wait(chan, "vm-saved"); */ 07423 #ifdef IMAP_STORAGE 07424 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07425 if (ast_strlen_zero(vmstmp.introfn)) 07426 #endif 07427 res = ast_play_and_wait(chan, "vm-msgsaved"); 07428 } 07429 #ifndef IMAP_STORAGE 07430 else { 07431 /* with IMAP, mailbox full warning played by imap_check_limits */ 07432 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07433 } 07434 /* Restore original message without prepended message if backup exists */ 07435 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07436 strcpy(textfile, msgfile); 07437 strcpy(backup, msgfile); 07438 strcpy(backup_textfile, msgfile); 07439 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07440 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07441 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07442 if (ast_fileexists(backup, NULL, NULL) > 0) { 07443 ast_filerename(backup, msgfile, NULL); 07444 rename(backup_textfile, textfile); 07445 } 07446 #endif 07447 } 07448 DISPOSE(dir, curmsg); 07449 #ifndef IMAP_STORAGE 07450 if (cmd) { /* assuming hangup, cleanup backup file */ 07451 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07452 strcpy(textfile, msgfile); 07453 strcpy(backup_textfile, msgfile); 07454 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07455 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07456 rename(backup_textfile, textfile); 07457 } 07458 #endif 07459 } 07460 07461 /* If anything failed above, we still have this list to free */ 07462 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07463 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07464 free_user(vmtmp); 07465 } 07466 return res ? res : cmd; 07467 }
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 11761 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.
11762 { 11763 struct ast_vm_user *current; 11764 AST_LIST_LOCK(&users); 11765 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11766 ast_set_flag(current, VM_ALLOCED); 11767 free_user(current); 11768 } 11769 AST_LIST_UNLOCK(&users); 11770 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11773 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and vm_zone::list.
11774 { 11775 struct vm_zone *zcur; 11776 AST_LIST_LOCK(&zones); 11777 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11778 free_zone(zcur); 11779 AST_LIST_UNLOCK(&zones); 11780 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5087 of file app_voicemail_imapstorage.c.
References ast_free.
05088 { 05089 ast_free(z); 05090 }
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 5043 of file app_voicemail_imapstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05044 { 05045 struct ast_tm tm; 05046 struct timeval t = ast_tvnow(); 05047 05048 ast_localtime(&t, &tm, "UTC"); 05049 05050 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05051 }
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 6775 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().
06776 { 06777 int x; 06778 int d; 06779 char fn[PATH_MAX]; 06780 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06781 if (d) 06782 return d; 06783 for (x = start; x < 5; x++) { /* For all folders */ 06784 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06785 return d; 06786 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06787 if (d) 06788 return d; 06789 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06790 06791 /* The inbox folder can have its name changed under certain conditions 06792 * so this checks if the sound file exists for the inbox folder name and 06793 * if it doesn't, plays the default name instead. */ 06794 if (x == 0) { 06795 if (ast_fileexists(fn, NULL, NULL)) { 06796 d = vm_play_folder_name(chan, fn); 06797 } else { 06798 ast_verb(1, "failed to find %s\n", fn); 06799 d = vm_play_folder_name(chan, "vm-INBOX"); 06800 } 06801 } else { 06802 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 06803 d = vm_play_folder_name(chan, fn); 06804 } 06805 06806 if (d) 06807 return d; 06808 d = ast_waitfordigit(chan, 500); 06809 if (d) 06810 return d; 06811 } 06812 06813 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06814 if (d) 06815 return d; 06816 d = ast_waitfordigit(chan, 4000); 06817 return d; 06818 }
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 6832 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
06833 { 06834 int res = 0; 06835 int loops = 0; 06836 06837 res = ast_play_and_wait(chan, fn); /* Folder name */ 06838 while (((res < '0') || (res > '9')) && 06839 (res != '#') && (res >= 0) && 06840 loops < 4) { 06841 res = get_folder(chan, 0); 06842 loops++; 06843 } 06844 if (loops == 4) { /* give up */ 06845 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 06846 return '#'; 06847 } 06848 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 06849 return res; 06850 }
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 11531 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.
11532 { 11533 unsigned int len; 11534 struct mwi_sub *mwi_sub; 11535 struct mwi_sub_task *p = datap; 11536 11537 len = sizeof(*mwi_sub); 11538 if (!ast_strlen_zero(p->mailbox)) 11539 len += strlen(p->mailbox); 11540 11541 if (!ast_strlen_zero(p->context)) 11542 len += strlen(p->context) + 1; /* Allow for seperator */ 11543 11544 if (!(mwi_sub = ast_calloc(1, len))) 11545 return -1; 11546 11547 mwi_sub->uniqueid = p->uniqueid; 11548 if (!ast_strlen_zero(p->mailbox)) 11549 strcpy(mwi_sub->mailbox, p->mailbox); 11550 11551 if (!ast_strlen_zero(p->context)) { 11552 strcat(mwi_sub->mailbox, "@"); 11553 strcat(mwi_sub->mailbox, p->context); 11554 } 11555 11556 AST_RWLIST_WRLOCK(&mwi_subs); 11557 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11558 AST_RWLIST_UNLOCK(&mwi_subs); 11559 ast_free((void *) p->mailbox); 11560 ast_free((void *) p->context); 11561 ast_free(p); 11562 poll_subscribed_mailbox(mwi_sub); 11563 return 0; 11564 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11509 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.
11510 { 11511 struct mwi_sub *mwi_sub; 11512 uint32_t *uniqueid = datap; 11513 11514 AST_RWLIST_WRLOCK(&mwi_subs); 11515 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11516 if (mwi_sub->uniqueid == *uniqueid) { 11517 AST_LIST_REMOVE_CURRENT(entry); 11518 break; 11519 } 11520 } 11521 AST_RWLIST_TRAVERSE_SAFE_END 11522 AST_RWLIST_UNLOCK(&mwi_subs); 11523 11524 if (mwi_sub) 11525 mwi_sub_destroy(mwi_sub); 11526 11527 ast_free(uniqueid); 11528 return 0; 11529 }
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 11284 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.
11285 { 11286 switch (cmd) { 11287 case CLI_INIT: 11288 e->command = "voicemail reload"; 11289 e->usage = 11290 "Usage: voicemail reload\n" 11291 " Reload voicemail configuration\n"; 11292 return NULL; 11293 case CLI_GENERATE: 11294 return NULL; 11295 } 11296 11297 if (a->argc != 2) 11298 return CLI_SHOWUSAGE; 11299 11300 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11301 load_config(1); 11302 11303 return CLI_SUCCESS; 11304 }
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 11172 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.
11173 { 11174 struct ast_vm_user *vmu; 11175 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 11176 const char *context = NULL; 11177 int users_counter = 0; 11178 11179 switch (cmd) { 11180 case CLI_INIT: 11181 e->command = "voicemail show users"; 11182 e->usage = 11183 "Usage: voicemail show users [for <context>]\n" 11184 " Lists all mailboxes currently set up\n"; 11185 return NULL; 11186 case CLI_GENERATE: 11187 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 11188 } 11189 11190 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 11191 return CLI_SHOWUSAGE; 11192 if (a->argc == 5) { 11193 if (strcmp(a->argv[3],"for")) 11194 return CLI_SHOWUSAGE; 11195 context = a->argv[4]; 11196 } 11197 11198 if (ast_check_realtime("voicemail")) { 11199 if (!context) { 11200 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 11201 return CLI_SHOWUSAGE; 11202 } 11203 return show_users_realtime(a->fd, context); 11204 } 11205 11206 AST_LIST_LOCK(&users); 11207 if (AST_LIST_EMPTY(&users)) { 11208 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 11209 AST_LIST_UNLOCK(&users); 11210 return CLI_FAILURE; 11211 } 11212 if (!context) { 11213 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11214 } else { 11215 int count = 0; 11216 AST_LIST_TRAVERSE(&users, vmu, list) { 11217 if (!strcmp(context, vmu->context)) { 11218 count++; 11219 break; 11220 } 11221 } 11222 if (count) { 11223 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 11224 } else { 11225 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 11226 AST_LIST_UNLOCK(&users); 11227 return CLI_FAILURE; 11228 } 11229 } 11230 AST_LIST_TRAVERSE(&users, vmu, list) { 11231 int newmsgs = 0, oldmsgs = 0; 11232 char count[12], tmp[256] = ""; 11233 11234 if (!context || !strcmp(context, vmu->context)) { 11235 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 11236 inboxcount(tmp, &newmsgs, &oldmsgs); 11237 snprintf(count, sizeof(count), "%d", newmsgs); 11238 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 11239 users_counter++; 11240 } 11241 } 11242 AST_LIST_UNLOCK(&users); 11243 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 11244 return CLI_SUCCESS; 11245 }
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 11248 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.
11249 { 11250 struct vm_zone *zone; 11251 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 11252 char *res = CLI_SUCCESS; 11253 11254 switch (cmd) { 11255 case CLI_INIT: 11256 e->command = "voicemail show zones"; 11257 e->usage = 11258 "Usage: voicemail show zones\n" 11259 " Lists zone message formats\n"; 11260 return NULL; 11261 case CLI_GENERATE: 11262 return NULL; 11263 } 11264 11265 if (a->argc != 3) 11266 return CLI_SHOWUSAGE; 11267 11268 AST_LIST_LOCK(&zones); 11269 if (!AST_LIST_EMPTY(&zones)) { 11270 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 11271 AST_LIST_TRAVERSE(&zones, zone, list) { 11272 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 11273 } 11274 } else { 11275 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 11276 res = CLI_FAILURE; 11277 } 11278 AST_LIST_UNLOCK(&zones); 11279 11280 return res; 11281 }
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 5431 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
05432 { 05433 char tmp[256], *tmp2 = tmp, *box, *context; 05434 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05435 if (ast_strlen_zero(folder)) { 05436 folder = "INBOX"; 05437 } 05438 while ((box = strsep(&tmp2, ",&"))) { 05439 if ((context = strchr(box, '@'))) 05440 *context++ = '\0'; 05441 else 05442 context = "default"; 05443 if (__has_voicemail(context, box, folder, 1)) 05444 return 1; 05445 /* If we are checking INBOX, we should check Urgent as well */ 05446 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05447 return 1; 05448 } 05449 } 05450 return 0; 05451 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5513 of file app_voicemail_imapstorage.c.
References inboxcount2().
05514 { 05515 int urgentmsgs = 0; 05516 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05517 if (newmsgs) { 05518 *newmsgs += urgentmsgs; 05519 } 05520 return res; 05521 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5454 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), inboxcount2(), and strsep().
05455 { 05456 char tmp[256]; 05457 char *context; 05458 05459 /* If no mailbox, return immediately */ 05460 if (ast_strlen_zero(mailbox)) 05461 return 0; 05462 05463 if (newmsgs) 05464 *newmsgs = 0; 05465 if (oldmsgs) 05466 *oldmsgs = 0; 05467 if (urgentmsgs) 05468 *urgentmsgs = 0; 05469 05470 if (strchr(mailbox, ',')) { 05471 int tmpnew, tmpold, tmpurgent; 05472 char *mb, *cur; 05473 05474 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05475 mb = tmp; 05476 while ((cur = strsep(&mb, ", "))) { 05477 if (!ast_strlen_zero(cur)) { 05478 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05479 return -1; 05480 else { 05481 if (newmsgs) 05482 *newmsgs += tmpnew; 05483 if (oldmsgs) 05484 *oldmsgs += tmpold; 05485 if (urgentmsgs) 05486 *urgentmsgs += tmpurgent; 05487 } 05488 } 05489 } 05490 return 0; 05491 } 05492 05493 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05494 05495 if ((context = strchr(tmp, '@'))) 05496 *context++ = '\0'; 05497 else 05498 context = "default"; 05499 05500 if (newmsgs) 05501 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05502 if (oldmsgs) 05503 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05504 if (urgentmsgs) 05505 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05506 05507 return 0; 05508 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4213 of file app_voicemail_imapstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
04214 { 04215 int l; 04216 04217 if (bio->ateof) 04218 return 0; 04219 04220 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04221 if (ferror(fi)) 04222 return -1; 04223 04224 bio->ateof = 1; 04225 return 0; 04226 } 04227 04228 bio->iolen = l; 04229 bio->iocp = 0; 04230 04231 return 1; 04232 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4237 of file app_voicemail_imapstorage.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
04238 { 04239 if (bio->iocp>=bio->iolen) { 04240 if (!inbuf(bio, fi)) 04241 return EOF; 04242 } 04243 04244 return bio->iobuf[bio->iocp++]; 04245 }
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 5053 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.
05054 { 05055 int res; 05056 char fn[PATH_MAX]; 05057 char dest[PATH_MAX]; 05058 05059 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05060 05061 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05062 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05063 return -1; 05064 } 05065 05066 RETRIEVE(fn, -1, ext, context); 05067 if (ast_fileexists(fn, NULL, NULL) > 0) { 05068 res = ast_stream_and_wait(chan, fn, ecodes); 05069 if (res) { 05070 DISPOSE(fn, -1); 05071 return res; 05072 } 05073 } else { 05074 /* Dispose just in case */ 05075 DISPOSE(fn, -1); 05076 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05077 if (res) 05078 return res; 05079 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 05080 if (res) 05081 return res; 05082 } 05083 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05084 return res; 05085 }
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 4032 of file app_voicemail_imapstorage.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
04033 { 04034 int x; 04035 unsigned char map[MAXMSGLIMIT] = ""; 04036 DIR *msgdir; 04037 struct dirent *msgdirent; 04038 int msgdirint; 04039 char extension[4]; 04040 int stopcount = 0; 04041 04042 /* Reading the entire directory into a file map scales better than 04043 * doing a stat repeatedly on a predicted sequence. I suspect this 04044 * is partially due to stat(2) internally doing a readdir(2) itself to 04045 * find each file. */ 04046 if (!(msgdir = opendir(dir))) { 04047 return -1; 04048 } 04049 04050 while ((msgdirent = readdir(msgdir))) { 04051 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04052 map[msgdirint] = 1; 04053 stopcount++; 04054 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04055 } 04056 } 04057 closedir(msgdir); 04058 04059 for (x = 0; x < vmu->maxmsg; x++) { 04060 if (map[x] == 1) { 04061 stopcount--; 04062 } else if (map[x] == 0 && !stopcount) { 04063 break; 04064 } 04065 } 04066 04067 return x - 1; 04068 }
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 5586 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, leave_vm_options::exitcontext, 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.
05587 { 05588 #ifdef IMAP_STORAGE 05589 int newmsgs, oldmsgs; 05590 #else 05591 char urgdir[PATH_MAX]; 05592 #endif 05593 char txtfile[PATH_MAX]; 05594 char tmptxtfile[PATH_MAX]; 05595 struct vm_state *vms = NULL; 05596 char callerid[256]; 05597 FILE *txt; 05598 char date[256]; 05599 int txtdes; 05600 int res = 0; 05601 int msgnum; 05602 int duration = 0; 05603 int sound_duration = 0; 05604 int ausemacro = 0; 05605 int ousemacro = 0; 05606 int ouseexten = 0; 05607 char tmpdur[16]; 05608 char priority[16]; 05609 char origtime[16]; 05610 char dir[PATH_MAX]; 05611 char tmpdir[PATH_MAX]; 05612 char fn[PATH_MAX]; 05613 char prefile[PATH_MAX] = ""; 05614 char tempfile[PATH_MAX] = ""; 05615 char ext_context[256] = ""; 05616 char fmt[80]; 05617 char *context; 05618 char ecodes[17] = "#"; 05619 struct ast_str *tmp = ast_str_create(16); 05620 char *tmpptr; 05621 struct ast_vm_user *vmu; 05622 struct ast_vm_user svm; 05623 const char *category = NULL; 05624 const char *code; 05625 const char *alldtmf = "0123456789ABCD*#"; 05626 char flag[80]; 05627 05628 if (!tmp) { 05629 return -1; 05630 } 05631 05632 ast_str_set(&tmp, 0, "%s", ext); 05633 ext = ast_str_buffer(tmp); 05634 if ((context = strchr(ext, '@'))) { 05635 *context++ = '\0'; 05636 tmpptr = strchr(context, '&'); 05637 } else { 05638 tmpptr = strchr(ext, '&'); 05639 } 05640 05641 if (tmpptr) 05642 *tmpptr++ = '\0'; 05643 05644 ast_channel_lock(chan); 05645 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05646 category = ast_strdupa(category); 05647 } 05648 ast_channel_unlock(chan); 05649 05650 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05651 ast_copy_string(flag, "Urgent", sizeof(flag)); 05652 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05653 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05654 } else { 05655 flag[0] = '\0'; 05656 } 05657 05658 ast_debug(3, "Before find_user\n"); 05659 if (!(vmu = find_user(&svm, context, ext))) { 05660 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05661 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05662 ast_free(tmp); 05663 return res; 05664 } 05665 /* Setup pre-file if appropriate */ 05666 if (strcmp(vmu->context, "default")) 05667 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05668 else 05669 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05670 05671 /* Set the path to the prefile. Will be one of 05672 VM_SPOOL_DIRcontext/ext/busy 05673 VM_SPOOL_DIRcontext/ext/unavail 05674 Depending on the flag set in options. 05675 */ 05676 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05677 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05678 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05679 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05680 } 05681 /* Set the path to the tmpfile as 05682 VM_SPOOL_DIR/context/ext/temp 05683 and attempt to create the folder structure. 05684 */ 05685 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05686 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05687 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05688 ast_free(tmp); 05689 return -1; 05690 } 05691 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05692 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05693 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05694 05695 DISPOSE(tempfile, -1); 05696 /* It's easier just to try to make it than to check for its existence */ 05697 #ifndef IMAP_STORAGE 05698 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05699 #else 05700 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05701 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05702 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05703 } 05704 #endif 05705 05706 /* Check current or macro-calling context for special extensions */ 05707 if (ast_test_flag(vmu, VM_OPERATOR)) { 05708 if (!ast_strlen_zero(vmu->exit)) { 05709 if (ast_exists_extension(chan, vmu->exit, "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 } 05714 } else if (ast_exists_extension(chan, chan->context, "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 ouseexten = 1; 05718 } else if (!ast_strlen_zero(chan->macrocontext) 05719 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05720 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05721 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05722 ousemacro = 1; 05723 } 05724 } 05725 05726 if (!ast_strlen_zero(vmu->exit)) { 05727 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05728 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05729 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05730 } 05731 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05732 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05733 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05734 } else if (!ast_strlen_zero(chan->macrocontext) 05735 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05736 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05737 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05738 ausemacro = 1; 05739 } 05740 05741 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05742 for (code = alldtmf; *code; code++) { 05743 char e[2] = ""; 05744 e[0] = *code; 05745 if (strchr(ecodes, e[0]) == NULL 05746 && ast_canmatch_extension(chan, 05747 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : chan->context), 05748 e, 1, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05749 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05750 } 05751 } 05752 } 05753 05754 /* Play the beginning intro if desired */ 05755 if (!ast_strlen_zero(prefile)) { 05756 #ifdef ODBC_STORAGE 05757 int success = 05758 #endif 05759 RETRIEVE(prefile, -1, ext, context); 05760 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05761 if (ast_streamfile(chan, prefile, chan->language) > -1) 05762 res = ast_waitstream(chan, ecodes); 05763 #ifdef ODBC_STORAGE 05764 if (success == -1) { 05765 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05766 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05767 store_file(prefile, vmu->mailbox, vmu->context, -1); 05768 } 05769 #endif 05770 } else { 05771 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05772 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05773 } 05774 DISPOSE(prefile, -1); 05775 if (res < 0) { 05776 ast_debug(1, "Hang up during prefile playback\n"); 05777 free_user(vmu); 05778 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05779 ast_free(tmp); 05780 return -1; 05781 } 05782 } 05783 if (res == '#') { 05784 /* On a '#' we skip the instructions */ 05785 ast_set_flag(options, OPT_SILENT); 05786 res = 0; 05787 } 05788 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05789 if (vmu->maxmsg == 0) { 05790 if (option_debug > 2) 05791 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05792 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05793 goto leave_vm_out; 05794 } 05795 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05796 res = ast_stream_and_wait(chan, INTRO, ecodes); 05797 if (res == '#') { 05798 ast_set_flag(options, OPT_SILENT); 05799 res = 0; 05800 } 05801 } 05802 if (res > 0) 05803 ast_stopstream(chan); 05804 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05805 other than the operator -- an automated attendant or mailbox login for example */ 05806 if (res == '*') { 05807 chan->exten[0] = 'a'; 05808 chan->exten[1] = '\0'; 05809 if (!ast_strlen_zero(vmu->exit)) { 05810 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05811 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05812 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05813 } 05814 chan->priority = 0; 05815 free_user(vmu); 05816 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05817 ast_free(tmp); 05818 return 0; 05819 } 05820 05821 /* Check for a '0' here */ 05822 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05823 transfer: 05824 if (ouseexten || ousemacro) { 05825 chan->exten[0] = 'o'; 05826 chan->exten[1] = '\0'; 05827 if (!ast_strlen_zero(vmu->exit)) { 05828 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05829 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05830 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05831 } 05832 ast_play_and_wait(chan, "transfer"); 05833 chan->priority = 0; 05834 free_user(vmu); 05835 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05836 } 05837 ast_free(tmp); 05838 return OPERATOR_EXIT; 05839 } 05840 05841 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05842 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05843 if (!ast_strlen_zero(options->exitcontext)) { 05844 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05845 } 05846 free_user(vmu); 05847 ast_free(tmp); 05848 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05849 return res; 05850 } 05851 05852 if (res < 0) { 05853 free_user(vmu); 05854 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05855 ast_free(tmp); 05856 return -1; 05857 } 05858 /* The meat of recording the message... All the announcements and beeps have been played*/ 05859 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05860 if (!ast_strlen_zero(fmt)) { 05861 msgnum = 0; 05862 05863 #ifdef IMAP_STORAGE 05864 /* Is ext a mailbox? */ 05865 /* must open stream for this user to get info! */ 05866 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05867 if (res < 0) { 05868 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05869 ast_free(tmp); 05870 return -1; 05871 } 05872 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05873 /* It is possible under certain circumstances that inboxcount did not 05874 * create a vm_state when it was needed. This is a catchall which will 05875 * rarely be used. 05876 */ 05877 if (!(vms = create_vm_state_from_user(vmu))) { 05878 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05879 ast_free(tmp); 05880 return -1; 05881 } 05882 } 05883 vms->newmessages++; 05884 05885 /* here is a big difference! We add one to it later */ 05886 msgnum = newmsgs + oldmsgs; 05887 ast_debug(3, "Messagecount set to %d\n", msgnum); 05888 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05889 /* set variable for compatibility */ 05890 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05891 05892 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05893 goto leave_vm_out; 05894 } 05895 #else 05896 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05897 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05898 if (!res) 05899 res = ast_waitstream(chan, ""); 05900 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05901 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05902 inprocess_count(vmu->mailbox, vmu->context, -1); 05903 goto leave_vm_out; 05904 } 05905 05906 #endif 05907 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05908 txtdes = mkstemp(tmptxtfile); 05909 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05910 if (txtdes < 0) { 05911 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05912 if (!res) 05913 res = ast_waitstream(chan, ""); 05914 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05915 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05916 inprocess_count(vmu->mailbox, vmu->context, -1); 05917 goto leave_vm_out; 05918 } 05919 05920 /* Now play the beep once we have the message number for our next message. */ 05921 if (res >= 0) { 05922 /* Unless we're *really* silent, try to send the beep */ 05923 res = ast_stream_and_wait(chan, "beep", ""); 05924 } 05925 05926 /* Store information in real-time storage */ 05927 if (ast_check_realtime("voicemail_data")) { 05928 snprintf(priority, sizeof(priority), "%d", chan->priority); 05929 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05930 get_date(date, sizeof(date)); 05931 ast_callerid_merge(callerid, sizeof(callerid), 05932 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05933 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05934 "Unknown"); 05935 ast_store_realtime("voicemail_data", 05936 "origmailbox", ext, 05937 "context", chan->context, 05938 "macrocontext", chan->macrocontext, 05939 "exten", chan->exten, 05940 "priority", priority, 05941 "callerchan", chan->name, 05942 "callerid", callerid, 05943 "origdate", date, 05944 "origtime", origtime, 05945 "category", S_OR(category, ""), 05946 "filename", tmptxtfile, 05947 SENTINEL); 05948 } 05949 05950 /* Store information */ 05951 txt = fdopen(txtdes, "w+"); 05952 if (txt) { 05953 get_date(date, sizeof(date)); 05954 ast_callerid_merge(callerid, sizeof(callerid), 05955 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05956 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05957 "Unknown"); 05958 fprintf(txt, 05959 ";\n" 05960 "; Message Information file\n" 05961 ";\n" 05962 "[message]\n" 05963 "origmailbox=%s\n" 05964 "context=%s\n" 05965 "macrocontext=%s\n" 05966 "exten=%s\n" 05967 "rdnis=%s\n" 05968 "priority=%d\n" 05969 "callerchan=%s\n" 05970 "callerid=%s\n" 05971 "origdate=%s\n" 05972 "origtime=%ld\n" 05973 "category=%s\n", 05974 ext, 05975 chan->context, 05976 chan->macrocontext, 05977 chan->exten, 05978 S_COR(chan->redirecting.from.number.valid, 05979 chan->redirecting.from.number.str, "unknown"), 05980 chan->priority, 05981 chan->name, 05982 callerid, 05983 date, (long) time(NULL), 05984 category ? category : ""); 05985 } else { 05986 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05987 inprocess_count(vmu->mailbox, vmu->context, -1); 05988 if (ast_check_realtime("voicemail_data")) { 05989 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05990 } 05991 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05992 goto leave_vm_out; 05993 } 05994 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag); 05995 05996 if (txt) { 05997 fprintf(txt, "flag=%s\n", flag); 05998 if (sound_duration < vmu->minsecs) { 05999 fclose(txt); 06000 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06001 ast_filedelete(tmptxtfile, NULL); 06002 unlink(tmptxtfile); 06003 if (ast_check_realtime("voicemail_data")) { 06004 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06005 } 06006 inprocess_count(vmu->mailbox, vmu->context, -1); 06007 } else { 06008 fprintf(txt, "duration=%d\n", duration); 06009 fclose(txt); 06010 if (vm_lock_path(dir)) { 06011 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06012 /* Delete files */ 06013 ast_filedelete(tmptxtfile, NULL); 06014 unlink(tmptxtfile); 06015 inprocess_count(vmu->mailbox, vmu->context, -1); 06016 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06017 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06018 unlink(tmptxtfile); 06019 ast_unlock_path(dir); 06020 inprocess_count(vmu->mailbox, vmu->context, -1); 06021 if (ast_check_realtime("voicemail_data")) { 06022 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06023 } 06024 } else { 06025 #ifndef IMAP_STORAGE 06026 msgnum = last_message_index(vmu, dir) + 1; 06027 #endif 06028 make_file(fn, sizeof(fn), dir, msgnum); 06029 06030 /* assign a variable with the name of the voicemail file */ 06031 #ifndef IMAP_STORAGE 06032 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06033 #else 06034 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06035 #endif 06036 06037 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06038 ast_filerename(tmptxtfile, fn, NULL); 06039 rename(tmptxtfile, txtfile); 06040 inprocess_count(vmu->mailbox, vmu->context, -1); 06041 06042 /* Properly set permissions on voicemail text descriptor file. 06043 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06044 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06045 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06046 06047 ast_unlock_path(dir); 06048 if (ast_check_realtime("voicemail_data")) { 06049 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 06050 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 06051 } 06052 /* We must store the file first, before copying the message, because 06053 * ODBC storage does the entire copy with SQL. 06054 */ 06055 if (ast_fileexists(fn, NULL, NULL) > 0) { 06056 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 06057 } 06058 06059 /* Are there to be more recipients of this message? */ 06060 while (tmpptr) { 06061 struct ast_vm_user recipu, *recip; 06062 char *exten, *cntx; 06063 06064 exten = strsep(&tmpptr, "&"); 06065 cntx = strchr(exten, '@'); 06066 if (cntx) { 06067 *cntx = '\0'; 06068 cntx++; 06069 } 06070 if ((recip = find_user(&recipu, cntx, exten))) { 06071 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 06072 free_user(recip); 06073 } 06074 } 06075 #ifndef IMAP_STORAGE 06076 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 06077 /* Move the message from INBOX to Urgent folder if this is urgent! */ 06078 char sfn[PATH_MAX]; 06079 char dfn[PATH_MAX]; 06080 int x; 06081 /* It's easier just to try to make it than to check for its existence */ 06082 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 06083 x = last_message_index(vmu, urgdir) + 1; 06084 make_file(sfn, sizeof(sfn), dir, msgnum); 06085 make_file(dfn, sizeof(dfn), urgdir, x); 06086 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 06087 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 06088 /* Notification must happen for this new message in Urgent folder, not INBOX */ 06089 ast_copy_string(fn, dfn, sizeof(fn)); 06090 msgnum = x; 06091 } 06092 #endif 06093 /* Notification needs to happen after the copy, though. */ 06094 if (ast_fileexists(fn, NULL, NULL)) { 06095 #ifdef IMAP_STORAGE 06096 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 06097 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06098 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06099 flag); 06100 #else 06101 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 06102 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 06103 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 06104 flag); 06105 #endif 06106 } 06107 06108 /* Disposal needs to happen after the optional move and copy */ 06109 if (ast_fileexists(fn, NULL, NULL)) { 06110 DISPOSE(dir, msgnum); 06111 } 06112 } 06113 } 06114 } else { 06115 inprocess_count(vmu->mailbox, vmu->context, -1); 06116 } 06117 if (res == '0') { 06118 goto transfer; 06119 } else if (res > 0 && res != 't') 06120 res = 0; 06121 06122 if (sound_duration < vmu->minsecs) 06123 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 06124 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06125 else 06126 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06127 } else 06128 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 06129 leave_vm_out: 06130 free_user(vmu); 06131 06132 #ifdef IMAP_STORAGE 06133 /* expunge message - use UID Expunge if supported on IMAP server*/ 06134 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 06135 if (expungeonhangup == 1) { 06136 ast_mutex_lock(&vms->lock); 06137 #ifdef HAVE_IMAP_TK2006 06138 if (LEVELUIDPLUS (vms->mailstream)) { 06139 mail_expunge_full(vms->mailstream, NIL, EX_UID); 06140 } else 06141 #endif 06142 mail_expunge(vms->mailstream); 06143 ast_mutex_unlock(&vms->lock); 06144 } 06145 #endif 06146 06147 ast_free(tmp); 06148 return res; 06149 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11829 of file app_voicemail_imapstorage.c.
References actual_load_config(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_log(), ast_unload_realtime(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_ERROR, and VOICEMAIL_CONFIG.
11830 { 11831 struct ast_config *cfg, *ucfg; 11832 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11833 int res; 11834 11835 ast_unload_realtime("voicemail"); 11836 ast_unload_realtime("voicemail_data"); 11837 11838 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11839 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11840 return 0; 11841 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11842 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11843 ucfg = NULL; 11844 } 11845 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11846 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11847 ast_config_destroy(ucfg); 11848 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11849 return 0; 11850 } 11851 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11852 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11853 return 0; 11854 } else { 11855 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11856 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11857 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11858 ucfg = NULL; 11859 } 11860 } 11861 11862 res = actual_load_config(reload, cfg, ucfg); 11863 11864 ast_config_destroy(cfg); 11865 ast_config_destroy(ucfg); 11866 11867 return res; 11868 }
static int load_module | ( | void | ) | [static] |
Definition at line 13129 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().
13130 { 13131 int res; 13132 my_umask = umask(0); 13133 umask(my_umask); 13134 13135 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 13136 return AST_MODULE_LOAD_DECLINE; 13137 } 13138 13139 /* compute the location of the voicemail spool directory */ 13140 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 13141 13142 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 13143 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 13144 } 13145 13146 if ((res = load_config(0))) 13147 return res; 13148 13149 res = ast_register_application_xml(app, vm_exec); 13150 res |= ast_register_application_xml(app2, vm_execmain); 13151 res |= ast_register_application_xml(app3, vm_box_exists); 13152 res |= ast_register_application_xml(app4, vmauthenticate); 13153 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 13154 res |= ast_custom_function_register(&mailbox_exists_acf); 13155 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 13156 #ifdef TEST_FRAMEWORK 13157 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 13158 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 13159 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 13160 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 13161 res |= AST_TEST_REGISTER(test_voicemail_load_config); 13162 #endif 13163 13164 if (res) 13165 return res; 13166 13167 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13168 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 13169 13170 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 13171 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 13172 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 13173 13174 return res; 13175 }
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 4530 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(), ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, 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().
04531 { 04532 char date[256]; 04533 char host[MAXHOSTNAMELEN] = ""; 04534 char who[256]; 04535 char bound[256]; 04536 char dur[256]; 04537 struct ast_tm tm; 04538 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04539 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04540 char *greeting_attachment; 04541 char filename[256]; 04542 04543 if (!str1 || !str2) { 04544 ast_free(str1); 04545 ast_free(str2); 04546 return; 04547 } 04548 04549 if (cidnum) { 04550 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04551 } 04552 if (cidname) { 04553 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04554 } 04555 gethostname(host, sizeof(host) - 1); 04556 04557 if (strchr(srcemail, '@')) { 04558 ast_copy_string(who, srcemail, sizeof(who)); 04559 } else { 04560 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04561 } 04562 04563 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04564 if (greeting_attachment) { 04565 *greeting_attachment++ = '\0'; 04566 } 04567 04568 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04569 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04570 fprintf(p, "Date: %s" ENDL, date); 04571 04572 /* Set date format for voicemail mail */ 04573 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04574 04575 if (!ast_strlen_zero(fromstring)) { 04576 struct ast_channel *ast; 04577 if ((ast = ast_dummy_channel_alloc())) { 04578 char *ptr; 04579 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04580 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04581 04582 if (check_mime(ast_str_buffer(str1))) { 04583 int first_line = 1; 04584 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04585 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04586 *ptr = '\0'; 04587 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04588 first_line = 0; 04589 /* Substring is smaller, so this will never grow */ 04590 ast_str_set(&str2, 0, "%s", ptr + 1); 04591 } 04592 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04593 } else { 04594 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04595 } 04596 ast = ast_channel_unref(ast); 04597 } else { 04598 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04599 } 04600 } else { 04601 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04602 } 04603 04604 if (check_mime(vmu->fullname)) { 04605 int first_line = 1; 04606 char *ptr; 04607 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04608 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04609 *ptr = '\0'; 04610 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04611 first_line = 0; 04612 /* Substring is smaller, so this will never grow */ 04613 ast_str_set(&str2, 0, "%s", ptr + 1); 04614 } 04615 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04616 } else { 04617 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04618 } 04619 04620 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04621 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04622 struct ast_channel *ast; 04623 if ((ast = ast_dummy_channel_alloc())) { 04624 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04625 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04626 if (check_mime(ast_str_buffer(str1))) { 04627 int first_line = 1; 04628 char *ptr; 04629 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04630 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04631 *ptr = '\0'; 04632 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04633 first_line = 0; 04634 /* Substring is smaller, so this will never grow */ 04635 ast_str_set(&str2, 0, "%s", ptr + 1); 04636 } 04637 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04638 } else { 04639 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04640 } 04641 ast = ast_channel_unref(ast); 04642 } else { 04643 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04644 } 04645 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04646 if (ast_strlen_zero(flag)) { 04647 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04648 } else { 04649 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04650 } 04651 } else { 04652 if (ast_strlen_zero(flag)) { 04653 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04654 } else { 04655 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04656 } 04657 } 04658 04659 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04660 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04661 if (imap) { 04662 /* additional information needed for IMAP searching */ 04663 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04664 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04665 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04666 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04667 #ifdef IMAP_STORAGE 04668 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04669 #else 04670 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04671 #endif 04672 /* flag added for Urgent */ 04673 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04674 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04675 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04676 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04677 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04678 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04679 if (!ast_strlen_zero(category)) { 04680 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04681 } else { 04682 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04683 } 04684 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04685 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04686 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04687 } 04688 if (!ast_strlen_zero(cidnum)) { 04689 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04690 } 04691 if (!ast_strlen_zero(cidname)) { 04692 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04693 } 04694 fprintf(p, "MIME-Version: 1.0" ENDL); 04695 if (attach_user_voicemail) { 04696 /* Something unique. */ 04697 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04698 (int) getpid(), (unsigned int) ast_random()); 04699 04700 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04701 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04702 fprintf(p, "--%s" ENDL, bound); 04703 } 04704 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04705 if (emailbody || vmu->emailbody) { 04706 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04707 struct ast_channel *ast; 04708 if ((ast = ast_dummy_channel_alloc())) { 04709 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04710 ast_str_substitute_variables(&str1, 0, ast, e_body); 04711 #ifdef IMAP_STORAGE 04712 { 04713 /* Convert body to native line terminators for IMAP backend */ 04714 char *line = ast_str_buffer(str1), *next; 04715 do { 04716 /* Terminate line before outputting it to the file */ 04717 if ((next = strchr(line, '\n'))) { 04718 *next++ = '\0'; 04719 } 04720 fprintf(p, "%s" ENDL, line); 04721 line = next; 04722 } while (!ast_strlen_zero(line)); 04723 } 04724 #else 04725 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04726 #endif 04727 ast = ast_channel_unref(ast); 04728 } else { 04729 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04730 } 04731 } else if (msgnum > -1) { 04732 if (strcmp(vmu->mailbox, mailbox)) { 04733 /* Forwarded type */ 04734 struct ast_config *msg_cfg; 04735 const char *v; 04736 int inttime; 04737 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04738 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04739 /* Retrieve info from VM attribute file */ 04740 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04741 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04742 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04743 strcat(fromfile, ".txt"); 04744 } 04745 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04746 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04747 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04748 } 04749 04750 /* You might be tempted to do origdate, except that a) it's in the wrong 04751 * format, and b) it's missing for IMAP recordings. */ 04752 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04753 struct timeval tv = { inttime, }; 04754 struct ast_tm tm; 04755 ast_localtime(&tv, &tm, NULL); 04756 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04757 } 04758 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04759 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04760 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04761 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04762 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04763 date, origcallerid, origdate); 04764 ast_config_destroy(msg_cfg); 04765 } else { 04766 goto plain_message; 04767 } 04768 } else { 04769 plain_message: 04770 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04771 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04772 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04773 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04774 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04775 } 04776 } else { 04777 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04778 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04779 } 04780 04781 if (imap || attach_user_voicemail) { 04782 if (!ast_strlen_zero(attach2)) { 04783 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04784 ast_debug(5, "creating second attachment filename %s\n", filename); 04785 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04786 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04787 ast_debug(5, "creating attachment filename %s\n", filename); 04788 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04789 } else { 04790 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04791 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04792 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04793 } 04794 } 04795 ast_free(str1); 04796 ast_free(str2); 04797 }
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 11660 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.
11661 { 11662 struct ast_vm_user *vmu = NULL; 11663 const char *id = astman_get_header(m, "ActionID"); 11664 char actionid[128] = ""; 11665 11666 if (!ast_strlen_zero(id)) 11667 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11668 11669 AST_LIST_LOCK(&users); 11670 11671 if (AST_LIST_EMPTY(&users)) { 11672 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11673 AST_LIST_UNLOCK(&users); 11674 return RESULT_SUCCESS; 11675 } 11676 11677 astman_send_ack(s, m, "Voicemail user list will follow"); 11678 11679 AST_LIST_TRAVERSE(&users, vmu, list) { 11680 char dirname[256]; 11681 11682 #ifdef IMAP_STORAGE 11683 int new, old; 11684 inboxcount(vmu->mailbox, &new, &old); 11685 #endif 11686 11687 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11688 astman_append(s, 11689 "%s" 11690 "Event: VoicemailUserEntry\r\n" 11691 "VMContext: %s\r\n" 11692 "VoiceMailbox: %s\r\n" 11693 "Fullname: %s\r\n" 11694 "Email: %s\r\n" 11695 "Pager: %s\r\n" 11696 "ServerEmail: %s\r\n" 11697 "MailCommand: %s\r\n" 11698 "Language: %s\r\n" 11699 "TimeZone: %s\r\n" 11700 "Callback: %s\r\n" 11701 "Dialout: %s\r\n" 11702 "UniqueID: %s\r\n" 11703 "ExitContext: %s\r\n" 11704 "SayDurationMinimum: %d\r\n" 11705 "SayEnvelope: %s\r\n" 11706 "SayCID: %s\r\n" 11707 "AttachMessage: %s\r\n" 11708 "AttachmentFormat: %s\r\n" 11709 "DeleteMessage: %s\r\n" 11710 "VolumeGain: %.2f\r\n" 11711 "CanReview: %s\r\n" 11712 "CallOperator: %s\r\n" 11713 "MaxMessageCount: %d\r\n" 11714 "MaxMessageLength: %d\r\n" 11715 "NewMessageCount: %d\r\n" 11716 #ifdef IMAP_STORAGE 11717 "OldMessageCount: %d\r\n" 11718 "IMAPUser: %s\r\n" 11719 #endif 11720 "\r\n", 11721 actionid, 11722 vmu->context, 11723 vmu->mailbox, 11724 vmu->fullname, 11725 vmu->email, 11726 vmu->pager, 11727 vmu->serveremail, 11728 vmu->mailcmd, 11729 vmu->language, 11730 vmu->zonetag, 11731 vmu->callback, 11732 vmu->dialout, 11733 vmu->uniqueid, 11734 vmu->exit, 11735 vmu->saydurationm, 11736 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11737 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11738 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11739 vmu->attachfmt, 11740 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11741 vmu->volgain, 11742 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11743 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11744 vmu->maxmsg, 11745 vmu->maxsecs, 11746 #ifdef IMAP_STORAGE 11747 new, old, vmu->imapuser 11748 #else 11749 count_messages(vmu, dirname) 11750 #endif 11751 ); 11752 } 11753 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11754 11755 AST_LIST_UNLOCK(&users); 11756 11757 return RESULT_SUCCESS; 11758 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11481 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.
11482 { 11483 while (poll_thread_run) { 11484 struct timespec ts = { 0, }; 11485 struct timeval wait; 11486 11487 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11488 ts.tv_sec = wait.tv_sec; 11489 ts.tv_nsec = wait.tv_usec * 1000; 11490 11491 ast_mutex_lock(&poll_lock); 11492 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11493 ast_mutex_unlock(&poll_lock); 11494 11495 if (!poll_thread_run) 11496 break; 11497 11498 poll_subscribed_mailboxes(); 11499 } 11500 11501 return NULL; 11502 }
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 5380 of file app_voicemail_imapstorage.c.
References __has_voicemail().
05381 { 05382 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05383 }
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 11592 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.
11593 { 11594 struct mwi_sub_task *mwist; 11595 11596 if (ast_event_get_type(event) != AST_EVENT_SUB) 11597 return; 11598 11599 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11600 return; 11601 11602 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11603 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11604 return; 11605 } 11606 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11607 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11608 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11609 11610 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11611 ast_free(mwist); 11612 } 11613 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11566 of file app_voicemail_imapstorage.c.
References ast_calloc, ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, ast_free, ast_log(), ast_taskprocessor_push(), handle_unsubscribe(), LOG_ERROR, mwi_subscription_tps, and mwi_sub_task::uniqueid.
11567 { 11568 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11569 11570 if (!uniqueid) { 11571 ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n"); 11572 return; 11573 } 11574 11575 if (ast_event_get_type(event) != AST_EVENT_UNSUB) { 11576 ast_free(uniqueid); 11577 return; 11578 } 11579 11580 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) { 11581 ast_free(uniqueid); 11582 return; 11583 } 11584 11585 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11586 *uniqueid = u; 11587 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11588 ast_free(uniqueid); 11589 } 11590 }
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 7063 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.
07064 { 07065 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 07066 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 07067 const char *category; 07068 char *myserveremail = serveremail; 07069 07070 ast_channel_lock(chan); 07071 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 07072 category = ast_strdupa(category); 07073 } 07074 ast_channel_unlock(chan); 07075 07076 #ifndef IMAP_STORAGE 07077 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 07078 #else 07079 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 07080 #endif 07081 make_file(fn, sizeof(fn), todir, msgnum); 07082 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 07083 07084 if (!ast_strlen_zero(vmu->attachfmt)) { 07085 if (strstr(fmt, vmu->attachfmt)) 07086 fmt = vmu->attachfmt; 07087 else 07088 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); 07089 } 07090 07091 /* Attach only the first format */ 07092 fmt = ast_strdupa(fmt); 07093 stringp = fmt; 07094 strsep(&stringp, "|"); 07095 07096 if (!ast_strlen_zero(vmu->serveremail)) 07097 myserveremail = vmu->serveremail; 07098 07099 if (!ast_strlen_zero(vmu->email)) { 07100 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 07101 07102 if (attach_user_voicemail) 07103 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 07104 07105 /* XXX possible imap issue, should category be NULL XXX */ 07106 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 07107 07108 if (attach_user_voicemail) 07109 DISPOSE(todir, msgnum); 07110 } 07111 07112 if (!ast_strlen_zero(vmu->pager)) { 07113 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 07114 } 07115 07116 if (ast_test_flag(vmu, VM_DELETE)) 07117 DELETE(todir, msgnum, fn, vmu); 07118 07119 /* Leave voicemail for someone */ 07120 if (ast_app_has_voicemail(ext_context, NULL)) 07121 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 07122 07123 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 07124 07125 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); 07126 run_externnotify(vmu->context, vmu->mailbox, flag); 07127 07128 #ifdef IMAP_STORAGE 07129 vm_delete(fn); /* Delete the file, but not the IMAP message */ 07130 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 07131 vm_imap_delete(NULL, vms->curmsg, vmu); 07132 vms->newmessages--; /* Fix new message count */ 07133 } 07134 #endif 07135 07136 return 0; 07137 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4250 of file app_voicemail_imapstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
04251 { 04252 if (bio->linelength >= BASELINELEN) { 04253 if (fputs(ENDL, so) == EOF) { 04254 return -1; 04255 } 04256 04257 bio->linelength = 0; 04258 } 04259 04260 if (putc(((unsigned char) c), so) == EOF) { 04261 return -1; 04262 } 04263 04264 bio->linelength++; 04265 04266 return 1; 04267 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7912 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.
07913 { 07914 int count_msg, last_msg; 07915 07916 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07917 07918 /* Rename the member vmbox HERE so that we don't try to return before 07919 * we know what's going on. 07920 */ 07921 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07922 07923 /* Faster to make the directory than to check if it exists. */ 07924 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07925 07926 /* traverses directory using readdir (or select query for ODBC) */ 07927 count_msg = count_messages(vmu, vms->curdir); 07928 if (count_msg < 0) { 07929 return count_msg; 07930 } else { 07931 vms->lastmsg = count_msg - 1; 07932 } 07933 07934 if (vm_allocate_dh(vms, vmu, count_msg)) { 07935 return -1; 07936 } 07937 07938 /* 07939 The following test is needed in case sequencing gets messed up. 07940 There appears to be more than one way to mess up sequence, so 07941 we will not try to find all of the root causes--just fix it when 07942 detected. 07943 */ 07944 07945 if (vm_lock_path(vms->curdir)) { 07946 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07947 return ERROR_LOCK_PATH; 07948 } 07949 07950 /* for local storage, checks directory for messages up to maxmsg limit */ 07951 last_msg = last_message_index(vmu, vms->curdir); 07952 ast_unlock_path(vms->curdir); 07953 07954 if (last_msg < -1) { 07955 return last_msg; 07956 } else if (vms->lastmsg != last_msg) { 07957 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); 07958 resequence_mailbox(vmu, vms->curdir, count_msg); 07959 } 07960 07961 return 0; 07962 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7686 of file app_voicemail_imapstorage.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, 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().
07687 { 07688 int res = 0; 07689 char filename[256], *cid; 07690 const char *origtime, *context, *category, *duration, *flag; 07691 struct ast_config *msg_cfg; 07692 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07693 07694 vms->starting = 0; 07695 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07696 adsi_message(chan, vms); 07697 if (!vms->curmsg) { 07698 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07699 } else if (vms->curmsg == vms->lastmsg) { 07700 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07701 } 07702 07703 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07704 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07705 msg_cfg = ast_config_load(filename, config_flags); 07706 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07707 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07708 return 0; 07709 } 07710 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07711 07712 /* Play the word urgent if we are listening to urgent messages */ 07713 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07714 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07715 } 07716 07717 if (!res) { 07718 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07719 /* POLISH syntax */ 07720 if (!strncasecmp(chan->language, "pl", 2)) { 07721 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07722 int ten, one; 07723 char nextmsg[256]; 07724 ten = (vms->curmsg + 1) / 10; 07725 one = (vms->curmsg + 1) % 10; 07726 07727 if (vms->curmsg < 20) { 07728 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07729 res = wait_file2(chan, vms, nextmsg); 07730 } else { 07731 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07732 res = wait_file2(chan, vms, nextmsg); 07733 if (one > 0) { 07734 if (!res) { 07735 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07736 res = wait_file2(chan, vms, nextmsg); 07737 } 07738 } 07739 } 07740 } 07741 if (!res) 07742 res = wait_file2(chan, vms, "vm-message"); 07743 /* HEBREW syntax */ 07744 } else if (!strncasecmp(chan->language, "he", 2)) { 07745 if (!vms->curmsg) { 07746 res = wait_file2(chan, vms, "vm-message"); 07747 res = wait_file2(chan, vms, "vm-first"); 07748 } else if (vms->curmsg == vms->lastmsg) { 07749 res = wait_file2(chan, vms, "vm-message"); 07750 res = wait_file2(chan, vms, "vm-last"); 07751 } else { 07752 res = wait_file2(chan, vms, "vm-message"); 07753 res = wait_file2(chan, vms, "vm-number"); 07754 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07755 } 07756 /* VIETNAMESE syntax */ 07757 } else if (!strncasecmp(chan->language, "vi", 2)) { 07758 if (!vms->curmsg) { 07759 res = wait_file2(chan, vms, "vm-message"); 07760 res = wait_file2(chan, vms, "vm-first"); 07761 } else if (vms->curmsg == vms->lastmsg) { 07762 res = wait_file2(chan, vms, "vm-message"); 07763 res = wait_file2(chan, vms, "vm-last"); 07764 } else { 07765 res = wait_file2(chan, vms, "vm-message"); 07766 res = wait_file2(chan, vms, "vm-number"); 07767 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07768 } 07769 } else { 07770 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07771 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07772 } else { /* DEFAULT syntax */ 07773 res = wait_file2(chan, vms, "vm-message"); 07774 } 07775 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07776 if (!res) { 07777 ast_test_suite_event_notify("PLAYBACK", "Message: message number"); 07778 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07779 } 07780 } 07781 } 07782 } 07783 07784 if (!msg_cfg) { 07785 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07786 return 0; 07787 } 07788 07789 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07790 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07791 DISPOSE(vms->curdir, vms->curmsg); 07792 ast_config_destroy(msg_cfg); 07793 return 0; 07794 } 07795 07796 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07797 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07798 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07799 07800 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07801 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07802 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07803 if (!res) { 07804 res = play_message_category(chan, category); 07805 } 07806 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) { 07807 res = play_message_datetime(chan, vmu, origtime, filename); 07808 } 07809 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) { 07810 res = play_message_callerid(chan, vms, cid, context, 0); 07811 } 07812 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) { 07813 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07814 } 07815 /* Allow pressing '1' to skip envelope / callerid */ 07816 if (res == '1') { 07817 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07818 res = 0; 07819 } 07820 ast_config_destroy(msg_cfg); 07821 07822 if (!res) { 07823 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07824 #ifdef IMAP_STORAGE 07825 ast_mutex_lock(&vms->lock); 07826 #endif 07827 vms->heard[vms->curmsg] = 1; 07828 #ifdef IMAP_STORAGE 07829 ast_mutex_unlock(&vms->lock); 07830 /*IMAP storage stores any prepended message from a forward 07831 * as a separate file from the rest of the message 07832 */ 07833 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07834 wait_file(chan, vms, vms->introfn); 07835 } 07836 #endif 07837 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07838 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07839 res = 0; 07840 } 07841 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07842 } 07843 DISPOSE(vms->curdir, vms->curmsg); 07844 return res; 07845 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7572 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().
07573 { 07574 int res = 0; 07575 int i; 07576 char *callerid, *name; 07577 char prefile[PATH_MAX] = ""; 07578 07579 07580 /* If voicemail cid is not enabled, or we didn't get cid or context from 07581 * the attribute file, leave now. 07582 * 07583 * TODO Still need to change this so that if this function is called by the 07584 * message envelope (and someone is explicitly requesting to hear the CID), 07585 * it does not check to see if CID is enabled in the config file. 07586 */ 07587 if ((cid == NULL)||(context == NULL)) 07588 return res; 07589 07590 /* Strip off caller ID number from name */ 07591 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07592 ast_callerid_parse(cid, &name, &callerid); 07593 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07594 /* Check for internal contexts and only */ 07595 /* say extension when the call didn't come from an internal context in the list */ 07596 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07597 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07598 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07599 break; 07600 } 07601 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07602 if (!res) { 07603 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07604 if (!ast_strlen_zero(prefile)) { 07605 /* See if we can find a recorded name for this person instead of their extension number */ 07606 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07607 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07608 if (!callback) 07609 res = wait_file2(chan, vms, "vm-from"); 07610 res = ast_stream_and_wait(chan, prefile, ""); 07611 } else { 07612 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07613 /* Say "from extension" as one saying to sound smoother */ 07614 if (!callback) 07615 res = wait_file2(chan, vms, "vm-from-extension"); 07616 res = ast_say_digit_str(chan, callerid, "", chan->language); 07617 } 07618 } 07619 } 07620 } else if (!res) { 07621 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07622 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07623 if (!callback) 07624 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07625 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07626 } 07627 } else { 07628 /* Number unknown */ 07629 ast_debug(1, "VM-CID: From an unknown number\n"); 07630 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07631 res = wait_file2(chan, vms, "vm-unknown-caller"); 07632 } 07633 return res; 07634 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7483 of file app_voicemail_imapstorage.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
07484 { 07485 int res = 0; 07486 07487 if (!ast_strlen_zero(category)) 07488 res = ast_play_and_wait(chan, category); 07489 07490 if (res) { 07491 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07492 res = 0; 07493 } 07494 07495 return res; 07496 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7498 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.
07499 { 07500 int res = 0; 07501 struct vm_zone *the_zone = NULL; 07502 time_t t; 07503 07504 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07505 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07506 return 0; 07507 } 07508 07509 /* Does this user have a timezone specified? */ 07510 if (!ast_strlen_zero(vmu->zonetag)) { 07511 /* Find the zone in the list */ 07512 struct vm_zone *z; 07513 AST_LIST_LOCK(&zones); 07514 AST_LIST_TRAVERSE(&zones, z, list) { 07515 if (!strcmp(z->name, vmu->zonetag)) { 07516 the_zone = z; 07517 break; 07518 } 07519 } 07520 AST_LIST_UNLOCK(&zones); 07521 } 07522 07523 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07524 #if 0 07525 /* Set the DIFF_* variables */ 07526 ast_localtime(&t, &time_now, NULL); 07527 tv_now = ast_tvnow(); 07528 ast_localtime(&tv_now, &time_then, NULL); 07529 07530 /* Day difference */ 07531 if (time_now.tm_year == time_then.tm_year) 07532 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07533 else 07534 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07535 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07536 07537 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07538 #endif 07539 if (the_zone) { 07540 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07541 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07542 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07543 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07544 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07545 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07546 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); 07547 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07548 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07549 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07550 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07551 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07552 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07553 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07554 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); 07555 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07556 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07557 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07558 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07559 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07560 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); 07561 } else { 07562 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07563 } 07564 #if 0 07565 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07566 #endif 07567 return res; 07568 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7636 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().
07637 { 07638 int res = 0; 07639 int durationm; 07640 int durations; 07641 /* Verify that we have a duration for the message */ 07642 if (duration == NULL) 07643 return res; 07644 07645 /* Convert from seconds to minutes */ 07646 durations = atoi(duration); 07647 durationm = (durations / 60); 07648 07649 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07650 07651 if ((!res) && (durationm >= minduration)) { 07652 res = wait_file2(chan, vms, "vm-duration"); 07653 07654 /* POLISH syntax */ 07655 if (!strncasecmp(chan->language, "pl", 2)) { 07656 div_t num = div(durationm, 10); 07657 07658 if (durationm == 1) { 07659 res = ast_play_and_wait(chan, "digits/1z"); 07660 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07661 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07662 if (num.rem == 2) { 07663 if (!num.quot) { 07664 res = ast_play_and_wait(chan, "digits/2-ie"); 07665 } else { 07666 res = say_and_wait(chan, durationm - 2 , chan->language); 07667 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07668 } 07669 } else { 07670 res = say_and_wait(chan, durationm, chan->language); 07671 } 07672 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07673 } else { 07674 res = say_and_wait(chan, durationm, chan->language); 07675 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07676 } 07677 /* DEFAULT syntax */ 07678 } else { 07679 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07680 res = wait_file2(chan, vms, "vm-minutes"); 07681 } 07682 } 07683 return res; 07684 }
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 13442 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.
13445 { 13446 /* Record message & let caller review or re-record it, or set options if applicable */ 13447 int res = 0; 13448 int cmd = 0; 13449 int max_attempts = 3; 13450 int attempts = 0; 13451 int recorded = 0; 13452 int msg_exists = 0; 13453 signed char zero_gain = 0; 13454 char tempfile[PATH_MAX]; 13455 char *acceptdtmf = "#"; 13456 char *canceldtmf = ""; 13457 int canceleddtmf = 0; 13458 13459 /* Note that urgent and private are for flagging messages as such in the future */ 13460 13461 /* barf if no pointer passed to store duration in */ 13462 if (duration == NULL) { 13463 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13464 return -1; 13465 } 13466 13467 if (!outsidecaller) 13468 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13469 else 13470 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13471 13472 cmd = '3'; /* Want to start by recording */ 13473 13474 while ((cmd >= 0) && (cmd != 't')) { 13475 switch (cmd) { 13476 case '1': 13477 if (!msg_exists) { 13478 /* In this case, 1 is to record a message */ 13479 cmd = '3'; 13480 break; 13481 } else { 13482 /* Otherwise 1 is to save the existing message */ 13483 ast_verb(3, "Saving message as is\n"); 13484 if (!outsidecaller) 13485 ast_filerename(tempfile, recordfile, NULL); 13486 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13487 if (!outsidecaller) { 13488 /* Saves to IMAP server only if imapgreeting=yes */ 13489 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13490 DISPOSE(recordfile, -1); 13491 } 13492 cmd = 't'; 13493 return res; 13494 } 13495 case '2': 13496 /* Review */ 13497 ast_verb(3, "Reviewing the message\n"); 13498 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13499 break; 13500 case '3': 13501 msg_exists = 0; 13502 /* Record */ 13503 if (recorded == 1) 13504 ast_verb(3, "Re-recording the message\n"); 13505 else 13506 ast_verb(3, "Recording the message\n"); 13507 13508 if (recorded && outsidecaller) { 13509 cmd = ast_play_and_wait(chan, INTRO); 13510 cmd = ast_play_and_wait(chan, "beep"); 13511 } 13512 recorded = 1; 13513 /* 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 */ 13514 if (record_gain) 13515 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13516 if (ast_test_flag(vmu, VM_OPERATOR)) 13517 canceldtmf = "0"; 13518 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, sound_duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13519 if (strchr(canceldtmf, cmd)) { 13520 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13521 canceleddtmf = 1; 13522 } 13523 if (record_gain) 13524 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13525 if (cmd == -1) { 13526 /* User has hung up, no options to give */ 13527 if (!outsidecaller) { 13528 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13529 ast_filedelete(tempfile, NULL); 13530 } 13531 return cmd; 13532 } 13533 if (cmd == '0') { 13534 break; 13535 } else if (cmd == '*') { 13536 break; 13537 #if 0 13538 } else if (vmu->review && sound_duration && (*sound_duration < 5)) { 13539 /* Message is too short */ 13540 ast_verb(3, "Message too short\n"); 13541 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13542 cmd = ast_filedelete(tempfile, NULL); 13543 break; 13544 } else if (vmu->review && (cmd == 2 && sound_duration && *sound_duration < (maxsilence + 3))) { 13545 /* Message is all silence */ 13546 ast_verb(3, "Nothing recorded\n"); 13547 cmd = ast_filedelete(tempfile, NULL); 13548 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13549 if (!cmd) 13550 cmd = ast_play_and_wait(chan, "vm-speakup"); 13551 break; 13552 #endif 13553 } else { 13554 /* If all is well, a message exists */ 13555 msg_exists = 1; 13556 cmd = 0; 13557 } 13558 break; 13559 case '4': 13560 if (outsidecaller) { /* only mark vm messages */ 13561 /* Mark Urgent */ 13562 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13563 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13564 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13565 strcpy(flag, "Urgent"); 13566 } else if (flag) { 13567 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13568 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13569 strcpy(flag, ""); 13570 } else { 13571 ast_play_and_wait(chan, "vm-sorry"); 13572 } 13573 cmd = 0; 13574 } else { 13575 cmd = ast_play_and_wait(chan, "vm-sorry"); 13576 } 13577 break; 13578 case '5': 13579 case '6': 13580 case '7': 13581 case '8': 13582 case '9': 13583 case '*': 13584 case '#': 13585 cmd = ast_play_and_wait(chan, "vm-sorry"); 13586 break; 13587 #if 0 13588 /* XXX Commented out for the moment because of the dangers of deleting 13589 a message while recording (can put the message numbers out of sync) */ 13590 case '*': 13591 /* Cancel recording, delete message, offer to take another message*/ 13592 cmd = ast_play_and_wait(chan, "vm-deleted"); 13593 cmd = ast_filedelete(tempfile, NULL); 13594 if (outsidecaller) { 13595 res = vm_exec(chan, NULL); 13596 return res; 13597 } 13598 else 13599 return 1; 13600 #endif 13601 case '0': 13602 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13603 cmd = ast_play_and_wait(chan, "vm-sorry"); 13604 break; 13605 } 13606 if (msg_exists || recorded) { 13607 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13608 if (!cmd) 13609 cmd = ast_waitfordigit(chan, 3000); 13610 if (cmd == '1') { 13611 ast_filerename(tempfile, recordfile, NULL); 13612 ast_play_and_wait(chan, "vm-msgsaved"); 13613 cmd = '0'; 13614 } else if (cmd == '4') { 13615 if (flag) { 13616 ast_play_and_wait(chan, "vm-marked-urgent"); 13617 strcpy(flag, "Urgent"); 13618 } 13619 ast_play_and_wait(chan, "vm-msgsaved"); 13620 cmd = '0'; 13621 } else { 13622 ast_play_and_wait(chan, "vm-deleted"); 13623 DELETE(tempfile, -1, tempfile, vmu); 13624 cmd = '0'; 13625 } 13626 } 13627 return cmd; 13628 default: 13629 /* If the caller is an ouside caller, and the review option is enabled, 13630 allow them to review the message, but let the owner of the box review 13631 their OGM's */ 13632 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13633 return cmd; 13634 if (msg_exists) { 13635 cmd = ast_play_and_wait(chan, "vm-review"); 13636 if (!cmd && outsidecaller) { 13637 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13638 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13639 } else if (flag) { 13640 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13641 } 13642 } 13643 } else { 13644 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13645 if (!cmd) 13646 cmd = ast_waitfordigit(chan, 600); 13647 } 13648 13649 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13650 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13651 if (!cmd) 13652 cmd = ast_waitfordigit(chan, 600); 13653 } 13654 #if 0 13655 if (!cmd) 13656 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13657 #endif 13658 if (!cmd) 13659 cmd = ast_waitfordigit(chan, 6000); 13660 if (!cmd) { 13661 attempts++; 13662 } 13663 if (attempts > max_attempts) { 13664 cmd = 't'; 13665 } 13666 } 13667 } 13668 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13669 /* Hang up or timeout, so delete the recording. */ 13670 ast_filedelete(tempfile, NULL); 13671 } 13672 13673 if (cmd != 't' && outsidecaller) 13674 ast_play_and_wait(chan, "vm-goodbye"); 13675 13676 return cmd; 13677 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11453 of file app_voicemail_imapstorage.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
11454 { 11455 int new = 0, old = 0, urgent = 0; 11456 11457 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11458 11459 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11460 mwi_sub->old_urgent = urgent; 11461 mwi_sub->old_new = new; 11462 mwi_sub->old_old = old; 11463 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11464 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11465 } 11466 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11468 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().
11469 { 11470 struct mwi_sub *mwi_sub; 11471 11472 AST_RWLIST_RDLOCK(&mwi_subs); 11473 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11474 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11475 poll_subscribed_mailbox(mwi_sub); 11476 } 11477 } 11478 AST_RWLIST_UNLOCK(&mwi_subs); 11479 }
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 4338 of file app_voicemail_imapstorage.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, 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.
04339 { 04340 char callerid[256]; 04341 char num[12]; 04342 char fromdir[256], fromfile[256]; 04343 struct ast_config *msg_cfg; 04344 const char *origcallerid, *origtime; 04345 char origcidname[80], origcidnum[80], origdate[80]; 04346 int inttime; 04347 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04348 04349 /* Prepare variables for substitution in email body and subject */ 04350 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04351 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04352 snprintf(num, sizeof(num), "%d", msgnum); 04353 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04354 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04355 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04356 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04357 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04358 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04359 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04360 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04361 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04362 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04363 04364 /* Retrieve info from VM attribute file */ 04365 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04366 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04367 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04368 strcat(fromfile, ".txt"); 04369 } 04370 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04371 if (option_debug > 0) { 04372 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04373 } 04374 return; 04375 } 04376 04377 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04378 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04379 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04380 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04381 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04382 } 04383 04384 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04385 struct timeval tv = { inttime, }; 04386 struct ast_tm tm; 04387 ast_localtime(&tv, &tm, NULL); 04388 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04389 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04390 } 04391 ast_config_destroy(msg_cfg); 04392 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 7026 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().
07027 { 07028 struct ast_event *event; 07029 char *mailbox, *context; 07030 07031 /* Strip off @default */ 07032 context = mailbox = ast_strdupa(box); 07033 strsep(&context, "@"); 07034 if (ast_strlen_zero(context)) 07035 context = "default"; 07036 07037 if (!(event = ast_event_new(AST_EVENT_MWI, 07038 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 07039 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 07040 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 07041 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 07042 AST_EVENT_IE_END))) { 07043 return; 07044 } 07045 07046 ast_event_queue_and_cache(event); 07047 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12559 of file app_voicemail_imapstorage.c.
References ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), and LOG_NOTICE.
12559 { 12560 struct ast_config *pwconf; 12561 struct ast_flags config_flags = { 0 }; 12562 12563 pwconf = ast_config_load(secretfn, config_flags); 12564 if (pwconf) { 12565 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12566 if (val) { 12567 ast_copy_string(password, val, passwordlen); 12568 ast_config_destroy(pwconf); 12569 return; 12570 } 12571 ast_config_destroy(pwconf); 12572 } 12573 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12574 }
static int reload | ( | void | ) | [static] |
Definition at line 13089 of file app_voicemail_imapstorage.c.
References load_config().
13090 { 13091 return load_config(1); 13092 }
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 4008 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
04009 { 04010 char stxt[PATH_MAX]; 04011 char dtxt[PATH_MAX]; 04012 ast_filerename(sfn, dfn, NULL); 04013 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 04014 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 04015 if (ast_check_realtime("voicemail_data")) { 04016 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 04017 } 04018 rename(stxt, dtxt); 04019 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6152 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().
06153 { 06154 /* we know the actual number of messages, so stop process when number is hit */ 06155 06156 int x, dest; 06157 char sfn[PATH_MAX]; 06158 char dfn[PATH_MAX]; 06159 06160 if (vm_lock_path(dir)) { 06161 return ERROR_LOCK_PATH; 06162 } 06163 06164 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06165 make_file(sfn, sizeof(sfn), dir, x); 06166 if (EXISTS(dir, x, sfn, NULL)) { 06167 06168 if (x != dest) { 06169 make_file(dfn, sizeof(dfn), dir, dest); 06170 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06171 } 06172 06173 dest++; 06174 } 06175 } 06176 ast_unlock_path(dir); 06177 06178 return dest; 06179 }
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 5523 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.
05524 { 05525 char arguments[255]; 05526 char ext_context[256] = ""; 05527 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05528 struct ast_smdi_mwi_message *mwi_msg; 05529 05530 if (!ast_strlen_zero(context)) 05531 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05532 else 05533 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05534 05535 if (smdi_iface) { 05536 if (ast_app_has_voicemail(ext_context, NULL)) 05537 ast_smdi_mwi_set(smdi_iface, extension); 05538 else 05539 ast_smdi_mwi_unset(smdi_iface, extension); 05540 05541 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05542 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05543 if (!strncmp(mwi_msg->cause, "INV", 3)) 05544 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05545 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05546 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05547 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05548 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05549 } else { 05550 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05551 } 05552 } 05553 05554 if (!ast_strlen_zero(externnotify)) { 05555 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05556 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05557 } else { 05558 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05559 ast_debug(1, "Executing %s\n", arguments); 05560 ast_safe_system(arguments); 05561 } 05562 } 05563 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6189 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().
06190 { 06191 #ifdef IMAP_STORAGE 06192 /* we must use mbox(x) folder names, and copy the message there */ 06193 /* simple. huh? */ 06194 char sequence[10]; 06195 char mailbox[256]; 06196 int res; 06197 06198 /* get the real IMAP message number for this message */ 06199 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06200 06201 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06202 ast_mutex_lock(&vms->lock); 06203 /* if save to Old folder, put in INBOX as read */ 06204 if (box == OLD_FOLDER) { 06205 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06206 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06207 } else if (box == NEW_FOLDER) { 06208 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06209 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06210 } 06211 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06212 ast_mutex_unlock(&vms->lock); 06213 return 0; 06214 } 06215 /* Create the folder if it don't exist */ 06216 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06217 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06218 if (mail_create(vms->mailstream, mailbox) == NIL) 06219 ast_debug(5, "Folder exists.\n"); 06220 else 06221 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06222 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06223 ast_mutex_unlock(&vms->lock); 06224 return res; 06225 #else 06226 char *dir = vms->curdir; 06227 char *username = vms->username; 06228 char *context = vmu->context; 06229 char sfn[PATH_MAX]; 06230 char dfn[PATH_MAX]; 06231 char ddir[PATH_MAX]; 06232 const char *dbox = mbox(vmu, box); 06233 int x, i; 06234 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06235 06236 if (vm_lock_path(ddir)) 06237 return ERROR_LOCK_PATH; 06238 06239 x = last_message_index(vmu, ddir) + 1; 06240 06241 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06242 x--; 06243 for (i = 1; i <= x; i++) { 06244 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06245 make_file(sfn, sizeof(sfn), ddir, i); 06246 make_file(dfn, sizeof(dfn), ddir, i - 1); 06247 if (EXISTS(ddir, i, sfn, NULL)) { 06248 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06249 } else 06250 break; 06251 } 06252 } else { 06253 if (x >= vmu->maxmsg) { 06254 ast_unlock_path(ddir); 06255 return -1; 06256 } 06257 } 06258 make_file(sfn, sizeof(sfn), dir, msg); 06259 make_file(dfn, sizeof(dfn), ddir, x); 06260 if (strcmp(sfn, dfn)) { 06261 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06262 } 06263 ast_unlock_path(ddir); 06264 #endif 06265 return 0; 06266 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6182 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, and ast_say_number().
06183 { 06184 int d; 06185 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06186 return d; 06187 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12545 of file app_voicemail_imapstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, RETRIEVE, and VM_SPOOL_DIR.
12546 { 12547 int res = -1; 12548 char dir[PATH_MAX]; 12549 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12550 ast_debug(2, "About to try retrieving name file %s\n", dir); 12551 RETRIEVE(dir, -1, mailbox, context); 12552 if (ast_fileexists(dir, NULL, NULL)) { 12553 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12554 } 12555 DISPOSE(dir, -1); 12556 return res; 12557 }
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 4853 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().
04854 { 04855 FILE *p = NULL; 04856 char tmp[80] = "/tmp/astmail-XXXXXX"; 04857 char tmp2[256]; 04858 char *stringp; 04859 04860 if (vmu && ast_strlen_zero(vmu->email)) { 04861 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04862 return(0); 04863 } 04864 04865 /* Mail only the first format */ 04866 format = ast_strdupa(format); 04867 stringp = format; 04868 strsep(&stringp, "|"); 04869 04870 if (!strcmp(format, "wav49")) 04871 format = "WAV"; 04872 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)); 04873 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04874 command hangs */ 04875 if ((p = vm_mkftemp(tmp)) == NULL) { 04876 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04877 return -1; 04878 } else { 04879 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04880 fclose(p); 04881 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04882 ast_safe_system(tmp2); 04883 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04884 } 04885 return 0; 04886 }
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 4888 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(), 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().
04889 { 04890 char enc_cidnum[256], enc_cidname[256]; 04891 char date[256]; 04892 char host[MAXHOSTNAMELEN] = ""; 04893 char who[256]; 04894 char dur[PATH_MAX]; 04895 char tmp[80] = "/tmp/astmail-XXXXXX"; 04896 char tmp2[PATH_MAX]; 04897 struct ast_tm tm; 04898 FILE *p; 04899 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04900 04901 if (!str1 || !str2) { 04902 ast_free(str1); 04903 ast_free(str2); 04904 return -1; 04905 } 04906 04907 if (cidnum) { 04908 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04909 } 04910 if (cidname) { 04911 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04912 } 04913 04914 if ((p = vm_mkftemp(tmp)) == NULL) { 04915 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04916 ast_free(str1); 04917 ast_free(str2); 04918 return -1; 04919 } 04920 gethostname(host, sizeof(host)-1); 04921 if (strchr(srcemail, '@')) { 04922 ast_copy_string(who, srcemail, sizeof(who)); 04923 } else { 04924 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04925 } 04926 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04927 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04928 fprintf(p, "Date: %s\n", date); 04929 04930 /* Reformat for custom pager format */ 04931 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04932 04933 if (!ast_strlen_zero(pagerfromstring)) { 04934 struct ast_channel *ast; 04935 if ((ast = ast_dummy_channel_alloc())) { 04936 char *ptr; 04937 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04938 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04939 04940 if (check_mime(ast_str_buffer(str1))) { 04941 int first_line = 1; 04942 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04943 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04944 *ptr = '\0'; 04945 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04946 first_line = 0; 04947 /* Substring is smaller, so this will never grow */ 04948 ast_str_set(&str2, 0, "%s", ptr + 1); 04949 } 04950 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04951 } else { 04952 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04953 } 04954 ast = ast_channel_unref(ast); 04955 } else { 04956 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04957 } 04958 } else { 04959 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04960 } 04961 04962 if (check_mime(vmu->fullname)) { 04963 int first_line = 1; 04964 char *ptr; 04965 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04966 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04967 *ptr = '\0'; 04968 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04969 first_line = 0; 04970 /* Substring is smaller, so this will never grow */ 04971 ast_str_set(&str2, 0, "%s", ptr + 1); 04972 } 04973 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04974 } else { 04975 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04976 } 04977 04978 if (!ast_strlen_zero(pagersubject)) { 04979 struct ast_channel *ast; 04980 if ((ast = ast_dummy_channel_alloc())) { 04981 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04982 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04983 if (check_mime(ast_str_buffer(str1))) { 04984 int first_line = 1; 04985 char *ptr; 04986 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04987 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04988 *ptr = '\0'; 04989 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04990 first_line = 0; 04991 /* Substring is smaller, so this will never grow */ 04992 ast_str_set(&str2, 0, "%s", ptr + 1); 04993 } 04994 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04995 } else { 04996 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04997 } 04998 ast = ast_channel_unref(ast); 04999 } else { 05000 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05001 } 05002 } else { 05003 if (ast_strlen_zero(flag)) { 05004 fprintf(p, "Subject: New VM\n\n"); 05005 } else { 05006 fprintf(p, "Subject: New %s VM\n\n", flag); 05007 } 05008 } 05009 05010 if (pagerbody) { 05011 struct ast_channel *ast; 05012 if ((ast = ast_dummy_channel_alloc())) { 05013 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 05014 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 05015 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 05016 ast = ast_channel_unref(ast); 05017 } else { 05018 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 05019 } 05020 } else { 05021 fprintf(p, "New %s long %s msg in box %s\n" 05022 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 05023 } 05024 05025 fclose(p); 05026 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 05027 ast_safe_system(tmp2); 05028 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 05029 ast_free(str1); 05030 ast_free(str2); 05031 return 0; 05032 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 11108 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.
11109 { 11110 struct ast_config *cfg; 11111 const char *cat = NULL; 11112 11113 if (!(cfg = ast_load_realtime_multientry("voicemail", 11114 "context", context, SENTINEL))) { 11115 return CLI_FAILURE; 11116 } 11117 11118 ast_cli(fd, 11119 "\n" 11120 "=============================================================\n" 11121 "=== Configured Voicemail Users ==============================\n" 11122 "=============================================================\n" 11123 "===\n"); 11124 11125 while ((cat = ast_category_browse(cfg, cat))) { 11126 struct ast_variable *var = NULL; 11127 ast_cli(fd, 11128 "=== Mailbox ...\n" 11129 "===\n"); 11130 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 11131 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 11132 ast_cli(fd, 11133 "===\n" 11134 "=== ---------------------------------------------------------\n" 11135 "===\n"); 11136 } 11137 11138 ast_cli(fd, 11139 "=============================================================\n" 11140 "\n"); 11141 11142 ast_config_destroy(cfg); 11143 11144 return CLI_SUCCESS; 11145 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11615 of file app_voicemail_imapstorage.c.
References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_log(), ast_pthread_create, LOG_ERROR, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), mwi_unsub_sub, poll_thread, and poll_thread_run.
11616 { 11617 int errcode; 11618 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11619 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11620 AST_EVENT_IE_END); 11621 11622 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11623 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11624 AST_EVENT_IE_END); 11625 11626 if (mwi_sub_sub) 11627 ast_event_report_subs(mwi_sub_sub); 11628 11629 poll_thread_run = 1; 11630 11631 if ((errcode = ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL))) { 11632 ast_log(LOG_ERROR, "Could not create thread: %s\n", strerror(errcode)); 11633 } 11634 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11636 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.
11637 { 11638 poll_thread_run = 0; 11639 11640 if (mwi_sub_sub) { 11641 ast_event_unsubscribe(mwi_sub_sub); 11642 mwi_sub_sub = NULL; 11643 } 11644 11645 if (mwi_unsub_sub) { 11646 ast_event_unsubscribe(mwi_unsub_sub); 11647 mwi_unsub_sub = NULL; 11648 } 11649 11650 ast_mutex_lock(&poll_lock); 11651 ast_cond_signal(&poll_cond); 11652 ast_mutex_unlock(&poll_lock); 11653 11654 pthread_join(poll_thread, NULL); 11655 11656 poll_thread = AST_PTHREADT_NULL; 11657 }
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 11782 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.
11783 { 11784 char *current; 11785 11786 /* Add 16 for fudge factor */ 11787 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11788 11789 ast_str_reset(str); 11790 11791 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11792 for (current = (char *) value; *current; current++) { 11793 if (*current == '\\') { 11794 current++; 11795 if (!*current) { 11796 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11797 break; 11798 } 11799 switch (*current) { 11800 case '\\': 11801 ast_str_append(&str, 0, "\\"); 11802 break; 11803 case 'r': 11804 ast_str_append(&str, 0, "\r"); 11805 break; 11806 case 'n': 11807 #ifdef IMAP_STORAGE 11808 if (!str->used || str->str[str->used - 1] != '\r') { 11809 ast_str_append(&str, 0, "\r"); 11810 } 11811 #endif 11812 ast_str_append(&str, 0, "\n"); 11813 break; 11814 case 't': 11815 ast_str_append(&str, 0, "\t"); 11816 break; 11817 default: 11818 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11819 break; 11820 } 11821 } else { 11822 ast_str_append(&str, 0, "%c", *current); 11823 } 11824 } 11825 11826 return ast_str_buffer(str); 11827 }
static int unload_module | ( | void | ) | [static] |
Definition at line 13094 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().
13095 { 13096 int res; 13097 13098 res = ast_unregister_application(app); 13099 res |= ast_unregister_application(app2); 13100 res |= ast_unregister_application(app3); 13101 res |= ast_unregister_application(app4); 13102 res |= ast_unregister_application(sayname_app); 13103 res |= ast_custom_function_unregister(&mailbox_exists_acf); 13104 res |= ast_manager_unregister("VoicemailUsersList"); 13105 res |= ast_data_unregister(NULL); 13106 #ifdef TEST_FRAMEWORK 13107 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 13108 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 13109 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 13110 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 13111 res |= AST_TEST_UNREGISTER(test_voicemail_load_config); 13112 #endif 13113 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 13114 ast_uninstall_vm_functions(); 13115 ao2_ref(inprocess_container, -1); 13116 13117 if (poll_thread != AST_PTHREADT_NULL) 13118 stop_poll_thread(); 13119 13120 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 13121 ast_unload_realtime("voicemail"); 13122 ast_unload_realtime("voicemail_data"); 13123 13124 free_vm_users(); 13125 free_vm_zones(); 13126 return res; 13127 }
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_free, 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 01762 /* remove old allocation */ 01763 if (vms->deleted) { 01764 ast_free(vms->deleted); 01765 vms->deleted = NULL; 01766 } 01767 if (vms->heard) { 01768 ast_free(vms->heard); 01769 vms->heard = NULL; 01770 } 01771 vms->dh_arraysize = 0; 01772 01773 if (arraysize > 0) { 01774 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01775 return -1; 01776 } 01777 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01778 ast_free(vms->deleted); 01779 vms->deleted = NULL; 01780 return -1; 01781 } 01782 vms->dh_arraysize = arraysize; 01783 } 01784 01785 return 0; 01786 }
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 9784 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.
09787 { 09788 int useadsi = 0, valid = 0, logretries = 0; 09789 char password[AST_MAX_EXTENSION]="", *passptr; 09790 struct ast_vm_user vmus, *vmu = NULL; 09791 09792 /* If ADSI is supported, setup login screen */ 09793 adsi_begin(chan, &useadsi); 09794 if (!skipuser && useadsi) 09795 adsi_login(chan); 09796 ast_test_suite_event_notify("PLAYBACK", "Message: vm-login"); 09797 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09798 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09799 return -1; 09800 } 09801 09802 /* Authenticate them and get their mailbox/password */ 09803 09804 while (!valid && (logretries < max_logins)) { 09805 /* Prompt for, and read in the username */ 09806 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09807 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09808 return -1; 09809 } 09810 if (ast_strlen_zero(mailbox)) { 09811 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09812 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09813 } else { 09814 ast_verb(3, "Username not entered\n"); 09815 return -1; 09816 } 09817 } else if (mailbox[0] == '*') { 09818 /* user entered '*' */ 09819 ast_verb(4, "Mailbox begins with '*', attempting jump to extension 'a'\n"); 09820 if (ast_exists_extension(chan, chan->context, "a", 1, 09821 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09822 return -1; 09823 } 09824 ast_verb(4, "Jump to extension 'a' failed; setting mailbox to NULL\n"); 09825 mailbox[0] = '\0'; 09826 } 09827 09828 if (useadsi) 09829 adsi_password(chan); 09830 09831 if (!ast_strlen_zero(prefix)) { 09832 char fullusername[80] = ""; 09833 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09834 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09835 ast_copy_string(mailbox, fullusername, mailbox_size); 09836 } 09837 09838 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09839 vmu = find_user(&vmus, context, mailbox); 09840 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09841 /* saved password is blank, so don't bother asking */ 09842 password[0] = '\0'; 09843 } else { 09844 ast_test_suite_event_notify("PLAYBACK", "Message: %s", vm_password); 09845 if (ast_streamfile(chan, vm_password, chan->language)) { 09846 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09847 return -1; 09848 } 09849 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09850 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09851 return -1; 09852 } else if (password[0] == '*') { 09853 /* user entered '*' */ 09854 ast_verb(4, "Password begins with '*', attempting jump to extension 'a'\n"); 09855 if (ast_exists_extension(chan, chan->context, "a", 1, 09856 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09857 mailbox[0] = '*'; 09858 return -1; 09859 } 09860 ast_verb(4, "Jump to extension 'a' failed; setting mailbox and user to NULL\n"); 09861 mailbox[0] = '\0'; 09862 /* if the password entered was '*', do not let a user mailbox be created if the extension 'a' is not defined */ 09863 vmu = NULL; 09864 } 09865 } 09866 09867 if (vmu) { 09868 passptr = vmu->password; 09869 if (passptr[0] == '-') passptr++; 09870 } 09871 if (vmu && !strcmp(passptr, password)) 09872 valid++; 09873 else { 09874 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09875 if (!ast_strlen_zero(prefix)) 09876 mailbox[0] = '\0'; 09877 } 09878 logretries++; 09879 if (!valid) { 09880 if (skipuser || logretries >= max_logins) { 09881 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect"); 09882 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09883 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09884 return -1; 09885 } 09886 } else { 09887 ast_test_suite_event_notify("PLAYBACK", "Message: vm-incorrect-mailbox"); 09888 if (useadsi) 09889 adsi_login(chan); 09890 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09891 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09892 return -1; 09893 } 09894 } 09895 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09896 return -1; 09897 } 09898 } 09899 if (!valid && (logretries >= max_logins)) { 09900 ast_stopstream(chan); 09901 ast_play_and_wait(chan, "vm-goodbye"); 09902 return -1; 09903 } 09904 if (vmu && !skipuser) { 09905 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09906 } 09907 return 0; 09908 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11003 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().
11004 { 11005 struct ast_vm_user svm; 11006 char *context, *box; 11007 AST_DECLARE_APP_ARGS(args, 11008 AST_APP_ARG(mbox); 11009 AST_APP_ARG(options); 11010 ); 11011 static int dep_warning = 0; 11012 11013 if (ast_strlen_zero(data)) { 11014 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 11015 return -1; 11016 } 11017 11018 if (!dep_warning) { 11019 dep_warning = 1; 11020 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 11021 } 11022 11023 box = ast_strdupa(data); 11024 11025 AST_STANDARD_APP_ARGS(args, box); 11026 11027 if (args.options) { 11028 } 11029 11030 if ((context = strchr(args.mbox, '@'))) { 11031 *context = '\0'; 11032 context++; 11033 } 11034 11035 if (find_user(&svm, context, args.mbox)) { 11036 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 11037 } else 11038 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 11039 11040 return 0; 11041 }
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 9763 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().
09764 { 09765 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09766 return vm_browse_messages_es(chan, vms, vmu); 09767 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09768 return vm_browse_messages_gr(chan, vms, vmu); 09769 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09770 return vm_browse_messages_he(chan, vms, vmu); 09771 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09772 return vm_browse_messages_it(chan, vms, vmu); 09773 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09774 return vm_browse_messages_pt(chan, vms, vmu); 09775 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09776 return vm_browse_messages_vi(chan, vms, vmu); 09777 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09778 return vm_browse_messages_zh(chan, vms, vmu); 09779 } else { /* Default to English syntax */ 09780 return vm_browse_messages_en(chan, vms, vmu); 09781 } 09782 }
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 9602 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09603 { 09604 int cmd = 0; 09605 09606 if (vms->lastmsg > -1) { 09607 cmd = play_message(chan, vmu, vms); 09608 } else { 09609 cmd = ast_play_and_wait(chan, "vm-youhave"); 09610 if (!cmd) 09611 cmd = ast_play_and_wait(chan, "vm-no"); 09612 if (!cmd) { 09613 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09614 cmd = ast_play_and_wait(chan, vms->fn); 09615 } 09616 if (!cmd) 09617 cmd = ast_play_and_wait(chan, "vm-messages"); 09618 } 09619 return cmd; 09620 }
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 9656 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09657 { 09658 int cmd; 09659 09660 if (vms->lastmsg > -1) { 09661 cmd = play_message(chan, vmu, vms); 09662 } else { 09663 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09664 if (!cmd) 09665 cmd = ast_play_and_wait(chan, "vm-messages"); 09666 if (!cmd) { 09667 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09668 cmd = ast_play_and_wait(chan, vms->fn); 09669 } 09670 } 09671 return cmd; 09672 }
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 9550 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.
09551 { 09552 int cmd = 0; 09553 09554 if (vms->lastmsg > -1) { 09555 cmd = play_message(chan, vmu, vms); 09556 } else { 09557 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09558 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09559 if (!cmd) { 09560 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09561 cmd = ast_play_and_wait(chan, vms->fn); 09562 } 09563 if (!cmd) 09564 cmd = ast_play_and_wait(chan, "vm-messages"); 09565 } else { 09566 if (!cmd) 09567 cmd = ast_play_and_wait(chan, "vm-messages"); 09568 if (!cmd) { 09569 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09570 cmd = ast_play_and_wait(chan, vms->fn); 09571 } 09572 } 09573 } 09574 return cmd; 09575 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9578 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
09579 { 09580 int cmd = 0; 09581 09582 if (vms->lastmsg > -1) { 09583 cmd = play_message(chan, vmu, vms); 09584 } else { 09585 if (!strcasecmp(vms->fn, "INBOX")) { 09586 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09587 } else { 09588 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09589 } 09590 } 09591 return cmd; 09592 }
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 9630 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09631 { 09632 int cmd; 09633 09634 if (vms->lastmsg > -1) { 09635 cmd = play_message(chan, vmu, vms); 09636 } else { 09637 cmd = ast_play_and_wait(chan, "vm-no"); 09638 if (!cmd) 09639 cmd = ast_play_and_wait(chan, "vm-message"); 09640 if (!cmd) { 09641 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09642 cmd = ast_play_and_wait(chan, vms->fn); 09643 } 09644 } 09645 return cmd; 09646 }
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 9682 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09683 { 09684 int cmd; 09685 09686 if (vms->lastmsg > -1) { 09687 cmd = play_message(chan, vmu, vms); 09688 } else { 09689 cmd = ast_play_and_wait(chan, "vm-no"); 09690 if (!cmd) { 09691 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09692 cmd = ast_play_and_wait(chan, vms->fn); 09693 } 09694 if (!cmd) 09695 cmd = ast_play_and_wait(chan, "vm-messages"); 09696 } 09697 return cmd; 09698 }
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 9736 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09737 { 09738 int cmd = 0; 09739 09740 if (vms->lastmsg > -1) { 09741 cmd = play_message(chan, vmu, vms); 09742 } else { 09743 cmd = ast_play_and_wait(chan, "vm-no"); 09744 if (!cmd) { 09745 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09746 cmd = ast_play_and_wait(chan, vms->fn); 09747 } 09748 } 09749 return cmd; 09750 }
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 9708 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09709 { 09710 int cmd; 09711 09712 if (vms->lastmsg > -1) { 09713 cmd = play_message(chan, vmu, vms); 09714 } else { 09715 cmd = ast_play_and_wait(chan, "vm-you"); 09716 if (!cmd) 09717 cmd = ast_play_and_wait(chan, "vm-haveno"); 09718 if (!cmd) 09719 cmd = ast_play_and_wait(chan, "vm-messages"); 09720 if (!cmd) { 09721 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09722 cmd = ast_play_and_wait(chan, vms->fn); 09723 } 09724 } 09725 return cmd; 09726 }
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_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 (!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 4192 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04193 { 04194 char *txt; 04195 int txtsize = 0; 04196 04197 txtsize = (strlen(file) + 5)*sizeof(char); 04198 txt = alloca(txtsize); 04199 /* Sprintf here would safe because we alloca'd exactly the right length, 04200 * but trying to eliminate all sprintf's anyhow 04201 */ 04202 if (ast_check_realtime("voicemail_data")) { 04203 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04204 } 04205 snprintf(txt, txtsize, "%s.txt", file); 04206 unlink(txt); 04207 return ast_filedelete(file, NULL); 04208 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10662 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.
10663 { 10664 int res = 0; 10665 char *tmp; 10666 struct leave_vm_options leave_options; 10667 struct ast_flags flags = { 0 }; 10668 char *opts[OPT_ARG_ARRAY_SIZE]; 10669 AST_DECLARE_APP_ARGS(args, 10670 AST_APP_ARG(argv0); 10671 AST_APP_ARG(argv1); 10672 ); 10673 10674 memset(&leave_options, 0, sizeof(leave_options)); 10675 10676 if (chan->_state != AST_STATE_UP) 10677 ast_answer(chan); 10678 10679 if (!ast_strlen_zero(data)) { 10680 tmp = ast_strdupa(data); 10681 AST_STANDARD_APP_ARGS(args, tmp); 10682 if (args.argc == 2) { 10683 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10684 return -1; 10685 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10686 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10687 int gain; 10688 10689 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10690 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10691 return -1; 10692 } else { 10693 leave_options.record_gain = (signed char) gain; 10694 } 10695 } 10696 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10697 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10698 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10699 } 10700 } 10701 } else { 10702 char temp[256]; 10703 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10704 if (res < 0) 10705 return res; 10706 if (ast_strlen_zero(temp)) 10707 return 0; 10708 args.argv0 = ast_strdupa(temp); 10709 } 10710 10711 res = leave_voicemail(chan, args.argv0, &leave_options); 10712 if (res == 't') { 10713 ast_play_and_wait(chan, "vm-goodbye"); 10714 res = 0; 10715 } 10716 10717 if (res == OPERATOR_EXIT) { 10718 res = 0; 10719 } 10720 10721 if (res == ERROR_LOCK_PATH) { 10722 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10723 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10724 res = 0; 10725 } 10726 10727 return res; 10728 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9910 of file app_voicemail_imapstorage.c.
References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_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.
09911 { 09912 /* XXX This is, admittedly, some pretty horrendous code. For some 09913 reason it just seemed a lot easier to do with GOTO's. I feel 09914 like I'm back in my GWBASIC days. XXX */ 09915 int res = -1; 09916 int cmd = 0; 09917 int valid = 0; 09918 char prefixstr[80] =""; 09919 char ext_context[256]=""; 09920 int box; 09921 int useadsi = 0; 09922 int skipuser = 0; 09923 struct vm_state vms; 09924 struct ast_vm_user *vmu = NULL, vmus; 09925 char *context = NULL; 09926 int silentexit = 0; 09927 struct ast_flags flags = { 0 }; 09928 signed char record_gain = 0; 09929 int play_auto = 0; 09930 int play_folder = 0; 09931 int in_urgent = 0; 09932 #ifdef IMAP_STORAGE 09933 int deleted = 0; 09934 #endif 09935 09936 /* Add the vm_state to the active list and keep it active */ 09937 memset(&vms, 0, sizeof(vms)); 09938 09939 vms.lastmsg = -1; 09940 09941 memset(&vmus, 0, sizeof(vmus)); 09942 09943 ast_test_suite_event_notify("START", "Message: vm_execmain started"); 09944 if (chan->_state != AST_STATE_UP) { 09945 ast_debug(1, "Before ast_answer\n"); 09946 ast_answer(chan); 09947 } 09948 09949 if (!ast_strlen_zero(data)) { 09950 char *opts[OPT_ARG_ARRAY_SIZE]; 09951 char *parse; 09952 AST_DECLARE_APP_ARGS(args, 09953 AST_APP_ARG(argv0); 09954 AST_APP_ARG(argv1); 09955 ); 09956 09957 parse = ast_strdupa(data); 09958 09959 AST_STANDARD_APP_ARGS(args, parse); 09960 09961 if (args.argc == 2) { 09962 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09963 return -1; 09964 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09965 int gain; 09966 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09967 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09968 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09969 return -1; 09970 } else { 09971 record_gain = (signed char) gain; 09972 } 09973 } else { 09974 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09975 } 09976 } 09977 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09978 play_auto = 1; 09979 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09980 /* See if it is a folder name first */ 09981 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09982 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09983 play_folder = -1; 09984 } 09985 } else { 09986 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09987 } 09988 } else { 09989 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09990 } 09991 if (play_folder > 9 || play_folder < 0) { 09992 ast_log(AST_LOG_WARNING, 09993 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09994 opts[OPT_ARG_PLAYFOLDER]); 09995 play_folder = 0; 09996 } 09997 } 09998 } else { 09999 /* old style options parsing */ 10000 while (*(args.argv0)) { 10001 if (*(args.argv0) == 's') 10002 ast_set_flag(&flags, OPT_SILENT); 10003 else if (*(args.argv0) == 'p') 10004 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 10005 else 10006 break; 10007 (args.argv0)++; 10008 } 10009 10010 } 10011 10012 valid = ast_test_flag(&flags, OPT_SILENT); 10013 10014 if ((context = strchr(args.argv0, '@'))) 10015 *context++ = '\0'; 10016 10017 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 10018 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 10019 else 10020 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 10021 10022 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 10023 skipuser++; 10024 else 10025 valid = 0; 10026 } 10027 10028 if (!valid) 10029 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 10030 10031 ast_debug(1, "After vm_authenticate\n"); 10032 10033 if (vms.username[0] == '*') { 10034 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 10035 10036 /* user entered '*' */ 10037 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10038 ast_test_suite_event_notify("REDIRECT", "Message: redirecting user to 'a' extension"); 10039 res = 0; /* prevent hangup */ 10040 goto out; 10041 } 10042 } 10043 10044 if (!res) { 10045 valid = 1; 10046 if (!skipuser) 10047 vmu = &vmus; 10048 } else { 10049 res = 0; 10050 } 10051 10052 /* If ADSI is supported, setup login screen */ 10053 adsi_begin(chan, &useadsi); 10054 10055 ast_test_suite_assert(valid); 10056 if (!valid) { 10057 goto out; 10058 } 10059 ast_test_suite_event_notify("AUTHENTICATED", "Message: vm_user authenticated"); 10060 10061 #ifdef IMAP_STORAGE 10062 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 10063 pthread_setspecific(ts_vmstate.key, &vms); 10064 10065 vms.interactive = 1; 10066 vms.updated = 1; 10067 if (vmu) 10068 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 10069 vmstate_insert(&vms); 10070 init_vm_state(&vms); 10071 #endif 10072 10073 /* Set language from config to override channel language */ 10074 if (!ast_strlen_zero(vmu->language)) 10075 ast_string_field_set(chan, language, vmu->language); 10076 10077 /* Retrieve urgent, old and new message counts */ 10078 ast_debug(1, "Before open_mailbox\n"); 10079 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10080 if (res < 0) 10081 goto out; 10082 vms.oldmessages = vms.lastmsg + 1; 10083 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 10084 /* check INBOX */ 10085 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10086 if (res < 0) 10087 goto out; 10088 vms.newmessages = vms.lastmsg + 1; 10089 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 10090 /* Start in Urgent */ 10091 in_urgent = 1; 10092 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 10093 if (res < 0) 10094 goto out; 10095 vms.urgentmessages = vms.lastmsg + 1; 10096 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 10097 10098 /* Select proper mailbox FIRST!! */ 10099 if (play_auto) { 10100 ast_test_suite_event_notify("AUTOPLAY", "Message: auto-playing messages"); 10101 if (vms.urgentmessages) { 10102 in_urgent = 1; 10103 res = open_mailbox(&vms, vmu, 11); 10104 } else { 10105 in_urgent = 0; 10106 res = open_mailbox(&vms, vmu, play_folder); 10107 } 10108 if (res < 0) 10109 goto out; 10110 10111 /* If there are no new messages, inform the user and hangup */ 10112 if (vms.lastmsg == -1) { 10113 in_urgent = 0; 10114 cmd = vm_browse_messages(chan, &vms, vmu); 10115 res = 0; 10116 goto out; 10117 } 10118 } else { 10119 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 10120 /* If we only have old messages start here */ 10121 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 10122 in_urgent = 0; 10123 play_folder = 1; 10124 if (res < 0) 10125 goto out; 10126 } else if (!vms.urgentmessages && vms.newmessages) { 10127 /* If we have new messages but none are urgent */ 10128 in_urgent = 0; 10129 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10130 if (res < 0) 10131 goto out; 10132 } 10133 } 10134 10135 if (useadsi) 10136 adsi_status(chan, &vms); 10137 res = 0; 10138 10139 /* Check to see if this is a new user */ 10140 if (!strcasecmp(vmu->mailbox, vmu->password) && 10141 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 10142 if (ast_play_and_wait(chan, "vm-newuser") == -1) 10143 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 10144 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 10145 if ((cmd == 't') || (cmd == '#')) { 10146 /* Timeout */ 10147 ast_test_suite_event_notify("TIMEOUT", "Message: response from user timed out"); 10148 res = 0; 10149 goto out; 10150 } else if (cmd < 0) { 10151 /* Hangup */ 10152 ast_test_suite_event_notify("HANGUP", "Message: hangup detected"); 10153 res = -1; 10154 goto out; 10155 } 10156 } 10157 #ifdef IMAP_STORAGE 10158 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 10159 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 10160 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 10161 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10162 } 10163 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10164 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 10165 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 10166 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10167 } 10168 #endif 10169 10170 ast_test_suite_event_notify("INTRO", "Message: playing intro menu"); 10171 if (play_auto) { 10172 cmd = '1'; 10173 } else { 10174 cmd = vm_intro(chan, vmu, &vms); 10175 } 10176 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10177 10178 vms.repeats = 0; 10179 vms.starting = 1; 10180 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10181 /* Run main menu */ 10182 switch (cmd) { 10183 case '1': /* First message */ 10184 vms.curmsg = 0; 10185 /* Fall through */ 10186 case '5': /* Play current message */ 10187 ast_test_suite_event_notify("BROWSE", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10188 cmd = vm_browse_messages(chan, &vms, vmu); 10189 break; 10190 case '2': /* Change folders */ 10191 ast_test_suite_event_notify("CHANGEFOLDER", "Message: browsing to a different folder"); 10192 if (useadsi) 10193 adsi_folders(chan, 0, "Change to folder..."); 10194 10195 cmd = get_folder2(chan, "vm-changeto", 0); 10196 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10197 if (cmd == '#') { 10198 cmd = 0; 10199 } else if (cmd > 0) { 10200 cmd = cmd - '0'; 10201 res = close_mailbox(&vms, vmu); 10202 if (res == ERROR_LOCK_PATH) 10203 goto out; 10204 /* If folder is not urgent, set in_urgent to zero! */ 10205 if (cmd != 11) in_urgent = 0; 10206 res = open_mailbox(&vms, vmu, cmd); 10207 if (res < 0) 10208 goto out; 10209 play_folder = cmd; 10210 cmd = 0; 10211 } 10212 if (useadsi) 10213 adsi_status2(chan, &vms); 10214 10215 if (!cmd) { 10216 cmd = vm_play_folder_name(chan, vms.vmbox); 10217 } 10218 10219 vms.starting = 1; 10220 vms.curmsg = 0; 10221 break; 10222 case '3': /* Advanced options */ 10223 ast_test_suite_event_notify("ADVOPTIONS", "Message: entering advanced options menu"); 10224 cmd = 0; 10225 vms.repeats = 0; 10226 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 10227 switch (cmd) { 10228 case '1': /* Reply */ 10229 if (vms.lastmsg > -1 && !vms.starting) { 10230 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 10231 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10232 res = cmd; 10233 goto out; 10234 } 10235 } else { 10236 cmd = ast_play_and_wait(chan, "vm-sorry"); 10237 } 10238 cmd = 't'; 10239 break; 10240 case '2': /* Callback */ 10241 if (!vms.starting) 10242 ast_verb(3, "Callback Requested\n"); 10243 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 10244 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 10245 if (cmd == 9) { 10246 silentexit = 1; 10247 goto out; 10248 } else if (cmd == ERROR_LOCK_PATH) { 10249 res = cmd; 10250 goto out; 10251 } 10252 } else { 10253 cmd = ast_play_and_wait(chan, "vm-sorry"); 10254 } 10255 cmd = 't'; 10256 break; 10257 case '3': /* Envelope */ 10258 if (vms.lastmsg > -1 && !vms.starting) { 10259 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 10260 if (cmd == ERROR_LOCK_PATH) { 10261 res = cmd; 10262 goto out; 10263 } 10264 } else { 10265 cmd = ast_play_and_wait(chan, "vm-sorry"); 10266 } 10267 cmd = 't'; 10268 break; 10269 case '4': /* Dialout */ 10270 if (!ast_strlen_zero(vmu->dialout)) { 10271 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10272 if (cmd == 9) { 10273 silentexit = 1; 10274 goto out; 10275 } 10276 } else { 10277 cmd = ast_play_and_wait(chan, "vm-sorry"); 10278 } 10279 cmd = 't'; 10280 break; 10281 10282 case '5': /* Leave VoiceMail */ 10283 if (ast_test_flag(vmu, VM_SVMAIL)) { 10284 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10285 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10286 res = cmd; 10287 goto out; 10288 } 10289 } else { 10290 cmd = ast_play_and_wait(chan, "vm-sorry"); 10291 } 10292 cmd = 't'; 10293 break; 10294 10295 case '*': /* Return to main menu */ 10296 cmd = 't'; 10297 break; 10298 10299 default: 10300 cmd = 0; 10301 if (!vms.starting) { 10302 cmd = ast_play_and_wait(chan, "vm-toreply"); 10303 } 10304 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10305 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10306 } 10307 if (!cmd && !vms.starting) { 10308 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10309 } 10310 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10311 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10312 } 10313 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) { 10314 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10315 } 10316 if (!cmd) { 10317 cmd = ast_play_and_wait(chan, "vm-starmain"); 10318 } 10319 if (!cmd) { 10320 cmd = ast_waitfordigit(chan, 6000); 10321 } 10322 if (!cmd) { 10323 vms.repeats++; 10324 } 10325 if (vms.repeats > 3) { 10326 cmd = 't'; 10327 } 10328 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10329 } 10330 } 10331 if (cmd == 't') { 10332 cmd = 0; 10333 vms.repeats = 0; 10334 } 10335 break; 10336 case '4': /* Go to the previous message */ 10337 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg - 1, vms.curmsg - 1); 10338 if (vms.curmsg > 0) { 10339 vms.curmsg--; 10340 cmd = play_message(chan, vmu, &vms); 10341 } else { 10342 /* Check if we were listening to new 10343 messages. If so, go to Urgent messages 10344 instead of saying "no more messages" 10345 */ 10346 if (in_urgent == 0 && vms.urgentmessages > 0) { 10347 /* Check for Urgent messages */ 10348 in_urgent = 1; 10349 res = close_mailbox(&vms, vmu); 10350 if (res == ERROR_LOCK_PATH) 10351 goto out; 10352 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10353 if (res < 0) 10354 goto out; 10355 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10356 vms.curmsg = vms.lastmsg; 10357 if (vms.lastmsg < 0) { 10358 cmd = ast_play_and_wait(chan, "vm-nomore"); 10359 } 10360 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10361 vms.curmsg = vms.lastmsg; 10362 cmd = play_message(chan, vmu, &vms); 10363 } else { 10364 cmd = ast_play_and_wait(chan, "vm-nomore"); 10365 } 10366 } 10367 break; 10368 case '6': /* Go to the next message */ 10369 ast_test_suite_event_notify("PREVMSG", "Message: browsing message %d\r\nVoicemail: %d", vms.curmsg + 1, vms.curmsg + 1); 10370 if (vms.curmsg < vms.lastmsg) { 10371 vms.curmsg++; 10372 cmd = play_message(chan, vmu, &vms); 10373 } else { 10374 if (in_urgent && vms.newmessages > 0) { 10375 /* Check if we were listening to urgent 10376 * messages. If so, go to regular new messages 10377 * instead of saying "no more messages" 10378 */ 10379 in_urgent = 0; 10380 res = close_mailbox(&vms, vmu); 10381 if (res == ERROR_LOCK_PATH) 10382 goto out; 10383 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10384 if (res < 0) 10385 goto out; 10386 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10387 vms.curmsg = -1; 10388 if (vms.lastmsg < 0) { 10389 cmd = ast_play_and_wait(chan, "vm-nomore"); 10390 } 10391 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10392 vms.curmsg = 0; 10393 cmd = play_message(chan, vmu, &vms); 10394 } else { 10395 cmd = ast_play_and_wait(chan, "vm-nomore"); 10396 } 10397 } 10398 break; 10399 case '7': /* Delete the current message */ 10400 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10401 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10402 if (useadsi) 10403 adsi_delete(chan, &vms); 10404 if (vms.deleted[vms.curmsg]) { 10405 if (play_folder == 0) { 10406 if (in_urgent) { 10407 vms.urgentmessages--; 10408 } else { 10409 vms.newmessages--; 10410 } 10411 } 10412 else if (play_folder == 1) 10413 vms.oldmessages--; 10414 cmd = ast_play_and_wait(chan, "vm-deleted"); 10415 } else { 10416 if (play_folder == 0) { 10417 if (in_urgent) { 10418 vms.urgentmessages++; 10419 } else { 10420 vms.newmessages++; 10421 } 10422 } 10423 else if (play_folder == 1) 10424 vms.oldmessages++; 10425 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10426 } 10427 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10428 if (vms.curmsg < vms.lastmsg) { 10429 vms.curmsg++; 10430 cmd = play_message(chan, vmu, &vms); 10431 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10432 vms.curmsg = 0; 10433 cmd = play_message(chan, vmu, &vms); 10434 } else { 10435 /* Check if we were listening to urgent 10436 messages. If so, go to regular new messages 10437 instead of saying "no more messages" 10438 */ 10439 if (in_urgent == 1) { 10440 /* Check for new messages */ 10441 in_urgent = 0; 10442 res = close_mailbox(&vms, vmu); 10443 if (res == ERROR_LOCK_PATH) 10444 goto out; 10445 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10446 if (res < 0) 10447 goto out; 10448 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10449 vms.curmsg = -1; 10450 if (vms.lastmsg < 0) { 10451 cmd = ast_play_and_wait(chan, "vm-nomore"); 10452 } 10453 } else { 10454 cmd = ast_play_and_wait(chan, "vm-nomore"); 10455 } 10456 } 10457 } 10458 } else /* Delete not valid if we haven't selected a message */ 10459 cmd = 0; 10460 #ifdef IMAP_STORAGE 10461 deleted = 1; 10462 #endif 10463 break; 10464 10465 case '8': /* Forward the current message */ 10466 if (vms.lastmsg > -1) { 10467 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10468 if (cmd == ERROR_LOCK_PATH) { 10469 res = cmd; 10470 goto out; 10471 } 10472 } else { 10473 /* Check if we were listening to urgent 10474 messages. If so, go to regular new messages 10475 instead of saying "no more messages" 10476 */ 10477 if (in_urgent == 1 && vms.newmessages > 0) { 10478 /* Check for new messages */ 10479 in_urgent = 0; 10480 res = close_mailbox(&vms, vmu); 10481 if (res == ERROR_LOCK_PATH) 10482 goto out; 10483 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10484 if (res < 0) 10485 goto out; 10486 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10487 vms.curmsg = -1; 10488 if (vms.lastmsg < 0) { 10489 cmd = ast_play_and_wait(chan, "vm-nomore"); 10490 } 10491 } else { 10492 cmd = ast_play_and_wait(chan, "vm-nomore"); 10493 } 10494 } 10495 break; 10496 case '9': /* Save message to folder */ 10497 ast_test_suite_event_notify("SAVEMSG", "Message: saving message %d\r\nVoicemail: %d", vms.curmsg, vms.curmsg); 10498 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10499 /* No message selected */ 10500 cmd = 0; 10501 break; 10502 } 10503 if (useadsi) 10504 adsi_folders(chan, 1, "Save to folder..."); 10505 cmd = get_folder2(chan, "vm-savefolder", 1); 10506 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 10507 box = 0; /* Shut up compiler */ 10508 if (cmd == '#') { 10509 cmd = 0; 10510 break; 10511 } else if (cmd > 0) { 10512 box = cmd = cmd - '0'; 10513 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10514 if (cmd == ERROR_LOCK_PATH) { 10515 res = cmd; 10516 goto out; 10517 #ifndef IMAP_STORAGE 10518 } else if (!cmd) { 10519 vms.deleted[vms.curmsg] = 1; 10520 #endif 10521 } else { 10522 vms.deleted[vms.curmsg] = 0; 10523 vms.heard[vms.curmsg] = 0; 10524 } 10525 } 10526 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10527 if (useadsi) 10528 adsi_message(chan, &vms); 10529 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10530 if (!cmd) { 10531 cmd = ast_play_and_wait(chan, "vm-message"); 10532 if (!cmd) 10533 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10534 if (!cmd) 10535 cmd = ast_play_and_wait(chan, "vm-savedto"); 10536 if (!cmd) 10537 cmd = vm_play_folder_name(chan, vms.fn); 10538 } else { 10539 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10540 } 10541 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10542 if (vms.curmsg < vms.lastmsg) { 10543 vms.curmsg++; 10544 cmd = play_message(chan, vmu, &vms); 10545 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10546 vms.curmsg = 0; 10547 cmd = play_message(chan, vmu, &vms); 10548 } else { 10549 /* Check if we were listening to urgent 10550 messages. If so, go to regular new messages 10551 instead of saying "no more messages" 10552 */ 10553 if (in_urgent == 1 && vms.newmessages > 0) { 10554 /* Check for new messages */ 10555 in_urgent = 0; 10556 res = close_mailbox(&vms, vmu); 10557 if (res == ERROR_LOCK_PATH) 10558 goto out; 10559 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10560 if (res < 0) 10561 goto out; 10562 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10563 vms.curmsg = -1; 10564 if (vms.lastmsg < 0) { 10565 cmd = ast_play_and_wait(chan, "vm-nomore"); 10566 } 10567 } else { 10568 cmd = ast_play_and_wait(chan, "vm-nomore"); 10569 } 10570 } 10571 } 10572 break; 10573 case '*': /* Help */ 10574 if (!vms.starting) { 10575 cmd = ast_play_and_wait(chan, "vm-onefor"); 10576 if (!strncasecmp(chan->language, "he", 2)) { 10577 cmd = ast_play_and_wait(chan, "vm-for"); 10578 } 10579 if (!cmd) 10580 cmd = vm_play_folder_name(chan, vms.vmbox); 10581 if (!cmd) 10582 cmd = ast_play_and_wait(chan, "vm-opts"); 10583 if (!cmd) 10584 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10585 } else 10586 cmd = 0; 10587 break; 10588 case '0': /* Mailbox options */ 10589 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10590 if (useadsi) 10591 adsi_status(chan, &vms); 10592 break; 10593 default: /* Nothing */ 10594 ast_test_suite_event_notify("PLAYBACK", "Message: instructions"); 10595 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10596 break; 10597 } 10598 } 10599 if ((cmd == 't') || (cmd == '#')) { 10600 /* Timeout */ 10601 res = 0; 10602 } else { 10603 /* Hangup */ 10604 res = -1; 10605 } 10606 10607 out: 10608 if (res > -1) { 10609 ast_stopstream(chan); 10610 adsi_goodbye(chan); 10611 if (valid && res != OPERATOR_EXIT) { 10612 if (silentexit) 10613 res = ast_play_and_wait(chan, "vm-dialout"); 10614 else 10615 res = ast_play_and_wait(chan, "vm-goodbye"); 10616 } 10617 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10618 res = 0; 10619 } 10620 if (useadsi) 10621 ast_adsi_unload_session(chan); 10622 } 10623 if (vmu) 10624 close_mailbox(&vms, vmu); 10625 if (valid) { 10626 int new = 0, old = 0, urgent = 0; 10627 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10628 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10629 /* Urgent flag not passwd to externnotify here */ 10630 run_externnotify(vmu->context, vmu->mailbox, NULL); 10631 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10632 queue_mwi_event(ext_context, urgent, new, old); 10633 } 10634 #ifdef IMAP_STORAGE 10635 /* expunge message - use UID Expunge if supported on IMAP server*/ 10636 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10637 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10638 ast_mutex_lock(&vms.lock); 10639 #ifdef HAVE_IMAP_TK2006 10640 if (LEVELUIDPLUS (vms.mailstream)) { 10641 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10642 } else 10643 #endif 10644 mail_expunge(vms.mailstream); 10645 ast_mutex_unlock(&vms.lock); 10646 } 10647 /* before we delete the state, we should copy pertinent info 10648 * back to the persistent model */ 10649 if (vmu) { 10650 vmstate_delete(&vms); 10651 } 10652 #endif 10653 if (vmu) 10654 free_user(vmu); 10655 10656 #ifdef IMAP_STORAGE 10657 pthread_setspecific(ts_vmstate.key, NULL); 10658 #endif 10659 return res; 10660 }
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 6870 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_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, maxsilence, play_record_review(), silencethreshold, vm_pls_try_again, and vm_prepend_timeout.
06872 { 06873 int cmd = 0; 06874 int retries = 0, prepend_duration = 0, already_recorded = 0; 06875 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06876 char textfile[PATH_MAX]; 06877 struct ast_config *msg_cfg; 06878 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06879 #ifndef IMAP_STORAGE 06880 signed char zero_gain = 0; 06881 #endif 06882 const char *duration_str; 06883 06884 /* Must always populate duration correctly */ 06885 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06886 strcpy(textfile, msgfile); 06887 strcpy(backup, msgfile); 06888 strcpy(backup_textfile, msgfile); 06889 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06890 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06891 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06892 06893 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06894 *duration = atoi(duration_str); 06895 } else { 06896 *duration = 0; 06897 } 06898 06899 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06900 if (cmd) 06901 retries = 0; 06902 switch (cmd) { 06903 case '1': 06904 06905 #ifdef IMAP_STORAGE 06906 /* Record new intro file */ 06907 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06908 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06909 ast_play_and_wait(chan, INTRO); 06910 ast_play_and_wait(chan, "beep"); 06911 cmd = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, NULL, record_gain, vms, flag); 06912 if (cmd == -1) { 06913 break; 06914 } 06915 cmd = 't'; 06916 #else 06917 06918 /* prepend a message to the current message, update the metadata and return */ 06919 06920 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06921 strcpy(textfile, msgfile); 06922 strncat(textfile, ".txt", sizeof(textfile) - 1); 06923 *duration = 0; 06924 06925 /* if we can't read the message metadata, stop now */ 06926 if (!msg_cfg) { 06927 cmd = 0; 06928 break; 06929 } 06930 06931 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06932 #ifndef IMAP_STORAGE 06933 if (already_recorded) { 06934 ast_filecopy(backup, msgfile, NULL); 06935 copy(backup_textfile, textfile); 06936 } 06937 else { 06938 ast_filecopy(msgfile, backup, NULL); 06939 copy(textfile, backup_textfile); 06940 } 06941 #endif 06942 already_recorded = 1; 06943 06944 if (record_gain) 06945 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06946 06947 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, NULL, 1, silencethreshold, maxsilence); 06948 06949 if (cmd == 'S') { /* If we timed out, tell the user it didn't work properly and clean up the files */ 06950 ast_stream_and_wait(chan, vm_pls_try_again, ""); /* this might be removed if a proper vm_prepend_timeout is ever recorded */ 06951 ast_stream_and_wait(chan, vm_prepend_timeout, ""); 06952 ast_filerename(backup, msgfile, NULL); 06953 } 06954 06955 if (record_gain) 06956 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06957 06958 06959 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06960 *duration = atoi(duration_str); 06961 06962 if (prepend_duration) { 06963 struct ast_category *msg_cat; 06964 /* need enough space for a maximum-length message duration */ 06965 char duration_buf[12]; 06966 06967 *duration += prepend_duration; 06968 msg_cat = ast_category_get(msg_cfg, "message"); 06969 snprintf(duration_buf, 11, "%ld", *duration); 06970 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06971 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06972 } 06973 } 06974 06975 #endif 06976 break; 06977 case '2': 06978 /* NULL out introfile so we know there is no intro! */ 06979 #ifdef IMAP_STORAGE 06980 *vms->introfn = '\0'; 06981 #endif 06982 cmd = 't'; 06983 break; 06984 case '*': 06985 cmd = '*'; 06986 break; 06987 default: 06988 /* If time_out and return to menu, reset already_recorded */ 06989 already_recorded = 0; 06990 06991 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06992 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06993 if (!cmd) { 06994 cmd = ast_play_and_wait(chan, "vm-starmain"); 06995 /* "press star to return to the main menu" */ 06996 } 06997 if (!cmd) { 06998 cmd = ast_waitfordigit(chan, 6000); 06999 } 07000 if (!cmd) { 07001 retries++; 07002 } 07003 if (retries > 3) { 07004 cmd = '*'; /* Let's cancel this beast */ 07005 } 07006 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07007 } 07008 } 07009 07010 if (msg_cfg) 07011 ast_config_destroy(msg_cfg); 07012 if (prepend_duration) 07013 *duration = prepend_duration; 07014 07015 if (already_recorded && cmd == -1) { 07016 /* restore original message if prepention cancelled */ 07017 ast_filerename(backup, msgfile, NULL); 07018 rename(backup_textfile, textfile); 07019 } 07020 07021 if (cmd == 't' || cmd == 'S') /* XXX entering this block with a value of 'S' is probably no longer possible. */ 07022 cmd = 0; 07023 return cmd; 07024 }
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 9225 of file app_voicemail_imapstorage.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
09226 { 09227 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09228 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09229 } else { /* Default to ENGLISH */ 09230 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09231 } 09232 }
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 9113 of file app_voicemail_imapstorage.c.
References ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::newmessages, vm_state::repeats, vm_state::starting, vm_state::urgentmessages, VM_MESSAGEWRAP, vm_play_folder_name(), and vm_state::vmbox.
09114 { 09115 int res = 0; 09116 /* Play instructions and wait for new command */ 09117 while (!res) { 09118 if (vms->starting) { 09119 if (vms->lastmsg > -1) { 09120 if (skipadvanced) 09121 res = ast_play_and_wait(chan, "vm-onefor-full"); 09122 else 09123 res = ast_play_and_wait(chan, "vm-onefor"); 09124 if (!res) 09125 res = vm_play_folder_name(chan, vms->vmbox); 09126 } 09127 if (!res) { 09128 if (skipadvanced) 09129 res = ast_play_and_wait(chan, "vm-opts-full"); 09130 else 09131 res = ast_play_and_wait(chan, "vm-opts"); 09132 } 09133 } else { 09134 /* Added for additional help */ 09135 if (skipadvanced) { 09136 res = ast_play_and_wait(chan, "vm-onefor-full"); 09137 if (!res) 09138 res = vm_play_folder_name(chan, vms->vmbox); 09139 res = ast_play_and_wait(chan, "vm-opts-full"); 09140 } 09141 /* Logic: 09142 * If the current message is not the first OR 09143 * if we're listening to the first new message and there are 09144 * also urgent messages, then prompt for navigation to the 09145 * previous message 09146 */ 09147 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 09148 res = ast_play_and_wait(chan, "vm-prev"); 09149 } 09150 if (!res && !skipadvanced) 09151 res = ast_play_and_wait(chan, "vm-advopts"); 09152 if (!res) 09153 res = ast_play_and_wait(chan, "vm-repeat"); 09154 /* Logic: 09155 * If we're not listening to the last message OR 09156 * we're listening to the last urgent message and there are 09157 * also new non-urgent messages, then prompt for navigation 09158 * to the next message 09159 */ 09160 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 09161 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 09162 res = ast_play_and_wait(chan, "vm-next"); 09163 } 09164 if (!res) { 09165 int curmsg_deleted; 09166 #ifdef IMAP_STORAGE 09167 ast_mutex_lock(&vms->lock); 09168 #endif 09169 curmsg_deleted = vms->deleted[vms->curmsg]; 09170 #ifdef IMAP_STORAGE 09171 ast_mutex_unlock(&vms->lock); 09172 #endif 09173 if (!curmsg_deleted) { 09174 res = ast_play_and_wait(chan, "vm-delete"); 09175 } else { 09176 res = ast_play_and_wait(chan, "vm-undelete"); 09177 } 09178 if (!res) { 09179 res = ast_play_and_wait(chan, "vm-toforward"); 09180 } 09181 if (!res) { 09182 res = ast_play_and_wait(chan, "vm-savemessage"); 09183 } 09184 } 09185 } 09186 if (!res) { 09187 res = ast_play_and_wait(chan, "vm-helpexit"); 09188 } 09189 if (!res) 09190 res = ast_waitfordigit(chan, 6000); 09191 if (!res) { 09192 vms->repeats++; 09193 if (vms->repeats > 2) { 09194 res = 't'; 09195 } 09196 } 09197 } 09198 return res; 09199 }
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 9201 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.
09202 { 09203 int res = 0; 09204 /* Play instructions and wait for new command */ 09205 while (!res) { 09206 if (vms->lastmsg > -1) { 09207 res = ast_play_and_wait(chan, "vm-listen"); 09208 if (!res) 09209 res = vm_play_folder_name(chan, vms->vmbox); 09210 if (!res) 09211 res = ast_play_and_wait(chan, "press"); 09212 if (!res) 09213 res = ast_play_and_wait(chan, "digits/1"); 09214 } 09215 if (!res) 09216 res = ast_play_and_wait(chan, "vm-opts"); 09217 if (!res) { 09218 vms->starting = 0; 09219 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09220 } 09221 } 09222 return res; 09223 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 9051 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.
09052 { 09053 char prefile[256]; 09054 09055 /* Notify the user that the temp greeting is set and give them the option to remove it */ 09056 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09057 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 09058 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09059 if (ast_fileexists(prefile, NULL, NULL) > 0) { 09060 ast_play_and_wait(chan, "vm-tempgreetactive"); 09061 } 09062 DISPOSE(prefile, -1); 09063 } 09064 09065 /* Play voicemail intro - syntax is different for different languages */ 09066 if (0) { 09067 return 0; 09068 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 09069 return vm_intro_cs(chan, vms); 09070 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 09071 static int deprecation_warning = 0; 09072 if (deprecation_warning++ % 10 == 0) { 09073 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 09074 } 09075 return vm_intro_cs(chan, vms); 09076 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 09077 return vm_intro_de(chan, vms); 09078 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 09079 return vm_intro_es(chan, vms); 09080 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 09081 return vm_intro_fr(chan, vms); 09082 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 09083 return vm_intro_gr(chan, vms); 09084 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 09085 return vm_intro_he(chan, vms); 09086 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 09087 return vm_intro_it(chan, vms); 09088 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 09089 return vm_intro_nl(chan, vms); 09090 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 09091 return vm_intro_no(chan, vms); 09092 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 09093 return vm_intro_pl(chan, vms); 09094 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 09095 return vm_intro_pt_BR(chan, vms); 09096 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 09097 return vm_intro_pt(chan, vms); 09098 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 09099 return vm_intro_multilang(chan, vms, "n"); 09100 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 09101 return vm_intro_se(chan, vms); 09102 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 09103 return vm_intro_multilang(chan, vms, "n"); 09104 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 09105 return vm_intro_vi(chan, vms); 09106 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09107 return vm_intro_zh(chan, vms); 09108 } else { /* Default to ENGLISH */ 09109 return vm_intro_en(chan, vms); 09110 } 09111 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8921 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.
08922 { 08923 int res; 08924 res = ast_play_and_wait(chan, "vm-youhave"); 08925 if (!res) { 08926 if (vms->newmessages) { 08927 if (vms->newmessages == 1) { 08928 res = ast_play_and_wait(chan, "digits/jednu"); 08929 } else { 08930 res = say_and_wait(chan, vms->newmessages, chan->language); 08931 } 08932 if (!res) { 08933 if ((vms->newmessages == 1)) 08934 res = ast_play_and_wait(chan, "vm-novou"); 08935 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08936 res = ast_play_and_wait(chan, "vm-nove"); 08937 if (vms->newmessages > 4) 08938 res = ast_play_and_wait(chan, "vm-novych"); 08939 } 08940 if (vms->oldmessages && !res) 08941 res = ast_play_and_wait(chan, "vm-and"); 08942 else if (!res) { 08943 if ((vms->newmessages == 1)) 08944 res = ast_play_and_wait(chan, "vm-zpravu"); 08945 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08946 res = ast_play_and_wait(chan, "vm-zpravy"); 08947 if (vms->newmessages > 4) 08948 res = ast_play_and_wait(chan, "vm-zprav"); 08949 } 08950 } 08951 if (!res && vms->oldmessages) { 08952 res = say_and_wait(chan, vms->oldmessages, chan->language); 08953 if (!res) { 08954 if ((vms->oldmessages == 1)) 08955 res = ast_play_and_wait(chan, "vm-starou"); 08956 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08957 res = ast_play_and_wait(chan, "vm-stare"); 08958 if (vms->oldmessages > 4) 08959 res = ast_play_and_wait(chan, "vm-starych"); 08960 } 08961 if (!res) { 08962 if ((vms->oldmessages == 1)) 08963 res = ast_play_and_wait(chan, "vm-zpravu"); 08964 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08965 res = ast_play_and_wait(chan, "vm-zpravy"); 08966 if (vms->oldmessages > 4) 08967 res = ast_play_and_wait(chan, "vm-zprav"); 08968 } 08969 } 08970 if (!res) { 08971 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08972 res = ast_play_and_wait(chan, "vm-no"); 08973 if (!res) 08974 res = ast_play_and_wait(chan, "vm-zpravy"); 08975 } 08976 } 08977 } 08978 return res; 08979 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8617 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.
08618 { 08619 /* Introduce messages they have */ 08620 int res; 08621 res = ast_play_and_wait(chan, "vm-youhave"); 08622 if (!res) { 08623 if (vms->newmessages) { 08624 if ((vms->newmessages == 1)) 08625 res = ast_play_and_wait(chan, "digits/1F"); 08626 else 08627 res = say_and_wait(chan, vms->newmessages, chan->language); 08628 if (!res) 08629 res = ast_play_and_wait(chan, "vm-INBOX"); 08630 if (vms->oldmessages && !res) 08631 res = ast_play_and_wait(chan, "vm-and"); 08632 else if (!res) { 08633 if ((vms->newmessages == 1)) 08634 res = ast_play_and_wait(chan, "vm-message"); 08635 else 08636 res = ast_play_and_wait(chan, "vm-messages"); 08637 } 08638 08639 } 08640 if (!res && vms->oldmessages) { 08641 if (vms->oldmessages == 1) 08642 res = ast_play_and_wait(chan, "digits/1F"); 08643 else 08644 res = say_and_wait(chan, vms->oldmessages, chan->language); 08645 if (!res) 08646 res = ast_play_and_wait(chan, "vm-Old"); 08647 if (!res) { 08648 if (vms->oldmessages == 1) 08649 res = ast_play_and_wait(chan, "vm-message"); 08650 else 08651 res = ast_play_and_wait(chan, "vm-messages"); 08652 } 08653 } 08654 if (!res) { 08655 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08656 res = ast_play_and_wait(chan, "vm-no"); 08657 if (!res) 08658 res = ast_play_and_wait(chan, "vm-messages"); 08659 } 08660 } 08661 } 08662 return res; 08663 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8366 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.
08367 { 08368 int res; 08369 08370 /* Introduce messages they have */ 08371 res = ast_play_and_wait(chan, "vm-youhave"); 08372 if (!res) { 08373 if (vms->urgentmessages) { 08374 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08375 if (!res) 08376 res = ast_play_and_wait(chan, "vm-Urgent"); 08377 if ((vms->oldmessages || vms->newmessages) && !res) { 08378 res = ast_play_and_wait(chan, "vm-and"); 08379 } else if (!res) { 08380 if ((vms->urgentmessages == 1)) 08381 res = ast_play_and_wait(chan, "vm-message"); 08382 else 08383 res = ast_play_and_wait(chan, "vm-messages"); 08384 } 08385 } 08386 if (vms->newmessages) { 08387 res = say_and_wait(chan, vms->newmessages, chan->language); 08388 if (!res) 08389 res = ast_play_and_wait(chan, "vm-INBOX"); 08390 if (vms->oldmessages && !res) 08391 res = ast_play_and_wait(chan, "vm-and"); 08392 else if (!res) { 08393 if ((vms->newmessages == 1)) 08394 res = ast_play_and_wait(chan, "vm-message"); 08395 else 08396 res = ast_play_and_wait(chan, "vm-messages"); 08397 } 08398 08399 } 08400 if (!res && vms->oldmessages) { 08401 res = say_and_wait(chan, vms->oldmessages, chan->language); 08402 if (!res) 08403 res = ast_play_and_wait(chan, "vm-Old"); 08404 if (!res) { 08405 if (vms->oldmessages == 1) 08406 res = ast_play_and_wait(chan, "vm-message"); 08407 else 08408 res = ast_play_and_wait(chan, "vm-messages"); 08409 } 08410 } 08411 if (!res) { 08412 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08413 res = ast_play_and_wait(chan, "vm-no"); 08414 if (!res) 08415 res = ast_play_and_wait(chan, "vm-messages"); 08416 } 08417 } 08418 } 08419 return res; 08420 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8666 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.
08667 { 08668 /* Introduce messages they have */ 08669 int res; 08670 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08671 res = ast_play_and_wait(chan, "vm-youhaveno"); 08672 if (!res) 08673 res = ast_play_and_wait(chan, "vm-messages"); 08674 } else { 08675 res = ast_play_and_wait(chan, "vm-youhave"); 08676 } 08677 if (!res) { 08678 if (vms->newmessages) { 08679 if (!res) { 08680 if ((vms->newmessages == 1)) { 08681 res = ast_play_and_wait(chan, "digits/1M"); 08682 if (!res) 08683 res = ast_play_and_wait(chan, "vm-message"); 08684 if (!res) 08685 res = ast_play_and_wait(chan, "vm-INBOXs"); 08686 } else { 08687 res = say_and_wait(chan, vms->newmessages, chan->language); 08688 if (!res) 08689 res = ast_play_and_wait(chan, "vm-messages"); 08690 if (!res) 08691 res = ast_play_and_wait(chan, "vm-INBOX"); 08692 } 08693 } 08694 if (vms->oldmessages && !res) 08695 res = ast_play_and_wait(chan, "vm-and"); 08696 } 08697 if (vms->oldmessages) { 08698 if (!res) { 08699 if (vms->oldmessages == 1) { 08700 res = ast_play_and_wait(chan, "digits/1M"); 08701 if (!res) 08702 res = ast_play_and_wait(chan, "vm-message"); 08703 if (!res) 08704 res = ast_play_and_wait(chan, "vm-Olds"); 08705 } else { 08706 res = say_and_wait(chan, vms->oldmessages, chan->language); 08707 if (!res) 08708 res = ast_play_and_wait(chan, "vm-messages"); 08709 if (!res) 08710 res = ast_play_and_wait(chan, "vm-Old"); 08711 } 08712 } 08713 } 08714 } 08715 return res; 08716 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8764 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.
08765 { 08766 /* Introduce messages they have */ 08767 int res; 08768 res = ast_play_and_wait(chan, "vm-youhave"); 08769 if (!res) { 08770 if (vms->newmessages) { 08771 res = say_and_wait(chan, vms->newmessages, chan->language); 08772 if (!res) 08773 res = ast_play_and_wait(chan, "vm-INBOX"); 08774 if (vms->oldmessages && !res) 08775 res = ast_play_and_wait(chan, "vm-and"); 08776 else if (!res) { 08777 if ((vms->newmessages == 1)) 08778 res = ast_play_and_wait(chan, "vm-message"); 08779 else 08780 res = ast_play_and_wait(chan, "vm-messages"); 08781 } 08782 08783 } 08784 if (!res && vms->oldmessages) { 08785 res = say_and_wait(chan, vms->oldmessages, chan->language); 08786 if (!res) 08787 res = ast_play_and_wait(chan, "vm-Old"); 08788 if (!res) { 08789 if (vms->oldmessages == 1) 08790 res = ast_play_and_wait(chan, "vm-message"); 08791 else 08792 res = ast_play_and_wait(chan, "vm-messages"); 08793 } 08794 } 08795 if (!res) { 08796 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08797 res = ast_play_and_wait(chan, "vm-no"); 08798 if (!res) 08799 res = ast_play_and_wait(chan, "vm-messages"); 08800 } 08801 } 08802 } 08803 return res; 08804 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8165 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.
08166 { 08167 int res = 0; 08168 08169 if (vms->newmessages) { 08170 res = ast_play_and_wait(chan, "vm-youhave"); 08171 if (!res) 08172 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 08173 if (!res) { 08174 if ((vms->newmessages == 1)) { 08175 res = ast_play_and_wait(chan, "vm-INBOX"); 08176 if (!res) 08177 res = ast_play_and_wait(chan, "vm-message"); 08178 } else { 08179 res = ast_play_and_wait(chan, "vm-INBOXs"); 08180 if (!res) 08181 res = ast_play_and_wait(chan, "vm-messages"); 08182 } 08183 } 08184 } else if (vms->oldmessages){ 08185 res = ast_play_and_wait(chan, "vm-youhave"); 08186 if (!res) 08187 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 08188 if ((vms->oldmessages == 1)){ 08189 res = ast_play_and_wait(chan, "vm-Old"); 08190 if (!res) 08191 res = ast_play_and_wait(chan, "vm-message"); 08192 } else { 08193 res = ast_play_and_wait(chan, "vm-Olds"); 08194 if (!res) 08195 res = ast_play_and_wait(chan, "vm-messages"); 08196 } 08197 } else if (!vms->oldmessages && !vms->newmessages) 08198 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 08199 return res; 08200 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8299 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.
08300 { 08301 int res = 0; 08302 08303 /* Introduce messages they have */ 08304 if (!res) { 08305 if ((vms->newmessages) || (vms->oldmessages)) { 08306 res = ast_play_and_wait(chan, "vm-youhave"); 08307 } 08308 /* 08309 * The word "shtei" refers to the number 2 in hebrew when performing a count 08310 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08311 * an element, this is one of them. 08312 */ 08313 if (vms->newmessages) { 08314 if (!res) { 08315 if (vms->newmessages == 1) { 08316 res = ast_play_and_wait(chan, "vm-INBOX1"); 08317 } else { 08318 if (vms->newmessages == 2) { 08319 res = ast_play_and_wait(chan, "vm-shtei"); 08320 } else { 08321 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08322 } 08323 res = ast_play_and_wait(chan, "vm-INBOX"); 08324 } 08325 } 08326 if (vms->oldmessages && !res) { 08327 res = ast_play_and_wait(chan, "vm-and"); 08328 if (vms->oldmessages == 1) { 08329 res = ast_play_and_wait(chan, "vm-Old1"); 08330 } else { 08331 if (vms->oldmessages == 2) { 08332 res = ast_play_and_wait(chan, "vm-shtei"); 08333 } else { 08334 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08335 } 08336 res = ast_play_and_wait(chan, "vm-Old"); 08337 } 08338 } 08339 } 08340 if (!res && vms->oldmessages && !vms->newmessages) { 08341 if (!res) { 08342 if (vms->oldmessages == 1) { 08343 res = ast_play_and_wait(chan, "vm-Old1"); 08344 } else { 08345 if (vms->oldmessages == 2) { 08346 res = ast_play_and_wait(chan, "vm-shtei"); 08347 } else { 08348 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08349 } 08350 res = ast_play_and_wait(chan, "vm-Old"); 08351 } 08352 } 08353 } 08354 if (!res) { 08355 if (!vms->oldmessages && !vms->newmessages) { 08356 if (!res) { 08357 res = ast_play_and_wait(chan, "vm-nomessages"); 08358 } 08359 } 08360 } 08361 } 08362 return res; 08363 }
static int vm_intro_it | ( | 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, say_and_wait(), and vm_state::urgentmessages.
08424 { 08425 /* Introduce messages they have */ 08426 int res; 08427 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08428 res = ast_play_and_wait(chan, "vm-no") || 08429 ast_play_and_wait(chan, "vm-message"); 08430 else 08431 res = ast_play_and_wait(chan, "vm-youhave"); 08432 if (!res && vms->newmessages) { 08433 res = (vms->newmessages == 1) ? 08434 ast_play_and_wait(chan, "digits/un") || 08435 ast_play_and_wait(chan, "vm-nuovo") || 08436 ast_play_and_wait(chan, "vm-message") : 08437 /* 2 or more new messages */ 08438 say_and_wait(chan, vms->newmessages, chan->language) || 08439 ast_play_and_wait(chan, "vm-nuovi") || 08440 ast_play_and_wait(chan, "vm-messages"); 08441 if (!res && vms->oldmessages) 08442 res = ast_play_and_wait(chan, "vm-and"); 08443 } 08444 if (!res && vms->oldmessages) { 08445 res = (vms->oldmessages == 1) ? 08446 ast_play_and_wait(chan, "digits/un") || 08447 ast_play_and_wait(chan, "vm-vecchio") || 08448 ast_play_and_wait(chan, "vm-message") : 08449 /* 2 or more old messages */ 08450 say_and_wait(chan, vms->oldmessages, chan->language) || 08451 ast_play_and_wait(chan, "vm-vecchi") || 08452 ast_play_and_wait(chan, "vm-messages"); 08453 } 08454 return res; 08455 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8259 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.
08260 { 08261 int res; 08262 int lastnum = 0; 08263 08264 res = ast_play_and_wait(chan, "vm-youhave"); 08265 08266 if (!res && vms->newmessages) { 08267 lastnum = vms->newmessages; 08268 08269 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08270 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08271 } 08272 08273 if (!res && vms->oldmessages) { 08274 res = ast_play_and_wait(chan, "vm-and"); 08275 } 08276 } 08277 08278 if (!res && vms->oldmessages) { 08279 lastnum = vms->oldmessages; 08280 08281 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08282 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08283 } 08284 } 08285 08286 if (!res) { 08287 if (lastnum == 0) { 08288 res = ast_play_and_wait(chan, "vm-no"); 08289 } 08290 if (!res) { 08291 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08292 } 08293 } 08294 08295 return res; 08296 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8807 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.
08808 { 08809 /* Introduce messages they have */ 08810 int res; 08811 res = ast_play_and_wait(chan, "vm-youhave"); 08812 if (!res) { 08813 if (vms->newmessages) { 08814 res = say_and_wait(chan, vms->newmessages, chan->language); 08815 if (!res) { 08816 if (vms->newmessages == 1) 08817 res = ast_play_and_wait(chan, "vm-INBOXs"); 08818 else 08819 res = ast_play_and_wait(chan, "vm-INBOX"); 08820 } 08821 if (vms->oldmessages && !res) 08822 res = ast_play_and_wait(chan, "vm-and"); 08823 else if (!res) { 08824 if ((vms->newmessages == 1)) 08825 res = ast_play_and_wait(chan, "vm-message"); 08826 else 08827 res = ast_play_and_wait(chan, "vm-messages"); 08828 } 08829 08830 } 08831 if (!res && vms->oldmessages) { 08832 res = say_and_wait(chan, vms->oldmessages, chan->language); 08833 if (!res) { 08834 if (vms->oldmessages == 1) 08835 res = ast_play_and_wait(chan, "vm-Olds"); 08836 else 08837 res = ast_play_and_wait(chan, "vm-Old"); 08838 } 08839 if (!res) { 08840 if (vms->oldmessages == 1) 08841 res = ast_play_and_wait(chan, "vm-message"); 08842 else 08843 res = ast_play_and_wait(chan, "vm-messages"); 08844 } 08845 } 08846 if (!res) { 08847 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08848 res = ast_play_and_wait(chan, "vm-no"); 08849 if (!res) 08850 res = ast_play_and_wait(chan, "vm-messages"); 08851 } 08852 } 08853 } 08854 return res; 08855 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8573 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.
08574 { 08575 /* Introduce messages they have */ 08576 int res; 08577 08578 res = ast_play_and_wait(chan, "vm-youhave"); 08579 if (res) 08580 return res; 08581 08582 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08583 res = ast_play_and_wait(chan, "vm-no"); 08584 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08585 return res; 08586 } 08587 08588 if (vms->newmessages) { 08589 if ((vms->newmessages == 1)) { 08590 res = ast_play_and_wait(chan, "digits/1"); 08591 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08592 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08593 } else { 08594 res = say_and_wait(chan, vms->newmessages, chan->language); 08595 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08596 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08597 } 08598 if (!res && vms->oldmessages) 08599 res = ast_play_and_wait(chan, "vm-and"); 08600 } 08601 if (!res && vms->oldmessages) { 08602 if (vms->oldmessages == 1) { 08603 res = ast_play_and_wait(chan, "digits/1"); 08604 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08605 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08606 } else { 08607 res = say_and_wait(chan, vms->oldmessages, chan->language); 08608 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08609 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08610 } 08611 } 08612 08613 return res; 08614 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8458 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08459 { 08460 /* Introduce messages they have */ 08461 int res; 08462 div_t num; 08463 08464 if (!vms->oldmessages && !vms->newmessages) { 08465 res = ast_play_and_wait(chan, "vm-no"); 08466 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08467 return res; 08468 } else { 08469 res = ast_play_and_wait(chan, "vm-youhave"); 08470 } 08471 08472 if (vms->newmessages) { 08473 num = div(vms->newmessages, 10); 08474 if (vms->newmessages == 1) { 08475 res = ast_play_and_wait(chan, "digits/1-a"); 08476 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08477 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08478 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08479 if (num.rem == 2) { 08480 if (!num.quot) { 08481 res = ast_play_and_wait(chan, "digits/2-ie"); 08482 } else { 08483 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08484 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08485 } 08486 } else { 08487 res = say_and_wait(chan, vms->newmessages, chan->language); 08488 } 08489 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08490 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08491 } else { 08492 res = say_and_wait(chan, vms->newmessages, chan->language); 08493 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08494 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08495 } 08496 if (!res && vms->oldmessages) 08497 res = ast_play_and_wait(chan, "vm-and"); 08498 } 08499 if (!res && vms->oldmessages) { 08500 num = div(vms->oldmessages, 10); 08501 if (vms->oldmessages == 1) { 08502 res = ast_play_and_wait(chan, "digits/1-a"); 08503 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08504 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08505 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08506 if (num.rem == 2) { 08507 if (!num.quot) { 08508 res = ast_play_and_wait(chan, "digits/2-ie"); 08509 } else { 08510 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08511 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08512 } 08513 } else { 08514 res = say_and_wait(chan, vms->oldmessages, chan->language); 08515 } 08516 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08517 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08518 } else { 08519 res = say_and_wait(chan, vms->oldmessages, chan->language); 08520 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08521 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08522 } 08523 } 08524 08525 return res; 08526 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8858 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.
08859 { 08860 /* Introduce messages they have */ 08861 int res; 08862 res = ast_play_and_wait(chan, "vm-youhave"); 08863 if (!res) { 08864 if (vms->newmessages) { 08865 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08866 if (!res) { 08867 if ((vms->newmessages == 1)) { 08868 res = ast_play_and_wait(chan, "vm-message"); 08869 if (!res) 08870 res = ast_play_and_wait(chan, "vm-INBOXs"); 08871 } else { 08872 res = ast_play_and_wait(chan, "vm-messages"); 08873 if (!res) 08874 res = ast_play_and_wait(chan, "vm-INBOX"); 08875 } 08876 } 08877 if (vms->oldmessages && !res) 08878 res = ast_play_and_wait(chan, "vm-and"); 08879 } 08880 if (!res && vms->oldmessages) { 08881 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08882 if (!res) { 08883 if (vms->oldmessages == 1) { 08884 res = ast_play_and_wait(chan, "vm-message"); 08885 if (!res) 08886 res = ast_play_and_wait(chan, "vm-Olds"); 08887 } else { 08888 res = ast_play_and_wait(chan, "vm-messages"); 08889 if (!res) 08890 res = ast_play_and_wait(chan, "vm-Old"); 08891 } 08892 } 08893 } 08894 if (!res) { 08895 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08896 res = ast_play_and_wait(chan, "vm-no"); 08897 if (!res) 08898 res = ast_play_and_wait(chan, "vm-messages"); 08899 } 08900 } 08901 } 08902 return res; 08903 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8719 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.
08719 { 08720 /* Introduce messages they have */ 08721 int res; 08722 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08723 res = ast_play_and_wait(chan, "vm-nomessages"); 08724 return res; 08725 } else { 08726 res = ast_play_and_wait(chan, "vm-youhave"); 08727 } 08728 if (vms->newmessages) { 08729 if (!res) 08730 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08731 if ((vms->newmessages == 1)) { 08732 if (!res) 08733 res = ast_play_and_wait(chan, "vm-message"); 08734 if (!res) 08735 res = ast_play_and_wait(chan, "vm-INBOXs"); 08736 } else { 08737 if (!res) 08738 res = ast_play_and_wait(chan, "vm-messages"); 08739 if (!res) 08740 res = ast_play_and_wait(chan, "vm-INBOX"); 08741 } 08742 if (vms->oldmessages && !res) 08743 res = ast_play_and_wait(chan, "vm-and"); 08744 } 08745 if (vms->oldmessages) { 08746 if (!res) 08747 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08748 if (vms->oldmessages == 1) { 08749 if (!res) 08750 res = ast_play_and_wait(chan, "vm-message"); 08751 if (!res) 08752 res = ast_play_and_wait(chan, "vm-Olds"); 08753 } else { 08754 if (!res) 08755 res = ast_play_and_wait(chan, "vm-messages"); 08756 if (!res) 08757 res = ast_play_and_wait(chan, "vm-Old"); 08758 } 08759 } 08760 return res; 08761 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8529 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.
08530 { 08531 /* Introduce messages they have */ 08532 int res; 08533 08534 res = ast_play_and_wait(chan, "vm-youhave"); 08535 if (res) 08536 return res; 08537 08538 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08539 res = ast_play_and_wait(chan, "vm-no"); 08540 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08541 return res; 08542 } 08543 08544 if (vms->newmessages) { 08545 if ((vms->newmessages == 1)) { 08546 res = ast_play_and_wait(chan, "digits/ett"); 08547 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08548 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08549 } else { 08550 res = say_and_wait(chan, vms->newmessages, chan->language); 08551 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08552 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08553 } 08554 if (!res && vms->oldmessages) 08555 res = ast_play_and_wait(chan, "vm-and"); 08556 } 08557 if (!res && vms->oldmessages) { 08558 if (vms->oldmessages == 1) { 08559 res = ast_play_and_wait(chan, "digits/ett"); 08560 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08561 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08562 } else { 08563 res = say_and_wait(chan, vms->oldmessages, chan->language); 08564 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08565 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08566 } 08567 } 08568 08569 return res; 08570 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 9021 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
09022 { 09023 int res; 09024 09025 /* Introduce messages they have */ 09026 res = ast_play_and_wait(chan, "vm-youhave"); 09027 if (!res) { 09028 if (vms->newmessages) { 09029 res = say_and_wait(chan, vms->newmessages, chan->language); 09030 if (!res) 09031 res = ast_play_and_wait(chan, "vm-INBOX"); 09032 if (vms->oldmessages && !res) 09033 res = ast_play_and_wait(chan, "vm-and"); 09034 } 09035 if (!res && vms->oldmessages) { 09036 res = say_and_wait(chan, vms->oldmessages, chan->language); 09037 if (!res) 09038 res = ast_play_and_wait(chan, "vm-Old"); 09039 } 09040 if (!res) { 09041 if (!vms->oldmessages && !vms->newmessages) { 09042 res = ast_play_and_wait(chan, "vm-no"); 09043 if (!res) 09044 res = ast_play_and_wait(chan, "vm-message"); 09045 } 09046 } 09047 } 09048 return res; 09049 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8982 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08983 { 08984 int res; 08985 /* Introduce messages they have */ 08986 res = ast_play_and_wait(chan, "vm-you"); 08987 08988 if (!res && vms->newmessages) { 08989 res = ast_play_and_wait(chan, "vm-have"); 08990 if (!res) 08991 res = say_and_wait(chan, vms->newmessages, chan->language); 08992 if (!res) 08993 res = ast_play_and_wait(chan, "vm-tong"); 08994 if (!res) 08995 res = ast_play_and_wait(chan, "vm-INBOX"); 08996 if (vms->oldmessages && !res) 08997 res = ast_play_and_wait(chan, "vm-and"); 08998 else if (!res) 08999 res = ast_play_and_wait(chan, "vm-messages"); 09000 } 09001 if (!res && vms->oldmessages) { 09002 res = ast_play_and_wait(chan, "vm-have"); 09003 if (!res) 09004 res = say_and_wait(chan, vms->oldmessages, chan->language); 09005 if (!res) 09006 res = ast_play_and_wait(chan, "vm-tong"); 09007 if (!res) 09008 res = ast_play_and_wait(chan, "vm-Old"); 09009 if (!res) 09010 res = ast_play_and_wait(chan, "vm-messages"); 09011 } 09012 if (!res && !vms->oldmessages && !vms->newmessages) { 09013 res = ast_play_and_wait(chan, "vm-haveno"); 09014 if (!res) 09015 res = ast_play_and_wait(chan, "vm-messages"); 09016 } 09017 return res; 09018 }
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 3267 of file app_voicemail_imapstorage.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03268 { 03269 switch (ast_lock_path(path)) { 03270 case AST_LOCK_TIMEOUT: 03271 return -1; 03272 default: 03273 return 0; 03274 } 03275 }
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 9235 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.
09236 { 09237 int cmd = 0; 09238 int duration = 0; 09239 int tries = 0; 09240 char newpassword[80] = ""; 09241 char newpassword2[80] = ""; 09242 char prefile[PATH_MAX] = ""; 09243 unsigned char buf[256]; 09244 int bytes = 0; 09245 09246 ast_test_suite_event_notify("NEWUSER", "Message: entering new user state"); 09247 if (ast_adsi_available(chan)) { 09248 bytes += adsi_logo(buf + bytes); 09249 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09250 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09251 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09252 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09253 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09254 } 09255 09256 /* If forcename is set, have the user record their name */ 09257 if (ast_test_flag(vmu, VM_FORCENAME)) { 09258 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09259 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09260 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09261 if (cmd < 0 || cmd == 't' || cmd == '#') 09262 return cmd; 09263 } 09264 } 09265 09266 /* If forcegreetings is set, have the user record their greetings */ 09267 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09268 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09269 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09270 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09271 if (cmd < 0 || cmd == 't' || cmd == '#') 09272 return cmd; 09273 } 09274 09275 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09276 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09277 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09278 if (cmd < 0 || cmd == 't' || cmd == '#') 09279 return cmd; 09280 } 09281 } 09282 09283 /* 09284 * Change the password last since new users will be able to skip over any steps this one comes before 09285 * by hanging up and calling back to voicemail main since the password is used to verify new user status. 09286 */ 09287 for (;;) { 09288 newpassword[1] = '\0'; 09289 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09290 if (cmd == '#') 09291 newpassword[0] = '\0'; 09292 if (cmd < 0 || cmd == 't' || cmd == '#') 09293 return cmd; 09294 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09295 if (cmd < 0 || cmd == 't' || cmd == '#') 09296 return cmd; 09297 cmd = check_password(vmu, newpassword); /* perform password validation */ 09298 if (cmd != 0) { 09299 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09300 cmd = ast_play_and_wait(chan, vm_invalid_password); 09301 } else { 09302 newpassword2[1] = '\0'; 09303 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09304 if (cmd == '#') 09305 newpassword2[0] = '\0'; 09306 if (cmd < 0 || cmd == 't' || cmd == '#') 09307 return cmd; 09308 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09309 if (cmd < 0 || cmd == 't' || cmd == '#') 09310 return cmd; 09311 if (!strcmp(newpassword, newpassword2)) 09312 break; 09313 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09314 cmd = ast_play_and_wait(chan, vm_mismatch); 09315 } 09316 if (++tries == 3) 09317 return -1; 09318 if (cmd != 0) { 09319 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09320 } 09321 } 09322 if (pwdchange & PWDCHANGE_INTERNAL) 09323 vm_change_password(vmu, newpassword); 09324 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09325 vm_change_password_shell(vmu, newpassword); 09326 09327 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09328 cmd = ast_play_and_wait(chan, vm_passchanged); 09329 09330 return cmd; 09331 }
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 9333 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().
09334 { 09335 int cmd = 0; 09336 int retries = 0; 09337 int duration = 0; 09338 char newpassword[80] = ""; 09339 char newpassword2[80] = ""; 09340 char prefile[PATH_MAX] = ""; 09341 unsigned char buf[256]; 09342 int bytes = 0; 09343 09344 ast_test_suite_event_notify("VMOPTIONS", "Message: entering mailbox options"); 09345 if (ast_adsi_available(chan)) { 09346 bytes += adsi_logo(buf + bytes); 09347 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09348 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09349 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09350 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09351 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09352 } 09353 while ((cmd >= 0) && (cmd != 't')) { 09354 if (cmd) 09355 retries = 0; 09356 switch (cmd) { 09357 case '1': /* Record your unavailable message */ 09358 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09359 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09360 break; 09361 case '2': /* Record your busy message */ 09362 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09363 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09364 break; 09365 case '3': /* Record greeting */ 09366 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09367 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09368 break; 09369 case '4': /* manage the temporary greeting */ 09370 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09371 break; 09372 case '5': /* change password */ 09373 if (vmu->password[0] == '-') { 09374 cmd = ast_play_and_wait(chan, "vm-no"); 09375 break; 09376 } 09377 newpassword[1] = '\0'; 09378 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09379 if (cmd == '#') 09380 newpassword[0] = '\0'; 09381 else { 09382 if (cmd < 0) 09383 break; 09384 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09385 break; 09386 } 09387 } 09388 cmd = check_password(vmu, newpassword); /* perform password validation */ 09389 if (cmd != 0) { 09390 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09391 cmd = ast_play_and_wait(chan, vm_invalid_password); 09392 if (!cmd) { 09393 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09394 } 09395 break; 09396 } 09397 newpassword2[1] = '\0'; 09398 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09399 if (cmd == '#') 09400 newpassword2[0] = '\0'; 09401 else { 09402 if (cmd < 0) 09403 break; 09404 09405 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09406 break; 09407 } 09408 } 09409 if (strcmp(newpassword, newpassword2)) { 09410 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09411 cmd = ast_play_and_wait(chan, vm_mismatch); 09412 if (!cmd) { 09413 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09414 } 09415 break; 09416 } 09417 09418 if (pwdchange & PWDCHANGE_INTERNAL) { 09419 vm_change_password(vmu, newpassword); 09420 } 09421 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) { 09422 vm_change_password_shell(vmu, newpassword); 09423 } 09424 09425 ast_debug(1, "User %s set password to %s of length %d\n", 09426 vms->username, newpassword, (int) strlen(newpassword)); 09427 cmd = ast_play_and_wait(chan, vm_passchanged); 09428 break; 09429 case '*': 09430 cmd = 't'; 09431 break; 09432 default: 09433 cmd = 0; 09434 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09435 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09436 if (ast_fileexists(prefile, NULL, NULL)) { 09437 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09438 } 09439 DISPOSE(prefile, -1); 09440 if (!cmd) { 09441 cmd = ast_play_and_wait(chan, "vm-options"); 09442 } 09443 if (!cmd) { 09444 cmd = ast_waitfordigit(chan, 6000); 09445 } 09446 if (!cmd) { 09447 retries++; 09448 } 09449 if (retries > 3) { 09450 cmd = 't'; 09451 } 09452 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09453 } 09454 } 09455 if (cmd == 't') 09456 cmd = 0; 09457 return cmd; 09458 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 8128 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().
08129 { 08130 int cmd; 08131 08132 if ( !strncasecmp(chan->language, "it", 2) || 08133 !strncasecmp(chan->language, "es", 2) || 08134 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 08135 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08136 return cmd ? cmd : ast_play_and_wait(chan, box); 08137 } else if (!strncasecmp(chan->language, "gr", 2)) { 08138 return vm_play_folder_name_gr(chan, box); 08139 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 08140 return ast_play_and_wait(chan, box); 08141 } else if (!strncasecmp(chan->language, "pl", 2)) { 08142 return vm_play_folder_name_pl(chan, box); 08143 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 08144 return vm_play_folder_name_ua(chan, box); 08145 } else if (!strncasecmp(chan->language, "vi", 2)) { 08146 return ast_play_and_wait(chan, box); 08147 } else { /* Default English */ 08148 cmd = ast_play_and_wait(chan, box); 08149 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 08150 } 08151 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8081 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
08082 { 08083 int cmd; 08084 char *buf; 08085 08086 buf = alloca(strlen(box) + 2); 08087 strcpy(buf, box); 08088 strcat(buf, "s"); 08089 08090 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 08091 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 08092 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08093 } else { 08094 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 08095 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 08096 } 08097 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8099 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
08100 { 08101 int cmd; 08102 08103 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 08104 if (!strcasecmp(box, "vm-INBOX")) 08105 cmd = ast_play_and_wait(chan, "vm-new-e"); 08106 else 08107 cmd = ast_play_and_wait(chan, "vm-old-e"); 08108 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08109 } else { 08110 cmd = ast_play_and_wait(chan, "vm-messages"); 08111 return cmd ? cmd : ast_play_and_wait(chan, box); 08112 } 08113 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 8115 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
08116 { 08117 int cmd; 08118 08119 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 08120 cmd = ast_play_and_wait(chan, "vm-messages"); 08121 return cmd ? cmd : ast_play_and_wait(chan, box); 08122 } else { 08123 cmd = ast_play_and_wait(chan, box); 08124 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 08125 } 08126 }
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 9476 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.
09477 { 09478 int cmd = 0; 09479 int retries = 0; 09480 int duration = 0; 09481 char prefile[PATH_MAX] = ""; 09482 unsigned char buf[256]; 09483 int bytes = 0; 09484 09485 if (ast_adsi_available(chan)) { 09486 bytes += adsi_logo(buf + bytes); 09487 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09488 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09489 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09490 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09491 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09492 } 09493 09494 ast_test_suite_event_notify("TEMPGREETING", "Message: entering temp greeting options"); 09495 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09496 while ((cmd >= 0) && (cmd != 't')) { 09497 if (cmd) 09498 retries = 0; 09499 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09500 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09501 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09502 if (cmd == -1) { 09503 break; 09504 } 09505 cmd = 't'; 09506 } else { 09507 switch (cmd) { 09508 case '1': 09509 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, NULL, record_gain, vms, NULL); 09510 break; 09511 case '2': 09512 DELETE(prefile, -1, prefile, vmu); 09513 ast_play_and_wait(chan, "vm-tempremoved"); 09514 cmd = 't'; 09515 break; 09516 case '*': 09517 cmd = 't'; 09518 break; 09519 default: 09520 cmd = ast_play_and_wait(chan, 09521 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09522 "vm-tempgreeting2" : "vm-tempgreeting"); 09523 if (!cmd) { 09524 cmd = ast_waitfordigit(chan, 6000); 09525 } 09526 if (!cmd) { 09527 retries++; 09528 } 09529 if (retries > 3) { 09530 cmd = 't'; 09531 } 09532 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 09533 } 09534 } 09535 DISPOSE(prefile, -1); 09536 } 09537 if (cmd == 't') 09538 cmd = 0; 09539 return cmd; 09540 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11430 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().
11432 { 11433 struct ast_vm_user *user; 11434 11435 AST_LIST_LOCK(&users); 11436 AST_LIST_TRAVERSE(&users, user, list) { 11437 vm_users_data_provider_get_helper(search, data_root, user); 11438 } 11439 AST_LIST_UNLOCK(&users); 11440 11441 return 0; 11442 }
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 11383 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.
11385 { 11386 struct ast_data *data_user, *data_zone; 11387 struct ast_data *data_state; 11388 struct vm_zone *zone = NULL; 11389 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11390 char ext_context[256] = ""; 11391 11392 data_user = ast_data_add_node(data_root, "user"); 11393 if (!data_user) { 11394 return -1; 11395 } 11396 11397 ast_data_add_structure(ast_vm_user, data_user, user); 11398 11399 AST_LIST_LOCK(&zones); 11400 AST_LIST_TRAVERSE(&zones, zone, list) { 11401 if (!strcmp(zone->name, user->zonetag)) { 11402 break; 11403 } 11404 } 11405 AST_LIST_UNLOCK(&zones); 11406 11407 /* state */ 11408 data_state = ast_data_add_node(data_user, "state"); 11409 if (!data_state) { 11410 return -1; 11411 } 11412 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11413 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11414 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11415 ast_data_add_int(data_state, "newmsg", newmsg); 11416 ast_data_add_int(data_state, "oldmsg", oldmsg); 11417 11418 if (zone) { 11419 data_zone = ast_data_add_node(data_user, "zone"); 11420 ast_data_add_structure(vm_zone, data_zone, zone); 11421 } 11422 11423 if (!ast_data_search_match(search, data_user)) { 11424 ast_data_remove_node(data_root, data_user); 11425 } 11426 11427 return 0; 11428 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 11067 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().
11068 { 11069 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 11070 struct ast_vm_user vmus; 11071 char *options = NULL; 11072 int silent = 0, skipuser = 0; 11073 int res = -1; 11074 11075 if (data) { 11076 s = ast_strdupa(data); 11077 user = strsep(&s, ","); 11078 options = strsep(&s, ","); 11079 if (user) { 11080 s = user; 11081 user = strsep(&s, "@"); 11082 context = strsep(&s, ""); 11083 if (!ast_strlen_zero(user)) 11084 skipuser++; 11085 ast_copy_string(mailbox, user, sizeof(mailbox)); 11086 } 11087 } 11088 11089 if (options) { 11090 silent = (strchr(options, 's')) != NULL; 11091 } 11092 11093 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 11094 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 11095 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 11096 ast_play_and_wait(chan, "auth-thankyou"); 11097 res = 0; 11098 } else if (mailbox[0] == '*') { 11099 /* user entered '*' */ 11100 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 11101 res = 0; /* prevent hangup */ 11102 } 11103 } 11104 11105 return res; 11106 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12609 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().
12610 { 12611 char *context; 12612 char *args_copy; 12613 int res; 12614 12615 if (ast_strlen_zero(data)) { 12616 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context\n"); 12617 return -1; 12618 } 12619 12620 args_copy = ast_strdupa(data); 12621 if ((context = strchr(args_copy, '@'))) { 12622 *context++ = '\0'; 12623 } else { 12624 context = "default"; 12625 } 12626 12627 if ((res = sayname(chan, args_copy, context) < 0)) { 12628 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12629 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12630 if (!res) { 12631 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12632 } 12633 } 12634 12635 return res; 12636 }
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 4424 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.
04425 { 04426 const struct vm_zone *z = NULL; 04427 struct timeval t = ast_tvnow(); 04428 04429 /* Does this user have a timezone specified? */ 04430 if (!ast_strlen_zero(vmu->zonetag)) { 04431 /* Find the zone in the list */ 04432 AST_LIST_LOCK(&zones); 04433 AST_LIST_TRAVERSE(&zones, z, list) { 04434 if (!strcmp(z->name, vmu->zonetag)) 04435 break; 04436 } 04437 AST_LIST_UNLOCK(&zones); 04438 } 04439 ast_localtime(&t, tm, z ? z->timezone : NULL); 04440 return tm; 04441 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7477 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.
07478 { 07479 ast_test_suite_event_notify("PLAYVOICE", "Message: Playing %s", file); 07480 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); 07481 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7469 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, ast_log(), and ast_stream_and_wait().
07470 { 07471 int res; 07472 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07473 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07474 return res; 07475 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12576 of file app_voicemail_imapstorage.c.
References ast_category_append(), ast_category_destroy(), ast_category_new(), ast_config_destroy(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
12576 { 12577 struct ast_config *conf; 12578 struct ast_category *cat; 12579 struct ast_variable *var; 12580 int res = -1; 12581 12582 if (!(conf = ast_config_new())) { 12583 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12584 return res; 12585 } 12586 if (!(cat = ast_category_new("general", "", 1))) { 12587 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12588 ast_config_destroy(conf); 12589 return res; 12590 } 12591 if (!(var = ast_variable_new("password", password, ""))) { 12592 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12593 ast_config_destroy(conf); 12594 ast_category_destroy(cat); 12595 return res; 12596 } 12597 ast_category_append(conf, cat); 12598 ast_variable_append(cat, var); 12599 if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12600 res = 0; 12601 } else { 12602 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12603 } 12604 12605 ast_config_destroy(conf); 12606 return res; 12607 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13688 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 13688 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 11306 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 11062 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 11444 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.