#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 | 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, 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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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_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 404 of file app_voicemail_imapstorage.c.
#define BASELINELEN 72 |
Definition at line 427 of file app_voicemail_imapstorage.c.
#define BASEMAXINLINE 256 |
Definition at line 428 of file app_voicemail_imapstorage.c.
#define CHUNKSIZE 65536 |
Definition at line 401 of file app_voicemail_imapstorage.c.
#define COMMAND_TIMEOUT 5000 |
Definition at line 397 of file app_voicemail_imapstorage.c.
#define COPY | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (copy_plain_file(g,h)); |
Definition at line 711 of file app_voicemail_imapstorage.c.
#define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 11040 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 11068 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
Definition at line 409 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
Definition at line 411 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
Definition at line 412 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
Definition at line 410 of file app_voicemail_imapstorage.c.
#define DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
Definition at line 413 of file app_voicemail_imapstorage.c.
#define DEFAULT_POLL_FREQ 30 |
By default, poll every 30 seconds
Definition at line 781 of file app_voicemail_imapstorage.c.
#define DELETE | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (vm_delete(c)) |
Definition at line 712 of file app_voicemail_imapstorage.c.
#define DISPOSE | ( | a, | |||
b | ) |
Definition at line 707 of file app_voicemail_imapstorage.c.
#define ENDL "\n" |
Definition at line 432 of file app_voicemail_imapstorage.c.
#define ERROR_LOCK_PATH -100 |
Definition at line 457 of file app_voicemail_imapstorage.c.
#define EXISTS | ( | a, | |||
b, | |||||
c, | |||||
d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 709 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 420 of file app_voicemail_imapstorage.c.
#define MAX_DATETIME_FORMAT 512 |
Definition at line 435 of file app_voicemail_imapstorage.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 436 of file app_voicemail_imapstorage.c.
#define MAXMSG 100 |
Definition at line 422 of file app_voicemail_imapstorage.c.
#define MAXMSGLIMIT 9999 |
Definition at line 423 of file app_voicemail_imapstorage.c.
#define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 425 of file app_voicemail_imapstorage.c.
#define OPERATOR_EXIT 300 |
Definition at line 458 of file app_voicemail_imapstorage.c.
#define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 724 of file app_voicemail_imapstorage.c.
#define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 723 of file app_voicemail_imapstorage.c.
#define RENAME | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h | ) | (rename_file(g,h)); |
Definition at line 710 of file app_voicemail_imapstorage.c.
#define RETRIEVE | ( | a, | |||
b, | |||||
c, | |||||
d | ) |
Definition at line 706 of file app_voicemail_imapstorage.c.
#define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 418 of file app_voicemail_imapstorage.c.
#define SMDI_MWI_WAIT_TIMEOUT 1000 |
Definition at line 395 of file app_voicemail_imapstorage.c.
#define STORE | ( | a, | |||
b, | |||||
c, | |||||
d, | |||||
e, | |||||
f, | |||||
g, | |||||
h, | |||||
i, | |||||
j | ) |
Definition at line 708 of file app_voicemail_imapstorage.c.
#define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 733 of file app_voicemail_imapstorage.c.
#define VALID_DTMF "1234567890*#" |
Definition at line 414 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 451 of file app_voicemail_imapstorage.c.
#define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 449 of file app_voicemail_imapstorage.c.
#define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 450 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 448 of file app_voicemail_imapstorage.c.
#define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 442 of file app_voicemail_imapstorage.c.
#define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 446 of file app_voicemail_imapstorage.c.
#define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 445 of file app_voicemail_imapstorage.c.
#define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 456 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 455 of file app_voicemail_imapstorage.c.
#define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 454 of file app_voicemail_imapstorage.c.
#define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 439 of file app_voicemail_imapstorage.c.
#define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 447 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 438 of file app_voicemail_imapstorage.c.
#define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 440 of file app_voicemail_imapstorage.c.
#define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 443 of file app_voicemail_imapstorage.c.
#define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 452 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 444 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 441 of file app_voicemail_imapstorage.c.
#define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 453 of file app_voicemail_imapstorage.c.
#define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 648 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 403 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_DIR_MODE 0777 |
Definition at line 399 of file app_voicemail_imapstorage.c.
#define VOICEMAIL_FILE_MODE 0666 |
Definition at line 400 of file app_voicemail_imapstorage.c.
enum vm_box |
Definition at line 461 of file app_voicemail_imapstorage.c.
00461 { 00462 NEW_FOLDER, 00463 OLD_FOLDER, 00464 WORK_FOLDER, 00465 FAMILY_FOLDER, 00466 FRIENDS_FOLDER, 00467 GREETINGS_FOLDER 00468 };
enum vm_option_args |
Definition at line 482 of file app_voicemail_imapstorage.c.
00482 { 00483 OPT_ARG_RECORDGAIN = 0, 00484 OPT_ARG_PLAYFOLDER = 1, 00485 OPT_ARG_DTMFEXIT = 2, 00486 /* This *must* be the last value in this enum! */ 00487 OPT_ARG_ARRAY_SIZE = 3, 00488 };
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 470 of file app_voicemail_imapstorage.c.
00470 { 00471 OPT_SILENT = (1 << 0), 00472 OPT_BUSY_GREETING = (1 << 1), 00473 OPT_UNAVAIL_GREETING = (1 << 2), 00474 OPT_RECORDGAIN = (1 << 3), 00475 OPT_PREPEND_MAILBOX = (1 << 4), 00476 OPT_AUTOPLAY = (1 << 6), 00477 OPT_DTMFEXIT = (1 << 7), 00478 OPT_MESSAGE_Urgent = (1 << 8), 00479 OPT_MESSAGE_PRIORITY = (1 << 9) 00480 };
enum vm_passwordlocation |
Definition at line 490 of file app_voicemail_imapstorage.c.
00490 { 00491 OPT_PWLOC_VOICEMAILCONF = 0, 00492 OPT_PWLOC_SPOOLDIR = 1, 00493 OPT_PWLOC_USERSCONF = 2, 00494 };
static int __has_voicemail | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder, | |||
int | shortcircuit | |||
) | [static] |
Definition at line 5245 of file app_voicemail_imapstorage.c.
References ast_strlen_zero().
05246 { 05247 DIR *dir; 05248 struct dirent *de; 05249 char fn[256]; 05250 int ret = 0; 05251 05252 /* If no mailbox, return immediately */ 05253 if (ast_strlen_zero(mailbox)) 05254 return 0; 05255 05256 if (ast_strlen_zero(folder)) 05257 folder = "INBOX"; 05258 if (ast_strlen_zero(context)) 05259 context = "default"; 05260 05261 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05262 05263 if (!(dir = opendir(fn))) 05264 return 0; 05265 05266 while ((de = readdir(dir))) { 05267 if (!strncasecmp(de->d_name, "msg", 3)) { 05268 if (shortcircuit) { 05269 ret = 1; 05270 break; 05271 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05272 ret++; 05273 } 05274 } 05275 } 05276 05277 closedir(dir); 05278 05279 return ret; 05280 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 13243 of file app_voicemail_imapstorage.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 13243 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 10744 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().
10745 { 10746 struct ast_vm_user svm; 10747 AST_DECLARE_APP_ARGS(arg, 10748 AST_APP_ARG(mbox); 10749 AST_APP_ARG(context); 10750 ); 10751 10752 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 10753 10754 if (ast_strlen_zero(arg.mbox)) { 10755 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 10756 return -1; 10757 } 10758 10759 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 10760 return 0; 10761 }
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 4663 of file app_voicemail_imapstorage.c.
References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
04664 { 04665 char tmpdir[256], newtmp[256]; 04666 char fname[256]; 04667 char tmpcmd[256]; 04668 int tmpfd = -1; 04669 04670 /* Eww. We want formats to tell us their own MIME type */ 04671 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04672 04673 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04674 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04675 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04676 tmpfd = mkstemp(newtmp); 04677 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04678 ast_debug(3, "newtmp: %s\n", newtmp); 04679 if (tmpfd > -1) { 04680 int soxstatus; 04681 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04682 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04683 attach = newtmp; 04684 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04685 } else { 04686 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04687 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04688 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04689 } 04690 } 04691 } 04692 fprintf(p, "--%s" ENDL, bound); 04693 if (msgnum > -1) 04694 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04695 else 04696 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04697 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04698 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04699 if (msgnum > -1) 04700 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04701 else 04702 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04703 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04704 base_encode(fname, p); 04705 if (last) 04706 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04707 if (tmpfd > -1) { 04708 unlink(fname); 04709 close(tmpfd); 04710 unlink(newtmp); 04711 } 04712 return 0; 04713 }
static void adsi_begin | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6261 of file app_voicemail_imapstorage.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available(), ast_adsi_load_session(), and ast_log().
06262 { 06263 int x; 06264 if (!ast_adsi_available(chan)) 06265 return; 06266 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 06267 if (x < 0) 06268 return; 06269 if (!x) { 06270 if (adsi_load_vmail(chan, useadsi)) { 06271 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 06272 return; 06273 } 06274 } else 06275 *useadsi = 1; 06276 }
static void adsi_delete | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6450 of file app_voicemail_imapstorage.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ast_adsi_available(), and vm_state::curmsg.
06451 { 06452 int bytes = 0; 06453 unsigned char buf[256]; 06454 unsigned char keys[8]; 06455 06456 int x; 06457 06458 if (!ast_adsi_available(chan)) 06459 return; 06460 06461 /* New meaning for keys */ 06462 for (x = 0; x < 5; x++) 06463 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06464 06465 keys[6] = 0x0; 06466 keys[7] = 0x0; 06467 06468 if (!vms->curmsg) { 06469 /* No prev key, provide "Folder" instead */ 06470 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06471 } 06472 if (vms->curmsg >= vms->lastmsg) { 06473 /* If last message ... */ 06474 if (vms->curmsg) { 06475 /* but not only message, provide "Folder" instead */ 06476 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06477 } else { 06478 /* Otherwise if only message, leave blank */ 06479 keys[3] = 1; 06480 } 06481 } 06482 06483 /* If deleted, show "undeleted" */ 06484 if (vms->deleted[vms->curmsg]) 06485 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06486 06487 /* Except "Exit" */ 06488 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06489 bytes += ast_adsi_set_keys(buf + bytes, keys); 06490 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06491 06492 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06493 }
static void adsi_folders | ( | struct ast_channel * | chan, | |
int | start, | |||
char * | label | |||
) | [static] |
Definition at line 6326 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().
06327 { 06328 unsigned char buf[256]; 06329 int bytes = 0; 06330 unsigned char keys[8]; 06331 int x, y; 06332 06333 if (!ast_adsi_available(chan)) 06334 return; 06335 06336 for (x = 0; x < 5; x++) { 06337 y = ADSI_KEY_APPS + 12 + start + x; 06338 if (y > ADSI_KEY_APPS + 12 + 4) 06339 y = 0; 06340 keys[x] = ADSI_KEY_SKT | y; 06341 } 06342 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 06343 keys[6] = 0; 06344 keys[7] = 0; 06345 06346 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 06347 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 06348 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06349 bytes += ast_adsi_set_keys(buf + bytes, keys); 06350 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06351 06352 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06353 }
static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6598 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().
06599 { 06600 unsigned char buf[256]; 06601 int bytes = 0; 06602 06603 if (!ast_adsi_available(chan)) 06604 return; 06605 bytes += adsi_logo(buf + bytes); 06606 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06607 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06608 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06609 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06610 06611 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06612 }
static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
int * | useadsi | |||
) | [static] |
Definition at line 6132 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, 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().
06133 { 06134 unsigned char buf[256]; 06135 int bytes = 0; 06136 int x; 06137 char num[5]; 06138 06139 *useadsi = 0; 06140 bytes += ast_adsi_data_mode(buf + bytes); 06141 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06142 06143 bytes = 0; 06144 bytes += adsi_logo(buf); 06145 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06146 #ifdef DISPLAY 06147 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06148 #endif 06149 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06150 bytes += ast_adsi_data_mode(buf + bytes); 06151 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06152 06153 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06154 bytes = 0; 06155 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06156 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06157 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06158 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06159 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06160 return 0; 06161 } 06162 06163 #ifdef DISPLAY 06164 /* Add a dot */ 06165 bytes = 0; 06166 bytes += ast_adsi_logo(buf); 06167 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06168 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06169 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06170 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06171 #endif 06172 bytes = 0; 06173 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06174 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06175 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06176 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06177 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06178 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 06179 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06180 06181 #ifdef DISPLAY 06182 /* Add another dot */ 06183 bytes = 0; 06184 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 06185 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06186 06187 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06188 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06189 #endif 06190 06191 bytes = 0; 06192 /* These buttons we load but don't use yet */ 06193 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 06194 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 06195 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 06196 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 06197 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 06198 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 06199 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06200 06201 #ifdef DISPLAY 06202 /* Add another dot */ 06203 bytes = 0; 06204 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 06205 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06206 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06207 #endif 06208 06209 bytes = 0; 06210 for (x = 0; x < 5; x++) { 06211 snprintf(num, sizeof(num), "%d", x); 06212 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 06213 } 06214 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 06215 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06216 06217 #ifdef DISPLAY 06218 /* Add another dot */ 06219 bytes = 0; 06220 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 06221 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06222 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06223 #endif 06224 06225 if (ast_adsi_end_download(chan)) { 06226 bytes = 0; 06227 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 06228 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06229 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06230 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06231 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06232 return 0; 06233 } 06234 bytes = 0; 06235 bytes += ast_adsi_download_disconnect(buf + bytes); 06236 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06237 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 06238 06239 ast_debug(1, "Done downloading scripts...\n"); 06240 06241 #ifdef DISPLAY 06242 /* Add last dot */ 06243 bytes = 0; 06244 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 06245 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06246 #endif 06247 ast_debug(1, "Restarting session...\n"); 06248 06249 bytes = 0; 06250 /* Load the session now */ 06251 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 06252 *useadsi = 1; 06253 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 06254 } else 06255 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 06256 06257 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06258 return 0; 06259 }
static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6278 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().
06279 { 06280 unsigned char buf[256]; 06281 int bytes = 0; 06282 unsigned char keys[8]; 06283 int x; 06284 if (!ast_adsi_available(chan)) 06285 return; 06286 06287 for (x = 0; x < 8; x++) 06288 keys[x] = 0; 06289 /* Set one key for next */ 06290 keys[3] = ADSI_KEY_APPS + 3; 06291 06292 bytes += adsi_logo(buf + bytes); 06293 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 06294 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 06295 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06296 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 06297 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 06298 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 06299 bytes += ast_adsi_set_keys(buf + bytes, keys); 06300 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06301 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06302 }
static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6124 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display().
06125 { 06126 int bytes = 0; 06127 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06128 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06129 return bytes; 06130 }
static void adsi_message | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6355 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, and strsep().
06356 { 06357 int bytes = 0; 06358 unsigned char buf[256]; 06359 char buf1[256], buf2[256]; 06360 char fn2[PATH_MAX]; 06361 06362 char cid[256] = ""; 06363 char *val; 06364 char *name, *num; 06365 char datetime[21] = ""; 06366 FILE *f; 06367 06368 unsigned char keys[8]; 06369 06370 int x; 06371 06372 if (!ast_adsi_available(chan)) 06373 return; 06374 06375 /* Retrieve important info */ 06376 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06377 f = fopen(fn2, "r"); 06378 if (f) { 06379 while (!feof(f)) { 06380 if (!fgets((char *) buf, sizeof(buf), f)) { 06381 continue; 06382 } 06383 if (!feof(f)) { 06384 char *stringp = NULL; 06385 stringp = (char *) buf; 06386 strsep(&stringp, "="); 06387 val = strsep(&stringp, "="); 06388 if (!ast_strlen_zero(val)) { 06389 if (!strcmp((char *) buf, "callerid")) 06390 ast_copy_string(cid, val, sizeof(cid)); 06391 if (!strcmp((char *) buf, "origdate")) 06392 ast_copy_string(datetime, val, sizeof(datetime)); 06393 } 06394 } 06395 } 06396 fclose(f); 06397 } 06398 /* New meaning for keys */ 06399 for (x = 0; x < 5; x++) 06400 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06401 keys[6] = 0x0; 06402 keys[7] = 0x0; 06403 06404 if (!vms->curmsg) { 06405 /* No prev key, provide "Folder" instead */ 06406 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06407 } 06408 if (vms->curmsg >= vms->lastmsg) { 06409 /* If last message ... */ 06410 if (vms->curmsg) { 06411 /* but not only message, provide "Folder" instead */ 06412 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06413 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06414 06415 } else { 06416 /* Otherwise if only message, leave blank */ 06417 keys[3] = 1; 06418 } 06419 } 06420 06421 if (!ast_strlen_zero(cid)) { 06422 ast_callerid_parse(cid, &name, &num); 06423 if (!name) 06424 name = num; 06425 } else 06426 name = "Unknown Caller"; 06427 06428 /* If deleted, show "undeleted" */ 06429 06430 if (vms->deleted[vms->curmsg]) 06431 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06432 06433 /* Except "Exit" */ 06434 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06435 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06436 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06437 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06438 06439 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06440 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06441 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06442 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06443 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06444 bytes += ast_adsi_set_keys(buf + bytes, keys); 06445 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06446 06447 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06448 }
static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6304 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().
06305 { 06306 unsigned char buf[256]; 06307 int bytes = 0; 06308 unsigned char keys[8]; 06309 int x; 06310 if (!ast_adsi_available(chan)) 06311 return; 06312 06313 for (x = 0; x < 8; x++) 06314 keys[x] = 0; 06315 /* Set one key for next */ 06316 keys[3] = ADSI_KEY_APPS + 3; 06317 06318 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06319 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 06320 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 06321 bytes += ast_adsi_set_keys(buf + bytes, keys); 06322 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06323 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06324 }
static void adsi_status | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6495 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
06496 { 06497 unsigned char buf[256] = ""; 06498 char buf1[256] = "", buf2[256] = ""; 06499 int bytes = 0; 06500 unsigned char keys[8]; 06501 int x; 06502 06503 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06504 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06505 if (!ast_adsi_available(chan)) 06506 return; 06507 if (vms->newmessages) { 06508 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06509 if (vms->oldmessages) { 06510 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06511 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06512 } else { 06513 snprintf(buf2, sizeof(buf2), "%s.", newm); 06514 } 06515 } else if (vms->oldmessages) { 06516 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06517 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06518 } else { 06519 strcpy(buf1, "You have no messages."); 06520 buf2[0] = ' '; 06521 buf2[1] = '\0'; 06522 } 06523 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06524 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06525 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06526 06527 for (x = 0; x < 6; x++) 06528 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06529 keys[6] = 0; 06530 keys[7] = 0; 06531 06532 /* Don't let them listen if there are none */ 06533 if (vms->lastmsg < 0) 06534 keys[0] = 1; 06535 bytes += ast_adsi_set_keys(buf + bytes, keys); 06536 06537 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06538 06539 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06540 }
static void adsi_status2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 6542 of file app_voicemail_imapstorage.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available(), ast_adsi_display(), ast_adsi_set_keys(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_voice_mode(), vm_state::curbox, and vm_state::lastmsg.
06543 { 06544 unsigned char buf[256] = ""; 06545 char buf1[256] = "", buf2[256] = ""; 06546 int bytes = 0; 06547 unsigned char keys[8]; 06548 int x; 06549 06550 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06551 06552 if (!ast_adsi_available(chan)) 06553 return; 06554 06555 /* Original command keys */ 06556 for (x = 0; x < 6; x++) 06557 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06558 06559 keys[6] = 0; 06560 keys[7] = 0; 06561 06562 if ((vms->lastmsg + 1) < 1) 06563 keys[0] = 0; 06564 06565 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06566 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06567 06568 if (vms->lastmsg + 1) 06569 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06570 else 06571 strcpy(buf2, "no messages."); 06572 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06573 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06574 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06575 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06576 bytes += ast_adsi_set_keys(buf + bytes, keys); 06577 06578 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06579 06580 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06581 06582 }
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 12809 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_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_datetime(), RETRIEVE, vm_state::starting, and wait_file().
12810 { 12811 int res = 0; 12812 char filename[PATH_MAX]; 12813 struct ast_config *msg_cfg = NULL; 12814 const char *origtime, *context; 12815 char *name, *num; 12816 int retries = 0; 12817 char *cid; 12818 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 12819 12820 vms->starting = 0; 12821 12822 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 12823 12824 /* Retrieve info from VM attribute file */ 12825 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 12826 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 12827 msg_cfg = ast_config_load(filename, config_flags); 12828 DISPOSE(vms->curdir, vms->curmsg); 12829 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 12830 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 12831 return 0; 12832 } 12833 12834 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 12835 ast_config_destroy(msg_cfg); 12836 return 0; 12837 } 12838 12839 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 12840 12841 context = ast_variable_retrieve(msg_cfg, "message", "context"); 12842 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 12843 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 12844 switch (option) { 12845 case 3: /* Play message envelope */ 12846 if (!res) 12847 res = play_message_datetime(chan, vmu, origtime, filename); 12848 if (!res) 12849 res = play_message_callerid(chan, vms, cid, context, 0); 12850 12851 res = 't'; 12852 break; 12853 12854 case 2: /* Call back */ 12855 12856 if (ast_strlen_zero(cid)) 12857 break; 12858 12859 ast_callerid_parse(cid, &name, &num); 12860 while ((res > -1) && (res != 't')) { 12861 switch (res) { 12862 case '1': 12863 if (num) { 12864 /* Dial the CID number */ 12865 res = dialout(chan, vmu, num, vmu->callback); 12866 if (res) { 12867 ast_config_destroy(msg_cfg); 12868 return 9; 12869 } 12870 } else { 12871 res = '2'; 12872 } 12873 break; 12874 12875 case '2': 12876 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 12877 if (!ast_strlen_zero(vmu->dialout)) { 12878 res = dialout(chan, vmu, NULL, vmu->dialout); 12879 if (res) { 12880 ast_config_destroy(msg_cfg); 12881 return 9; 12882 } 12883 } else { 12884 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 12885 res = ast_play_and_wait(chan, "vm-sorry"); 12886 } 12887 ast_config_destroy(msg_cfg); 12888 return res; 12889 case '*': 12890 res = 't'; 12891 break; 12892 case '3': 12893 case '4': 12894 case '5': 12895 case '6': 12896 case '7': 12897 case '8': 12898 case '9': 12899 case '0': 12900 12901 res = ast_play_and_wait(chan, "vm-sorry"); 12902 retries++; 12903 break; 12904 default: 12905 if (num) { 12906 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 12907 res = ast_play_and_wait(chan, "vm-num-i-have"); 12908 if (!res) 12909 res = play_message_callerid(chan, vms, num, vmu->context, 1); 12910 if (!res) 12911 res = ast_play_and_wait(chan, "vm-tocallnum"); 12912 /* Only prompt for a caller-specified number if there is a dialout context specified */ 12913 if (!ast_strlen_zero(vmu->dialout)) { 12914 if (!res) 12915 res = ast_play_and_wait(chan, "vm-calldiffnum"); 12916 } 12917 } else { 12918 res = ast_play_and_wait(chan, "vm-nonumber"); 12919 if (!ast_strlen_zero(vmu->dialout)) { 12920 if (!res) 12921 res = ast_play_and_wait(chan, "vm-toenternumber"); 12922 } 12923 } 12924 if (!res) 12925 res = ast_play_and_wait(chan, "vm-star-cancel"); 12926 if (!res) 12927 res = ast_waitfordigit(chan, 6000); 12928 if (!res) { 12929 retries++; 12930 if (retries > 3) 12931 res = 't'; 12932 } 12933 break; 12934 12935 } 12936 if (res == 't') 12937 res = 0; 12938 else if (res == '*') 12939 res = -1; 12940 } 12941 break; 12942 12943 case 1: /* Reply */ 12944 /* Send reply directly to sender */ 12945 if (ast_strlen_zero(cid)) 12946 break; 12947 12948 ast_callerid_parse(cid, &name, &num); 12949 if (!num) { 12950 ast_verb(3, "No CID number available, no reply sent\n"); 12951 if (!res) 12952 res = ast_play_and_wait(chan, "vm-nonumber"); 12953 ast_config_destroy(msg_cfg); 12954 return res; 12955 } else { 12956 struct ast_vm_user vmu2; 12957 if (find_user(&vmu2, vmu->context, num)) { 12958 struct leave_vm_options leave_options; 12959 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 12960 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 12961 12962 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 12963 12964 memset(&leave_options, 0, sizeof(leave_options)); 12965 leave_options.record_gain = record_gain; 12966 res = leave_voicemail(chan, mailbox, &leave_options); 12967 if (!res) 12968 res = 't'; 12969 ast_config_destroy(msg_cfg); 12970 return res; 12971 } else { 12972 /* Sender has no mailbox, can't reply */ 12973 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 12974 ast_play_and_wait(chan, "vm-nobox"); 12975 res = 't'; 12976 ast_config_destroy(msg_cfg); 12977 return res; 12978 } 12979 } 12980 res = 0; 12981 12982 break; 12983 } 12984 12985 #ifndef IMAP_STORAGE 12986 ast_config_destroy(msg_cfg); 12987 12988 if (!res) { 12989 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 12990 vms->heard[msg] = 1; 12991 res = wait_file(chan, vms, vms->fn); 12992 } 12993 #endif 12994 return res; 12995 }
static int append_mailbox | ( | const char * | context, | |
const char * | box, | |||
const char * | data | |||
) | [static] |
Definition at line 10487 of file app_voicemail_imapstorage.c.
References apply_options(), ast_copy_string(), ast_strdupa, ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), queue_mwi_event(), read_password_from_file(), and strsep().
10488 { 10489 /* Assumes lock is already held */ 10490 char *tmp; 10491 char *stringp; 10492 char *s; 10493 struct ast_vm_user *vmu; 10494 char *mailbox_full; 10495 int new = 0, old = 0, urgent = 0; 10496 char secretfn[PATH_MAX] = ""; 10497 10498 tmp = ast_strdupa(data); 10499 10500 if (!(vmu = find_or_create(context, box))) 10501 return -1; 10502 10503 populate_defaults(vmu); 10504 10505 stringp = tmp; 10506 if ((s = strsep(&stringp, ","))) { 10507 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 10508 } 10509 if (stringp && (s = strsep(&stringp, ","))) { 10510 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 10511 } 10512 if (stringp && (s = strsep(&stringp, ","))) { 10513 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 10514 } 10515 if (stringp && (s = strsep(&stringp, ","))) { 10516 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 10517 } 10518 if (stringp && (s = strsep(&stringp, ","))) { 10519 apply_options(vmu, s); 10520 } 10521 10522 switch (vmu->passwordlocation) { 10523 case OPT_PWLOC_SPOOLDIR: 10524 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 10525 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 10526 } 10527 10528 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 10529 strcpy(mailbox_full, box); 10530 strcat(mailbox_full, "@"); 10531 strcat(mailbox_full, context); 10532 10533 inboxcount2(mailbox_full, &urgent, &new, &old); 10534 queue_mwi_event(mailbox_full, urgent, new, old); 10535 10536 return 0; 10537 }
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 1009 of file app_voicemail_imapstorage.c.
References apply_options(), ast_copy_string(), ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, 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, 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.
01010 { 01011 int x; 01012 if (!strcasecmp(var, "attach")) { 01013 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01014 } else if (!strcasecmp(var, "attachfmt")) { 01015 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01016 } else if (!strcasecmp(var, "serveremail")) { 01017 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01018 } else if (!strcasecmp(var, "language")) { 01019 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01020 } else if (!strcasecmp(var, "tz")) { 01021 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01022 } else if (!strcasecmp(var, "locale")) { 01023 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01024 #ifdef IMAP_STORAGE 01025 } else if (!strcasecmp(var, "imapuser")) { 01026 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01027 vmu->imapversion = imapversion; 01028 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01029 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01030 vmu->imapversion = imapversion; 01031 } else if (!strcasecmp(var, "imapfolder")) { 01032 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01033 } else if (!strcasecmp(var, "imapvmshareid")) { 01034 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01035 vmu->imapversion = imapversion; 01036 #endif 01037 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01038 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01039 } else if (!strcasecmp(var, "saycid")){ 01040 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01041 } else if (!strcasecmp(var, "sendvoicemail")){ 01042 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01043 } else if (!strcasecmp(var, "review")){ 01044 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01045 } else if (!strcasecmp(var, "tempgreetwarn")){ 01046 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01047 } else if (!strcasecmp(var, "messagewrap")){ 01048 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01049 } else if (!strcasecmp(var, "operator")) { 01050 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01051 } else if (!strcasecmp(var, "envelope")){ 01052 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01053 } else if (!strcasecmp(var, "moveheard")){ 01054 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01055 } else if (!strcasecmp(var, "sayduration")){ 01056 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01057 } else if (!strcasecmp(var, "saydurationm")){ 01058 if (sscanf(value, "%30d", &x) == 1) { 01059 vmu->saydurationm = x; 01060 } else { 01061 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01062 } 01063 } else if (!strcasecmp(var, "forcename")){ 01064 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01065 } else if (!strcasecmp(var, "forcegreetings")){ 01066 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01067 } else if (!strcasecmp(var, "callback")) { 01068 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01069 } else if (!strcasecmp(var, "dialout")) { 01070 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01071 } else if (!strcasecmp(var, "exitcontext")) { 01072 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01073 } else if (!strcasecmp(var, "minsecs")) { 01074 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01075 vmu->minsecs = x; 01076 } else { 01077 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01078 vmu->minsecs = vmminsecs; 01079 } 01080 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01081 vmu->maxsecs = atoi(value); 01082 if (vmu->maxsecs <= 0) { 01083 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01084 vmu->maxsecs = vmmaxsecs; 01085 } else { 01086 vmu->maxsecs = atoi(value); 01087 } 01088 if (!strcasecmp(var, "maxmessage")) 01089 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01090 } else if (!strcasecmp(var, "maxmsg")) { 01091 vmu->maxmsg = atoi(value); 01092 /* Accept maxmsg=0 (Greetings only voicemail) */ 01093 if (vmu->maxmsg < 0) { 01094 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01095 vmu->maxmsg = MAXMSG; 01096 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01097 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01098 vmu->maxmsg = MAXMSGLIMIT; 01099 } 01100 } else if (!strcasecmp(var, "nextaftercmd")) { 01101 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01102 } else if (!strcasecmp(var, "backupdeleted")) { 01103 if (sscanf(value, "%30d", &x) == 1) 01104 vmu->maxdeletedmsg = x; 01105 else if (ast_true(value)) 01106 vmu->maxdeletedmsg = MAXMSG; 01107 else 01108 vmu->maxdeletedmsg = 0; 01109 01110 if (vmu->maxdeletedmsg < 0) { 01111 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01112 vmu->maxdeletedmsg = MAXMSG; 01113 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01114 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01115 vmu->maxdeletedmsg = MAXMSGLIMIT; 01116 } 01117 } else if (!strcasecmp(var, "volgain")) { 01118 sscanf(value, "%30lf", &vmu->volgain); 01119 } else if (!strcasecmp(var, "passwordlocation")) { 01120 if (!strcasecmp(value, "spooldir")) { 01121 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01122 } else { 01123 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01124 } 01125 } else if (!strcasecmp(var, "options")) { 01126 apply_options(vmu, value); 01127 } 01128 }
static void apply_options | ( | struct ast_vm_user * | vmu, | |
const char * | options | |||
) | [static] |
Destructively Parse options and apply.
Definition at line 1242 of file app_voicemail_imapstorage.c.
References apply_option(), ast_strdupa, strsep(), value, and var.
01243 { 01244 char *stringp; 01245 char *s; 01246 char *var, *value; 01247 stringp = ast_strdupa(options); 01248 while ((s = strsep(&stringp, "|"))) { 01249 value = s; 01250 if ((var = strsep(&value, "=")) && value) { 01251 apply_option(vmu, var, value); 01252 } 01253 } 01254 }
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 1261 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_strlen_zero(), ast_vm_user::password, and var.
01262 { 01263 for (; var; var = var->next) { 01264 if (!strcasecmp(var->name, "vmsecret")) { 01265 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01266 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01267 if (ast_strlen_zero(retval->password)) 01268 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01269 } else if (!strcasecmp(var->name, "uniqueid")) { 01270 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01271 } else if (!strcasecmp(var->name, "pager")) { 01272 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01273 } else if (!strcasecmp(var->name, "email")) { 01274 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01275 } else if (!strcasecmp(var->name, "fullname")) { 01276 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01277 } else if (!strcasecmp(var->name, "context")) { 01278 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01279 } else if (!strcasecmp(var->name, "emailsubject")) { 01280 retval->emailsubject = ast_strdup(var->value); 01281 } else if (!strcasecmp(var->name, "emailbody")) { 01282 retval->emailbody = ast_strdup(var->value); 01283 #ifdef IMAP_STORAGE 01284 } else if (!strcasecmp(var->name, "imapuser")) { 01285 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01286 retval->imapversion = imapversion; 01287 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01288 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01289 retval->imapversion = imapversion; 01290 } else if (!strcasecmp(var->name, "imapfolder")) { 01291 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01292 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01293 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01294 retval->imapversion = imapversion; 01295 #endif 01296 } else 01297 apply_option(retval, var->name, var->value); 01298 } 01299 }
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 4338 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.
04339 { 04340 struct ast_str *tmp = ast_str_alloca(80); 04341 int first_section = 1; 04342 04343 ast_str_reset(*end); 04344 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04345 for (; *start; start++) { 04346 int need_encoding = 0; 04347 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04348 need_encoding = 1; 04349 } 04350 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04351 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04352 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04353 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04354 /* Start new line */ 04355 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04356 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04357 first_section = 0; 04358 } 04359 if (need_encoding && *start == ' ') { 04360 ast_str_append(&tmp, -1, "_"); 04361 } else if (need_encoding) { 04362 ast_str_append(&tmp, -1, "=%hhX", *start); 04363 } else { 04364 ast_str_append(&tmp, -1, "%c", *start); 04365 } 04366 } 04367 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04368 return ast_str_buffer(*end); 04369 }
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 4266 of file app_voicemail_imapstorage.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04267 { 04268 const char *ptr; 04269 04270 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04271 ast_str_set(buf, maxlen, "\""); 04272 for (ptr = from; *ptr; ptr++) { 04273 if (*ptr == '"' || *ptr == '\\') { 04274 ast_str_append(buf, maxlen, "\\%c", *ptr); 04275 } else { 04276 ast_str_append(buf, maxlen, "%c", *ptr); 04277 } 04278 } 04279 ast_str_append(buf, maxlen, "\""); 04280 04281 return ast_str_buffer(*buf); 04282 }
AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 10539 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, 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.
10540 { 10541 int res = 0; 10542 struct ast_vm_user *vmu; 10543 /* language parameter seems to only be used for display in manager action */ 10544 static const char options_string[] = "attach=yes|attachfmt=wav49|" 10545 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 10546 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 10547 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 10548 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 10549 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 10550 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir"; 10551 #ifdef IMAP_STORAGE 10552 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 10553 "imapfolder=INBOX|imapvmshareid=6000"; 10554 #endif 10555 10556 switch (cmd) { 10557 case TEST_INIT: 10558 info->name = "vmuser"; 10559 info->category = "/apps/app_voicemail/"; 10560 info->summary = "Vmuser unit test"; 10561 info->description = 10562 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 10563 return AST_TEST_NOT_RUN; 10564 case TEST_EXECUTE: 10565 break; 10566 } 10567 10568 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 10569 return AST_TEST_NOT_RUN; 10570 } 10571 ast_set_flag(vmu, VM_ALLOCED); 10572 10573 apply_options(vmu, options_string); 10574 10575 if (!ast_test_flag(vmu, VM_ATTACH)) { 10576 ast_test_status_update(test, "Parse failure for attach option\n"); 10577 res = 1; 10578 } 10579 if (strcasecmp(vmu->attachfmt, "wav49")) { 10580 ast_test_status_update(test, "Parse failure for attachftm option\n"); 10581 res = 1; 10582 } 10583 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 10584 ast_test_status_update(test, "Parse failure for serveremail option\n"); 10585 res = 1; 10586 } 10587 if (strcasecmp(vmu->zonetag, "central")) { 10588 ast_test_status_update(test, "Parse failure for tz option\n"); 10589 res = 1; 10590 } 10591 if (!ast_test_flag(vmu, VM_DELETE)) { 10592 ast_test_status_update(test, "Parse failure for delete option\n"); 10593 res = 1; 10594 } 10595 if (!ast_test_flag(vmu, VM_SAYCID)) { 10596 ast_test_status_update(test, "Parse failure for saycid option\n"); 10597 res = 1; 10598 } 10599 if (!ast_test_flag(vmu, VM_SVMAIL)) { 10600 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 10601 res = 1; 10602 } 10603 if (!ast_test_flag(vmu, VM_REVIEW)) { 10604 ast_test_status_update(test, "Parse failure for review option\n"); 10605 res = 1; 10606 } 10607 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 10608 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 10609 res = 1; 10610 } 10611 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 10612 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 10613 res = 1; 10614 } 10615 if (!ast_test_flag(vmu, VM_OPERATOR)) { 10616 ast_test_status_update(test, "Parse failure for operator option\n"); 10617 res = 1; 10618 } 10619 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 10620 ast_test_status_update(test, "Parse failure for envelope option\n"); 10621 res = 1; 10622 } 10623 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 10624 ast_test_status_update(test, "Parse failure for moveheard option\n"); 10625 res = 1; 10626 } 10627 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 10628 ast_test_status_update(test, "Parse failure for sayduration option\n"); 10629 res = 1; 10630 } 10631 if (vmu->saydurationm != 5) { 10632 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 10633 res = 1; 10634 } 10635 if (!ast_test_flag(vmu, VM_FORCENAME)) { 10636 ast_test_status_update(test, "Parse failure for forcename option\n"); 10637 res = 1; 10638 } 10639 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 10640 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 10641 res = 1; 10642 } 10643 if (strcasecmp(vmu->callback, "somecontext")) { 10644 ast_test_status_update(test, "Parse failure for callbacks option\n"); 10645 res = 1; 10646 } 10647 if (strcasecmp(vmu->dialout, "somecontext2")) { 10648 ast_test_status_update(test, "Parse failure for dialout option\n"); 10649 res = 1; 10650 } 10651 if (strcasecmp(vmu->exit, "somecontext3")) { 10652 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 10653 res = 1; 10654 } 10655 if (vmu->minsecs != 10) { 10656 ast_test_status_update(test, "Parse failure for minsecs option\n"); 10657 res = 1; 10658 } 10659 if (vmu->maxsecs != 100) { 10660 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 10661 res = 1; 10662 } 10663 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10664 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 10665 res = 1; 10666 } 10667 if (vmu->maxdeletedmsg != 50) { 10668 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 10669 res = 1; 10670 } 10671 if (vmu->volgain != 1.3) { 10672 ast_test_status_update(test, "Parse failure for volgain option\n"); 10673 res = 1; 10674 } 10675 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 10676 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 10677 res = 1; 10678 } 10679 #ifdef IMAP_STORAGE 10680 apply_options(vmu, option_string2); 10681 10682 if (strcasecmp(vmu->imapuser, "imapuser")) { 10683 ast_test_status_update(test, "Parse failure for imapuser option\n"); 10684 res = 1; 10685 } 10686 if (strcasecmp(vmu->imappassword, "imappasswd")) { 10687 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10688 res = 1; 10689 } 10690 if (strcasecmp(vmu->imapfolder, "INBOX")) { 10691 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 10692 res = 1; 10693 } 10694 if (strcasecmp(vmu->imapvmshareid, "6000")) { 10695 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 10696 res = 1; 10697 } 10698 #endif 10699 10700 free_user(vmu); 10701 return res ? AST_TEST_FAIL : AST_TEST_PASS; 10702 }
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 4142 of file app_voicemail_imapstorage.c.
References ast_log(), BASEMAXINLINE, ENDL, errno, inchar(), and ochar().
04143 { 04144 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04145 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04146 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04147 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04148 int i, hiteof = 0; 04149 FILE *fi; 04150 struct baseio bio; 04151 04152 memset(&bio, 0, sizeof(bio)); 04153 bio.iocp = BASEMAXINLINE; 04154 04155 if (!(fi = fopen(filename, "rb"))) { 04156 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04157 return -1; 04158 } 04159 04160 while (!hiteof){ 04161 unsigned char igroup[3], ogroup[4]; 04162 int c, n; 04163 04164 memset(igroup, 0, sizeof(igroup)); 04165 04166 for (n = 0; n < 3; n++) { 04167 if ((c = inchar(&bio, fi)) == EOF) { 04168 hiteof = 1; 04169 break; 04170 } 04171 04172 igroup[n] = (unsigned char) c; 04173 } 04174 04175 if (n > 0) { 04176 ogroup[0]= dtable[igroup[0] >> 2]; 04177 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04178 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04179 ogroup[3]= dtable[igroup[2] & 0x3F]; 04180 04181 if (n < 3) { 04182 ogroup[3] = '='; 04183 04184 if (n < 2) 04185 ogroup[2] = '='; 04186 } 04187 04188 for (i = 0; i < 4; i++) 04189 ochar(&bio, ogroup[i], so); 04190 } 04191 } 04192 04193 fclose(fi); 04194 04195 if (fputs(ENDL, so) == EOF) { 04196 return 0; 04197 } 04198 04199 return 1; 04200 }
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 1221 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_realtime_require_field(), ast_update2_realtime(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, RQ_CHAR, and SENTINEL.
01222 { 01223 int res = -1; 01224 if (!strcmp(vmu->password, password)) { 01225 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01226 return 0; 01227 } 01228 01229 if (strlen(password) > 10) { 01230 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01231 } 01232 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01233 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01234 res = 0; 01235 } 01236 return res; 01237 }
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 4311 of file app_voicemail_imapstorage.c.
04312 { 04313 for (; *str; str++) { 04314 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04315 return 1; 04316 } 04317 } 04318 return 0; 04319 }
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 1183 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().
01184 { 01185 /* check minimum length */ 01186 if (strlen(password) < minpassword) 01187 return 1; 01188 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01189 char cmd[255], buf[255]; 01190 01191 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01192 01193 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01194 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01195 ast_debug(5, "Result: %s\n", buf); 01196 if (!strncasecmp(buf, "VALID", 5)) { 01197 ast_debug(3, "Passed password check: '%s'\n", buf); 01198 return 0; 01199 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01200 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01201 return 0; 01202 } else { 01203 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01204 return 1; 01205 } 01206 } 01207 } 01208 return 0; 01209 }
static int close_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 7765 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_log(), 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, vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
07766 { 07767 int x = 0; 07768 #ifndef IMAP_STORAGE 07769 int res = 0, nummsg; 07770 char fn2[PATH_MAX]; 07771 #endif 07772 07773 if (vms->lastmsg <= -1) { 07774 goto done; 07775 } 07776 07777 vms->curmsg = -1; 07778 #ifndef IMAP_STORAGE 07779 /* Get the deleted messages fixed */ 07780 if (vm_lock_path(vms->curdir)) { 07781 return ERROR_LOCK_PATH; 07782 } 07783 07784 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 07785 for (x = 0; x < vms->lastmsg + 1; x++) { 07786 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07787 /* Save this message. It's not in INBOX or hasn't been heard */ 07788 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07789 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 07790 break; 07791 } 07792 vms->curmsg++; 07793 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07794 if (strcmp(vms->fn, fn2)) { 07795 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07796 } 07797 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07798 /* Move to old folder before deleting */ 07799 res = save_to_folder(vmu, vms, x, 1); 07800 if (res == ERROR_LOCK_PATH) { 07801 /* If save failed do not delete the message */ 07802 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07803 vms->deleted[x] = 0; 07804 vms->heard[x] = 0; 07805 --x; 07806 } 07807 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07808 /* Move to deleted folder */ 07809 res = save_to_folder(vmu, vms, x, 10); 07810 if (res == ERROR_LOCK_PATH) { 07811 /* If save failed do not delete the message */ 07812 vms->deleted[x] = 0; 07813 vms->heard[x] = 0; 07814 --x; 07815 } 07816 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07817 /* If realtime storage enabled - we should explicitly delete this message, 07818 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07819 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07820 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07821 DELETE(vms->curdir, x, vms->fn, vmu); 07822 } 07823 } 07824 } 07825 07826 /* Delete ALL remaining messages */ 07827 nummsg = x - 1; 07828 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07829 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07830 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 07831 DELETE(vms->curdir, x, vms->fn, vmu); 07832 } 07833 } 07834 ast_unlock_path(vms->curdir); 07835 #else /* defined(IMAP_STORAGE) */ 07836 if (vms->deleted) { 07837 /* Since we now expunge after each delete, deleting in reverse order 07838 * ensures that no reordering occurs between each step. */ 07839 for (x = vms->dh_arraysize - 1; x >= 0; x--) { 07840 if (vms->deleted[x]) { 07841 ast_debug(3, "IMAP delete of %d\n", x); 07842 DELETE(vms->curdir, x, vms->fn, vmu); 07843 } 07844 } 07845 } 07846 #endif 07847 07848 done: 07849 if (vms->deleted && vmu->maxmsg) { 07850 memset(vms->deleted, 0, vms->dh_arraysize * sizeof(int)); 07851 } 07852 if (vms->heard && vmu->maxmsg) { 07853 memset(vms->heard, 0, vms->dh_arraysize * sizeof(int)); 07854 } 07855 07856 return 0; 07857 }
static char* complete_voicemail_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 10848 of file app_voicemail_imapstorage.c.
References AST_LIST_TRAVERSE, ast_strdup, ast_vm_user::context, and ast_vm_user::list.
10849 { 10850 int which = 0; 10851 int wordlen; 10852 struct ast_vm_user *vmu; 10853 const char *context = ""; 10854 10855 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 10856 if (pos > 4) 10857 return NULL; 10858 if (pos == 3) 10859 return (state == 0) ? ast_strdup("for") : NULL; 10860 wordlen = strlen(word); 10861 AST_LIST_TRAVERSE(&users, vmu, list) { 10862 if (!strncasecmp(word, vmu->context, wordlen)) { 10863 if (context && strcmp(context, vmu->context) && ++which > state) 10864 return ast_strdup(vmu->context); 10865 /* ignore repeated contexts ? */ 10866 context = vmu->context; 10867 } 10868 } 10869 return NULL; 10870 }
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 3946 of file app_voicemail_imapstorage.c.
References ast_log(), errno, and VOICEMAIL_FILE_MODE.
03947 { 03948 int ifd; 03949 int ofd; 03950 int res; 03951 int len; 03952 char buf[4096]; 03953 03954 #ifdef HARDLINK_WHEN_POSSIBLE 03955 /* Hard link if possible; saves disk space & is faster */ 03956 if (link(infile, outfile)) { 03957 #endif 03958 if ((ifd = open(infile, O_RDONLY)) < 0) { 03959 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03960 return -1; 03961 } 03962 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03963 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03964 close(ifd); 03965 return -1; 03966 } 03967 do { 03968 len = read(ifd, buf, sizeof(buf)); 03969 if (len < 0) { 03970 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03971 close(ifd); 03972 close(ofd); 03973 unlink(outfile); 03974 } 03975 if (len) { 03976 res = write(ofd, buf, len); 03977 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03978 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03979 close(ifd); 03980 close(ofd); 03981 unlink(outfile); 03982 } 03983 } 03984 } while (len); 03985 close(ifd); 03986 close(ofd); 03987 return 0; 03988 #ifdef HARDLINK_WHEN_POSSIBLE 03989 } else { 03990 /* Hard link succeeded */ 03991 return 0; 03992 } 03993 #endif 03994 }
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 5182 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::caller, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_party_caller::id, inprocess_count(), ast_channel::language, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), mbox(), ast_party_id::name, notify_new_message(), ast_party_id::number, S_COR, STORE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, vm_delete(), and vm_lock_path().
05183 { 05184 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05185 const char *frombox = mbox(vmu, imbox); 05186 int recipmsgnum; 05187 int res = 0; 05188 05189 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05190 05191 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05192 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 05193 } else { 05194 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 05195 } 05196 05197 if (!dir) 05198 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05199 else 05200 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05201 05202 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05203 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 05204 05205 if (vm_lock_path(todir)) 05206 return ERROR_LOCK_PATH; 05207 05208 recipmsgnum = last_message_index(recip, todir) + 1; 05209 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05210 make_file(topath, sizeof(topath), todir, recipmsgnum); 05211 #ifndef ODBC_STORAGE 05212 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 05213 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05214 } else { 05215 #endif 05216 /* If we are prepending a message for ODBC, then the message already 05217 * exists in the database, but we want to force copying from the 05218 * filesystem (since only the FS contains the prepend). */ 05219 copy_plain_file(frompath, topath); 05220 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 05221 vm_delete(topath); 05222 #ifndef ODBC_STORAGE 05223 } 05224 #endif 05225 } else { 05226 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05227 res = -1; 05228 } 05229 ast_unlock_path(todir); 05230 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05231 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05232 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05233 flag); 05234 05235 return res; 05236 }
static void copy_plain_file | ( | char * | frompath, | |
char * | topath | |||
) | [static] |
Copies a voicemail information (envelope) file.
frompath | ||
topath |
Definition at line 4005 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.
04006 { 04007 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04008 struct ast_variable *tmp,*var = NULL; 04009 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04010 ast_filecopy(frompath, topath, NULL); 04011 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04012 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04013 if (ast_check_realtime("voicemail_data")) { 04014 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04015 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04016 for (tmp = var; tmp; tmp = tmp->next) { 04017 if (!strcasecmp(tmp->name, "origmailbox")) { 04018 origmailbox = tmp->value; 04019 } else if (!strcasecmp(tmp->name, "context")) { 04020 context = tmp->value; 04021 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04022 macrocontext = tmp->value; 04023 } else if (!strcasecmp(tmp->name, "exten")) { 04024 exten = tmp->value; 04025 } else if (!strcasecmp(tmp->name, "priority")) { 04026 priority = tmp->value; 04027 } else if (!strcasecmp(tmp->name, "callerchan")) { 04028 callerchan = tmp->value; 04029 } else if (!strcasecmp(tmp->name, "callerid")) { 04030 callerid = tmp->value; 04031 } else if (!strcasecmp(tmp->name, "origdate")) { 04032 origdate = tmp->value; 04033 } else if (!strcasecmp(tmp->name, "origtime")) { 04034 origtime = tmp->value; 04035 } else if (!strcasecmp(tmp->name, "category")) { 04036 category = tmp->value; 04037 } else if (!strcasecmp(tmp->name, "duration")) { 04038 duration = tmp->value; 04039 } 04040 } 04041 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); 04042 } 04043 copy(frompath2, topath2); 04044 ast_variables_destroy(var); 04045 }
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 3841 of file app_voicemail_imapstorage.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
03842 { 03843 03844 int vmcount = 0; 03845 DIR *vmdir = NULL; 03846 struct dirent *vment = NULL; 03847 03848 if (vm_lock_path(dir)) 03849 return ERROR_LOCK_PATH; 03850 03851 if ((vmdir = opendir(dir))) { 03852 while ((vment = readdir(vmdir))) { 03853 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03854 vmcount++; 03855 } 03856 } 03857 closedir(vmdir); 03858 } 03859 ast_unlock_path(dir); 03860 03861 return vmcount; 03862 }
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 1609 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01610 { 01611 mode_t mode = VOICEMAIL_DIR_MODE; 01612 int res; 01613 01614 make_dir(dest, len, context, ext, folder); 01615 if ((res = ast_mkdir(dest, mode))) { 01616 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01617 return -1; 01618 } 01619 return 0; 01620 }
static int dialout | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
char * | num, | |||
char * | outgoing_context | |||
) | [static] |
Definition at line 12737 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_verb, ast_verbose, ast_waitfordigit(), ast_channel::context, ast_channel::exten, option_verbose, ast_channel::priority, and VERBOSE_PREFIX_3.
12738 { 12739 int cmd = 0; 12740 char destination[80] = ""; 12741 int retries = 0; 12742 12743 if (!num) { 12744 ast_verb(3, "Destination number will be entered manually\n"); 12745 while (retries < 3 && cmd != 't') { 12746 destination[1] = '\0'; 12747 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 12748 if (!cmd) 12749 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 12750 if (!cmd) 12751 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 12752 if (!cmd) { 12753 cmd = ast_waitfordigit(chan, 6000); 12754 if (cmd) 12755 destination[0] = cmd; 12756 } 12757 if (!cmd) { 12758 retries++; 12759 } else { 12760 12761 if (cmd < 0) 12762 return 0; 12763 if (cmd == '*') { 12764 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 12765 return 0; 12766 } 12767 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 12768 retries++; 12769 else 12770 cmd = 't'; 12771 } 12772 } 12773 if (retries >= 3) { 12774 return 0; 12775 } 12776 12777 } else { 12778 if (option_verbose > 2) 12779 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 12780 ast_copy_string(destination, num, sizeof(destination)); 12781 } 12782 12783 if (!ast_strlen_zero(destination)) { 12784 if (destination[strlen(destination) -1 ] == '*') 12785 return 0; 12786 if (option_verbose > 2) 12787 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 12788 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 12789 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 12790 chan->priority = 0; 12791 return 9; 12792 } 12793 return 0; 12794 }
static struct ast_vm_user* find_or_create | ( | const char * | context, | |
const char * | box | |||
) | [static] |
Definition at line 10455 of file app_voicemail_imapstorage.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_vm_user::context, globalflags, ast_vm_user::list, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
10456 { 10457 struct ast_vm_user *vmu; 10458 10459 AST_LIST_TRAVERSE(&users, vmu, list) { 10460 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 10461 if (strcasecmp(vmu->context, context)) { 10462 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 10463 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 10464 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 10465 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 10466 } 10467 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 10468 return NULL; 10469 } 10470 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 10471 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 10472 return NULL; 10473 } 10474 } 10475 10476 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 10477 return NULL; 10478 10479 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 10480 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 10481 10482 AST_LIST_INSERT_TAIL(&users, vmu, list); 10483 10484 return vmu; 10485 }
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 1370 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_test_flag, find_user_realtime(), globalflags, ast_vm_user::list, VM_ALLOCED, and VM_SEARCH.
01371 { 01372 /* This function could be made to generate one from a database, too */ 01373 struct ast_vm_user *vmu = NULL, *cur; 01374 AST_LIST_LOCK(&users); 01375 01376 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01377 context = "default"; 01378 01379 AST_LIST_TRAVERSE(&users, cur, list) { 01380 #ifdef IMAP_STORAGE 01381 if (cur->imapversion != imapversion) { 01382 continue; 01383 } 01384 #endif 01385 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01386 break; 01387 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01388 break; 01389 } 01390 if (cur) { 01391 /* Make a copy, so that on a reload, we have no race */ 01392 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01393 memcpy(vmu, cur, sizeof(*vmu)); 01394 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01395 AST_LIST_NEXT(vmu, list) = NULL; 01396 } 01397 } else 01398 vmu = find_user_realtime(ivm, context, mailbox); 01399 AST_LIST_UNLOCK(&users); 01400 return vmu; 01401 }
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 1333 of file app_voicemail_imapstorage.c.
References apply_options_full(), ast_calloc, ast_copy_string(), ast_free, ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), globalflags, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
01334 { 01335 struct ast_variable *var; 01336 struct ast_vm_user *retval; 01337 01338 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01339 if (!ivm) 01340 ast_set_flag(retval, VM_ALLOCED); 01341 else 01342 memset(retval, 0, sizeof(*retval)); 01343 if (mailbox) 01344 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01345 populate_defaults(retval); 01346 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01347 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01348 else 01349 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01350 if (var) { 01351 apply_options_full(retval, var); 01352 ast_variables_destroy(var); 01353 } else { 01354 if (!ivm) 01355 ast_free(retval); 01356 retval = NULL; 01357 } 01358 } 01359 return retval; 01360 }
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 6979 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_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(), STORE, ast_party_name::str, ast_party_number::str, strsep(), vm_state::username, ast_party_name::valid, ast_party_number::valid, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
06980 { 06981 #ifdef IMAP_STORAGE 06982 int todircount = 0; 06983 struct vm_state *dstvms; 06984 #endif 06985 char username[70]=""; 06986 char fn[PATH_MAX]; /* for playback of name greeting */ 06987 char ecodes[16] = "#"; 06988 int res = 0, cmd = 0; 06989 struct ast_vm_user *receiver = NULL, *vmtmp; 06990 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 06991 char *stringp; 06992 const char *s; 06993 int saved_messages = 0; 06994 int valid_extensions = 0; 06995 char *dir; 06996 int curmsg; 06997 char urgent_str[7] = ""; 06998 char tmptxtfile[PATH_MAX]; 06999 int prompt_played = 0; 07000 #ifndef IMAP_STORAGE 07001 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07002 #endif 07003 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07004 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07005 } 07006 07007 if (vms == NULL) return -1; 07008 dir = vms->curdir; 07009 curmsg = vms->curmsg; 07010 07011 tmptxtfile[0] = '\0'; 07012 while (!res && !valid_extensions) { 07013 int use_directory = 0; 07014 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07015 int done = 0; 07016 int retries = 0; 07017 cmd = 0; 07018 while ((cmd >= 0) && !done ){ 07019 if (cmd) 07020 retries = 0; 07021 switch (cmd) { 07022 case '1': 07023 use_directory = 0; 07024 done = 1; 07025 break; 07026 case '2': 07027 use_directory = 1; 07028 done = 1; 07029 break; 07030 case '*': 07031 cmd = 't'; 07032 done = 1; 07033 break; 07034 default: 07035 /* Press 1 to enter an extension press 2 to use the directory */ 07036 cmd = ast_play_and_wait(chan, "vm-forward"); 07037 if (!cmd) 07038 cmd = ast_waitfordigit(chan, 3000); 07039 if (!cmd) 07040 retries++; 07041 if (retries > 3) { 07042 cmd = 't'; 07043 done = 1; 07044 } 07045 07046 } 07047 } 07048 if (cmd < 0 || cmd == 't') 07049 break; 07050 } 07051 07052 if (use_directory) { 07053 /* use app_directory */ 07054 07055 char old_context[sizeof(chan->context)]; 07056 char old_exten[sizeof(chan->exten)]; 07057 int old_priority; 07058 struct ast_app* directory_app; 07059 07060 directory_app = pbx_findapp("Directory"); 07061 if (directory_app) { 07062 char vmcontext[256]; 07063 /* make backup copies */ 07064 memcpy(old_context, chan->context, sizeof(chan->context)); 07065 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 07066 old_priority = chan->priority; 07067 07068 /* call the the Directory, changes the channel */ 07069 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07070 res = pbx_exec(chan, directory_app, vmcontext); 07071 07072 ast_copy_string(username, chan->exten, sizeof(username)); 07073 07074 /* restore the old context, exten, and priority */ 07075 memcpy(chan->context, old_context, sizeof(chan->context)); 07076 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 07077 chan->priority = old_priority; 07078 } else { 07079 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07080 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07081 } 07082 } else { 07083 /* Ask for an extension */ 07084 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 07085 prompt_played++; 07086 if (res || prompt_played > 4) 07087 break; 07088 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 07089 break; 07090 } 07091 07092 /* start all over if no username */ 07093 if (ast_strlen_zero(username)) 07094 continue; 07095 stringp = username; 07096 s = strsep(&stringp, "*"); 07097 /* start optimistic */ 07098 valid_extensions = 1; 07099 while (s) { 07100 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 07101 int oldmsgs; 07102 int newmsgs; 07103 int capacity; 07104 if (inboxcount(s, &newmsgs, &oldmsgs)) { 07105 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 07106 /* Shouldn't happen, but allow trying another extension if it does */ 07107 res = ast_play_and_wait(chan, "pbx-invalid"); 07108 valid_extensions = 0; 07109 break; 07110 } 07111 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 07112 if ((newmsgs + oldmsgs) >= capacity) { 07113 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 07114 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07115 valid_extensions = 0; 07116 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07117 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07118 free_user(vmtmp); 07119 } 07120 inprocess_count(receiver->mailbox, receiver->context, -1); 07121 break; 07122 } 07123 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 07124 } else { 07125 /* XXX Optimization for the future. When we encounter a single bad extension, 07126 * bailing out on all of the extensions may not be the way to go. We should 07127 * probably just bail on that single extension, then allow the user to enter 07128 * several more. XXX 07129 */ 07130 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07131 free_user(receiver); 07132 } 07133 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 07134 /* "I am sorry, that's not a valid extension. Please try again." */ 07135 res = ast_play_and_wait(chan, "pbx-invalid"); 07136 valid_extensions = 0; 07137 break; 07138 } 07139 07140 /* play name if available, else play extension number */ 07141 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 07142 RETRIEVE(fn, -1, s, receiver->context); 07143 if (ast_fileexists(fn, NULL, NULL) > 0) { 07144 res = ast_stream_and_wait(chan, fn, ecodes); 07145 if (res) { 07146 DISPOSE(fn, -1); 07147 return res; 07148 } 07149 } else { 07150 res = ast_say_digit_str(chan, s, ecodes, chan->language); 07151 } 07152 DISPOSE(fn, -1); 07153 07154 s = strsep(&stringp, "*"); 07155 } 07156 /* break from the loop of reading the extensions */ 07157 if (valid_extensions) 07158 break; 07159 } 07160 /* check if we're clear to proceed */ 07161 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 07162 return res; 07163 if (is_new_message == 1) { 07164 struct leave_vm_options leave_options; 07165 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 07166 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 07167 07168 /* Send VoiceMail */ 07169 memset(&leave_options, 0, sizeof(leave_options)); 07170 leave_options.record_gain = record_gain; 07171 cmd = leave_voicemail(chan, mailbox, &leave_options); 07172 } else { 07173 /* Forward VoiceMail */ 07174 long duration = 0; 07175 struct vm_state vmstmp; 07176 int copy_msg_result = 0; 07177 memcpy(&vmstmp, vms, sizeof(vmstmp)); 07178 07179 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 07180 07181 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 07182 if (!cmd) { 07183 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 07184 #ifdef IMAP_STORAGE 07185 int attach_user_voicemail; 07186 char *myserveremail = serveremail; 07187 07188 /* get destination mailbox */ 07189 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 07190 if (!dstvms) { 07191 dstvms = create_vm_state_from_user(vmtmp); 07192 } 07193 if (dstvms) { 07194 init_mailstream(dstvms, 0); 07195 if (!dstvms->mailstream) { 07196 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 07197 } else { 07198 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 07199 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 07200 } 07201 } else { 07202 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 07203 } 07204 if (!ast_strlen_zero(vmtmp->serveremail)) 07205 myserveremail = vmtmp->serveremail; 07206 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 07207 /* NULL category for IMAP storage */ 07208 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 07209 dstvms->curbox, 07210 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 07211 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 07212 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 07213 NULL, urgent_str); 07214 #else 07215 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 07216 #endif 07217 saved_messages++; 07218 AST_LIST_REMOVE_CURRENT(list); 07219 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07220 free_user(vmtmp); 07221 if (res) 07222 break; 07223 } 07224 AST_LIST_TRAVERSE_SAFE_END; 07225 if (saved_messages > 0 && !copy_msg_result) { 07226 /* give confirmation that the message was saved */ 07227 /* commented out since we can't forward batches yet 07228 if (saved_messages == 1) 07229 res = ast_play_and_wait(chan, "vm-message"); 07230 else 07231 res = ast_play_and_wait(chan, "vm-messages"); 07232 if (!res) 07233 res = ast_play_and_wait(chan, "vm-saved"); */ 07234 #ifdef IMAP_STORAGE 07235 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 07236 if (ast_strlen_zero(vmstmp.introfn)) 07237 #endif 07238 res = ast_play_and_wait(chan, "vm-msgsaved"); 07239 } 07240 #ifndef IMAP_STORAGE 07241 else { 07242 /* with IMAP, mailbox full warning played by imap_check_limits */ 07243 res = ast_play_and_wait(chan, "vm-mailboxfull"); 07244 } 07245 /* Restore original message without prepended message if backup exists */ 07246 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07247 strcpy(textfile, msgfile); 07248 strcpy(backup, msgfile); 07249 strcpy(backup_textfile, msgfile); 07250 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07251 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 07252 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07253 if (ast_fileexists(backup, NULL, NULL) > 0) { 07254 ast_filerename(backup, msgfile, NULL); 07255 rename(backup_textfile, textfile); 07256 } 07257 #endif 07258 } 07259 DISPOSE(dir, curmsg); 07260 #ifndef IMAP_STORAGE 07261 if (cmd) { /* assuming hangup, cleanup backup file */ 07262 make_file(msgfile, sizeof(msgfile), dir, curmsg); 07263 strcpy(textfile, msgfile); 07264 strcpy(backup_textfile, msgfile); 07265 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 07266 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 07267 rename(backup_textfile, textfile); 07268 } 07269 #endif 07270 } 07271 07272 /* If anything failed above, we still have this list to free */ 07273 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 07274 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 07275 free_user(vmtmp); 07276 } 07277 return res ? res : cmd; 07278 }
static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1664 of file app_voicemail_imapstorage.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01665 { 01666 if (ast_test_flag(vmu, VM_ALLOCED)) { 01667 if (vmu->emailbody != NULL) { 01668 ast_free(vmu->emailbody); 01669 vmu->emailbody = NULL; 01670 } 01671 if (vmu->emailsubject != NULL) { 01672 ast_free(vmu->emailsubject); 01673 vmu->emailsubject = NULL; 01674 } 01675 ast_free(vmu); 01676 } 01677 }
static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 11447 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.
11448 { 11449 struct ast_vm_user *current; 11450 AST_LIST_LOCK(&users); 11451 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 11452 ast_set_flag(current, VM_ALLOCED); 11453 free_user(current); 11454 } 11455 AST_LIST_UNLOCK(&users); 11456 }
static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 11459 of file app_voicemail_imapstorage.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and vm_zone::list.
11460 { 11461 struct vm_zone *zcur; 11462 AST_LIST_LOCK(&zones); 11463 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 11464 free_zone(zcur); 11465 AST_LIST_UNLOCK(&zones); 11466 }
static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4949 of file app_voicemail_imapstorage.c.
References ast_free.
04950 { 04951 ast_free(z); 04952 }
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 4905 of file app_voicemail_imapstorage.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
04906 { 04907 struct ast_tm tm; 04908 struct timeval t = ast_tvnow(); 04909 04910 ast_localtime(&t, &tm, "UTC"); 04911 04912 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04913 }
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 6618 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().
06619 { 06620 int x; 06621 int d; 06622 char fn[PATH_MAX]; 06623 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06624 if (d) 06625 return d; 06626 for (x = start; x < 5; x++) { /* For all folders */ 06627 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06628 return d; 06629 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06630 if (d) 06631 return d; 06632 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 06633 d = vm_play_folder_name(chan, fn); 06634 if (d) 06635 return d; 06636 d = ast_waitfordigit(chan, 500); 06637 if (d) 06638 return d; 06639 } 06640 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06641 if (d) 06642 return d; 06643 d = ast_waitfordigit(chan, 4000); 06644 return d; 06645 }
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 6659 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), and get_folder().
06660 { 06661 int res = 0; 06662 int loops = 0; 06663 res = ast_play_and_wait(chan, fn); /* Folder name */ 06664 while (((res < '0') || (res > '9')) && 06665 (res != '#') && (res >= 0) && 06666 loops < 4) { 06667 res = get_folder(chan, 0); 06668 loops++; 06669 } 06670 if (loops == 4) { /* give up */ 06671 return '#'; 06672 } 06673 return res; 06674 }
static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1651 of file app_voicemail_imapstorage.c.
References ARRAY_LEN.
01652 { 01653 size_t i; 01654 01655 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01656 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01657 return i; 01658 } 01659 } 01660 01661 return -1; 01662 }
static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 11230 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.
11231 { 11232 unsigned int len; 11233 struct mwi_sub *mwi_sub; 11234 struct mwi_sub_task *p = datap; 11235 11236 len = sizeof(*mwi_sub); 11237 if (!ast_strlen_zero(p->mailbox)) 11238 len += strlen(p->mailbox); 11239 11240 if (!ast_strlen_zero(p->context)) 11241 len += strlen(p->context) + 1; /* Allow for seperator */ 11242 11243 if (!(mwi_sub = ast_calloc(1, len))) 11244 return -1; 11245 11246 mwi_sub->uniqueid = p->uniqueid; 11247 if (!ast_strlen_zero(p->mailbox)) 11248 strcpy(mwi_sub->mailbox, p->mailbox); 11249 11250 if (!ast_strlen_zero(p->context)) { 11251 strcat(mwi_sub->mailbox, "@"); 11252 strcat(mwi_sub->mailbox, p->context); 11253 } 11254 11255 AST_RWLIST_WRLOCK(&mwi_subs); 11256 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 11257 AST_RWLIST_UNLOCK(&mwi_subs); 11258 ast_free((void *) p->mailbox); 11259 ast_free((void *) p->context); 11260 ast_free(p); 11261 poll_subscribed_mailbox(mwi_sub); 11262 return 0; 11263 }
static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 11208 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.
11209 { 11210 struct mwi_sub *mwi_sub; 11211 uint32_t *uniqueid = datap; 11212 11213 AST_RWLIST_WRLOCK(&mwi_subs); 11214 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 11215 if (mwi_sub->uniqueid == *uniqueid) { 11216 AST_LIST_REMOVE_CURRENT(entry); 11217 break; 11218 } 11219 } 11220 AST_RWLIST_TRAVERSE_SAFE_END 11221 AST_RWLIST_UNLOCK(&mwi_subs); 11222 11223 if (mwi_sub) 11224 mwi_sub_destroy(mwi_sub); 11225 11226 ast_free(uniqueid); 11227 return 0; 11228 }
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 10983 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.
10984 { 10985 switch (cmd) { 10986 case CLI_INIT: 10987 e->command = "voicemail reload"; 10988 e->usage = 10989 "Usage: voicemail reload\n" 10990 " Reload voicemail configuration\n"; 10991 return NULL; 10992 case CLI_GENERATE: 10993 return NULL; 10994 } 10995 10996 if (a->argc != 2) 10997 return CLI_SHOWUSAGE; 10998 10999 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 11000 load_config(1); 11001 11002 return CLI_SUCCESS; 11003 }
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 10873 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.
10874 { 10875 struct ast_vm_user *vmu; 10876 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 10877 const char *context = NULL; 10878 int users_counter = 0; 10879 10880 switch (cmd) { 10881 case CLI_INIT: 10882 e->command = "voicemail show users"; 10883 e->usage = 10884 "Usage: voicemail show users [for <context>]\n" 10885 " Lists all mailboxes currently set up\n"; 10886 return NULL; 10887 case CLI_GENERATE: 10888 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 10889 } 10890 10891 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 10892 return CLI_SHOWUSAGE; 10893 if (a->argc == 5) { 10894 if (strcmp(a->argv[3],"for")) 10895 return CLI_SHOWUSAGE; 10896 context = a->argv[4]; 10897 } 10898 10899 if (ast_check_realtime("voicemail")) { 10900 if (!context) { 10901 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 10902 return CLI_SHOWUSAGE; 10903 } 10904 return show_users_realtime(a->fd, context); 10905 } 10906 10907 AST_LIST_LOCK(&users); 10908 if (AST_LIST_EMPTY(&users)) { 10909 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 10910 AST_LIST_UNLOCK(&users); 10911 return CLI_FAILURE; 10912 } 10913 if (a->argc == 3) 10914 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10915 else { 10916 int count = 0; 10917 AST_LIST_TRAVERSE(&users, vmu, list) { 10918 if (!strcmp(context, vmu->context)) 10919 count++; 10920 } 10921 if (count) { 10922 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10923 } else { 10924 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 10925 AST_LIST_UNLOCK(&users); 10926 return CLI_FAILURE; 10927 } 10928 } 10929 AST_LIST_TRAVERSE(&users, vmu, list) { 10930 int newmsgs = 0, oldmsgs = 0; 10931 char count[12], tmp[256] = ""; 10932 10933 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 10934 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 10935 inboxcount(tmp, &newmsgs, &oldmsgs); 10936 snprintf(count, sizeof(count), "%d", newmsgs); 10937 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 10938 users_counter++; 10939 } 10940 } 10941 AST_LIST_UNLOCK(&users); 10942 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 10943 return CLI_SUCCESS; 10944 }
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 10947 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.
10948 { 10949 struct vm_zone *zone; 10950 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 10951 char *res = CLI_SUCCESS; 10952 10953 switch (cmd) { 10954 case CLI_INIT: 10955 e->command = "voicemail show zones"; 10956 e->usage = 10957 "Usage: voicemail show zones\n" 10958 " Lists zone message formats\n"; 10959 return NULL; 10960 case CLI_GENERATE: 10961 return NULL; 10962 } 10963 10964 if (a->argc != 3) 10965 return CLI_SHOWUSAGE; 10966 10967 AST_LIST_LOCK(&zones); 10968 if (!AST_LIST_EMPTY(&zones)) { 10969 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 10970 AST_LIST_TRAVERSE(&zones, zone, list) { 10971 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 10972 } 10973 } else { 10974 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 10975 res = CLI_FAILURE; 10976 } 10977 AST_LIST_UNLOCK(&zones); 10978 10979 return res; 10980 }
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 5291 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
05292 { 05293 char tmp[256], *tmp2 = tmp, *box, *context; 05294 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05295 if (ast_strlen_zero(folder)) { 05296 folder = "INBOX"; 05297 } 05298 while ((box = strsep(&tmp2, ",&"))) { 05299 if ((context = strchr(box, '@'))) 05300 *context++ = '\0'; 05301 else 05302 context = "default"; 05303 if (__has_voicemail(context, box, folder, 1)) 05304 return 1; 05305 /* If we are checking INBOX, we should check Urgent as well */ 05306 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05307 return 1; 05308 } 05309 } 05310 return 0; 05311 }
static int inboxcount | ( | const char * | mailbox, | |
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5373 of file app_voicemail_imapstorage.c.
References inboxcount2().
05374 { 05375 int urgentmsgs = 0; 05376 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05377 if (newmsgs) { 05378 *newmsgs += urgentmsgs; 05379 } 05380 return res; 05381 }
static int inboxcount2 | ( | const char * | mailbox, | |
int * | urgentmsgs, | |||
int * | newmsgs, | |||
int * | oldmsgs | |||
) | [static] |
Definition at line 5314 of file app_voicemail_imapstorage.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), inboxcount2(), and strsep().
05315 { 05316 char tmp[256]; 05317 char *context; 05318 05319 /* If no mailbox, return immediately */ 05320 if (ast_strlen_zero(mailbox)) 05321 return 0; 05322 05323 if (newmsgs) 05324 *newmsgs = 0; 05325 if (oldmsgs) 05326 *oldmsgs = 0; 05327 if (urgentmsgs) 05328 *urgentmsgs = 0; 05329 05330 if (strchr(mailbox, ',')) { 05331 int tmpnew, tmpold, tmpurgent; 05332 char *mb, *cur; 05333 05334 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05335 mb = tmp; 05336 while ((cur = strsep(&mb, ", "))) { 05337 if (!ast_strlen_zero(cur)) { 05338 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05339 return -1; 05340 else { 05341 if (newmsgs) 05342 *newmsgs += tmpnew; 05343 if (oldmsgs) 05344 *oldmsgs += tmpold; 05345 if (urgentmsgs) 05346 *urgentmsgs += tmpurgent; 05347 } 05348 } 05349 } 05350 return 0; 05351 } 05352 05353 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05354 05355 if ((context = strchr(tmp, '@'))) 05356 *context++ = '\0'; 05357 else 05358 context = "default"; 05359 05360 if (newmsgs) 05361 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05362 if (oldmsgs) 05363 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05364 if (urgentmsgs) 05365 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05366 05367 return 0; 05368 }
static int inbuf | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4077 of file app_voicemail_imapstorage.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
04078 { 04079 int l; 04080 04081 if (bio->ateof) 04082 return 0; 04083 04084 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04085 if (ferror(fi)) 04086 return -1; 04087 04088 bio->ateof = 1; 04089 return 0; 04090 } 04091 04092 bio->iolen = l; 04093 bio->iocp = 0; 04094 04095 return 1; 04096 }
static int inchar | ( | struct baseio * | bio, | |
FILE * | fi | |||
) | [static] |
utility used by base_encode()
Definition at line 4101 of file app_voicemail_imapstorage.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
04102 { 04103 if (bio->iocp>=bio->iolen) { 04104 if (!inbuf(bio, fi)) 04105 return EOF; 04106 } 04107 04108 return bio->iobuf[bio->iocp++]; 04109 }
static int inprocess_cmp_fn | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 891 of file app_voicemail_imapstorage.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
00892 { 00893 struct inprocess *i = obj, *j = arg; 00894 if (strcmp(i->mailbox, j->mailbox)) { 00895 return 0; 00896 } 00897 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 00898 }
static int inprocess_count | ( | const char * | context, | |
const char * | mailbox, | |||
int | delta | |||
) | [static] |
Definition at line 900 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.
00901 { 00902 struct inprocess *i, *arg = alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 00903 arg->context = arg->mailbox + strlen(mailbox) + 1; 00904 strcpy(arg->mailbox, mailbox); /* SAFE */ 00905 strcpy(arg->context, context); /* SAFE */ 00906 ao2_lock(inprocess_container); 00907 if ((i = ao2_find(inprocess_container, arg, 0))) { 00908 int ret = ast_atomic_fetchadd_int(&i->count, delta); 00909 ao2_unlock(inprocess_container); 00910 ao2_ref(i, -1); 00911 return ret; 00912 } 00913 if (delta < 0) { 00914 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 00915 } 00916 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 00917 ao2_unlock(inprocess_container); 00918 return 0; 00919 } 00920 i->context = i->mailbox + strlen(mailbox) + 1; 00921 strcpy(i->mailbox, mailbox); /* SAFE */ 00922 strcpy(i->context, context); /* SAFE */ 00923 i->count = delta; 00924 ao2_link(inprocess_container, i); 00925 ao2_unlock(inprocess_container); 00926 ao2_ref(i, -1); 00927 return 0; 00928 }
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 4915 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, and RETRIEVE.
04916 { 04917 int res; 04918 char fn[PATH_MAX]; 04919 char dest[PATH_MAX]; 04920 04921 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04922 04923 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04924 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04925 return -1; 04926 } 04927 04928 RETRIEVE(fn, -1, ext, context); 04929 if (ast_fileexists(fn, NULL, NULL) > 0) { 04930 res = ast_stream_and_wait(chan, fn, ecodes); 04931 if (res) { 04932 DISPOSE(fn, -1); 04933 return res; 04934 } 04935 } else { 04936 /* Dispose just in case */ 04937 DISPOSE(fn, -1); 04938 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04939 if (res) 04940 return res; 04941 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04942 if (res) 04943 return res; 04944 } 04945 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04946 return res; 04947 }
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 1308 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
01309 { 01310 int i; 01311 char *local_key = ast_strdupa(key); 01312 01313 for (i = 0; i < strlen(key); ++i) { 01314 if (!strchr(VALID_DTMF, *local_key)) { 01315 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01316 return 0; 01317 } 01318 local_key++; 01319 } 01320 return 1; 01321 }
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 3895 of file app_voicemail_imapstorage.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
03896 { 03897 int x; 03898 unsigned char map[MAXMSGLIMIT] = ""; 03899 DIR *msgdir; 03900 struct dirent *msgdirent; 03901 int msgdirint; 03902 char extension[4]; 03903 int stopcount = 0; 03904 03905 /* Reading the entire directory into a file map scales better than 03906 * doing a stat repeatedly on a predicted sequence. I suspect this 03907 * is partially due to stat(2) internally doing a readdir(2) itself to 03908 * find each file. */ 03909 if (!(msgdir = opendir(dir))) { 03910 return -1; 03911 } 03912 03913 while ((msgdirent = readdir(msgdir))) { 03914 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 03915 map[msgdirint] = 1; 03916 stopcount++; 03917 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 03918 } 03919 } 03920 closedir(msgdir); 03921 03922 for (x = 0; x < vmu->maxmsg; x++) { 03923 if (map[x] == 1) { 03924 stopcount--; 03925 } else if (map[x] == 0 && !stopcount) { 03926 break; 03927 } 03928 } 03929 03930 return x - 1; 03931 }
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 5446 of file app_voicemail_imapstorage.c.
References ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_exists_extension(), ast_fileexists(), ast_free, ast_log(), ast_str_buffer(), ast_str_create(), ast_str_set(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_channel::caller, ast_channel::context, ast_vm_user::context, create_dirpath(), DISPOSE, errno, ast_vm_user::exit, find_user(), ast_party_caller::id, LOG_WARNING, ast_channel::macrocontext, ast_vm_user::mailbox, ast_party_id::number, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), RETRIEVE, S_COR, ast_party_number::str, ast_party_number::valid, VM_OPERATOR, and VOICEMAIL_DIR_MODE.
05447 { 05448 #ifdef IMAP_STORAGE 05449 int newmsgs, oldmsgs; 05450 #else 05451 char urgdir[PATH_MAX]; 05452 #endif 05453 char txtfile[PATH_MAX]; 05454 char tmptxtfile[PATH_MAX]; 05455 struct vm_state *vms = NULL; 05456 char callerid[256]; 05457 FILE *txt; 05458 char date[256]; 05459 int txtdes; 05460 int res = 0; 05461 int msgnum; 05462 int duration = 0; 05463 int ausemacro = 0; 05464 int ousemacro = 0; 05465 int ouseexten = 0; 05466 char tmpdur[16]; 05467 char priority[16]; 05468 char origtime[16]; 05469 char dir[PATH_MAX]; 05470 char tmpdir[PATH_MAX]; 05471 char fn[PATH_MAX]; 05472 char prefile[PATH_MAX] = ""; 05473 char tempfile[PATH_MAX] = ""; 05474 char ext_context[256] = ""; 05475 char fmt[80]; 05476 char *context; 05477 char ecodes[17] = "#"; 05478 struct ast_str *tmp = ast_str_create(16); 05479 char *tmpptr; 05480 struct ast_vm_user *vmu; 05481 struct ast_vm_user svm; 05482 const char *category = NULL; 05483 const char *code; 05484 const char *alldtmf = "0123456789ABCD*#"; 05485 char flag[80]; 05486 05487 if (!tmp) { 05488 return -1; 05489 } 05490 05491 ast_str_set(&tmp, 0, "%s", ext); 05492 ext = ast_str_buffer(tmp); 05493 if ((context = strchr(ext, '@'))) { 05494 *context++ = '\0'; 05495 tmpptr = strchr(context, '&'); 05496 } else { 05497 tmpptr = strchr(ext, '&'); 05498 } 05499 05500 if (tmpptr) 05501 *tmpptr++ = '\0'; 05502 05503 ast_channel_lock(chan); 05504 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05505 category = ast_strdupa(category); 05506 } 05507 ast_channel_unlock(chan); 05508 05509 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05510 ast_copy_string(flag, "Urgent", sizeof(flag)); 05511 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05512 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05513 } else { 05514 flag[0] = '\0'; 05515 } 05516 05517 ast_debug(3, "Before find_user\n"); 05518 if (!(vmu = find_user(&svm, context, ext))) { 05519 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05520 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05521 ast_free(tmp); 05522 return res; 05523 } 05524 /* Setup pre-file if appropriate */ 05525 if (strcmp(vmu->context, "default")) 05526 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05527 else 05528 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05529 05530 /* Set the path to the prefile. Will be one of 05531 VM_SPOOL_DIRcontext/ext/busy 05532 VM_SPOOL_DIRcontext/ext/unavail 05533 Depending on the flag set in options. 05534 */ 05535 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05536 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05537 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05538 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05539 } 05540 /* Set the path to the tmpfile as 05541 VM_SPOOL_DIR/context/ext/temp 05542 and attempt to create the folder structure. 05543 */ 05544 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05545 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05546 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05547 ast_free(tmp); 05548 return -1; 05549 } 05550 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05551 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05552 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05553 05554 DISPOSE(tempfile, -1); 05555 /* It's easier just to try to make it than to check for its existence */ 05556 #ifndef IMAP_STORAGE 05557 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05558 #else 05559 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 05560 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 05561 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 05562 } 05563 #endif 05564 05565 /* Check current or macro-calling context for special extensions */ 05566 if (ast_test_flag(vmu, VM_OPERATOR)) { 05567 if (!ast_strlen_zero(vmu->exit)) { 05568 if (ast_exists_extension(chan, vmu->exit, "o", 1, 05569 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05570 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05571 ouseexten = 1; 05572 } 05573 } else if (ast_exists_extension(chan, chan->context, "o", 1, 05574 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05575 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05576 ouseexten = 1; 05577 } else if (!ast_strlen_zero(chan->macrocontext) 05578 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 05579 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05580 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05581 ousemacro = 1; 05582 } 05583 } 05584 05585 if (!ast_strlen_zero(vmu->exit)) { 05586 if (ast_exists_extension(chan, vmu->exit, "a", 1, 05587 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05588 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05589 } 05590 } else if (ast_exists_extension(chan, chan->context, "a", 1, 05591 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05592 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05593 } else if (!ast_strlen_zero(chan->macrocontext) 05594 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 05595 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05596 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05597 ausemacro = 1; 05598 } 05599 05600 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05601 for (code = alldtmf; *code; code++) { 05602 char e[2] = ""; 05603 e[0] = *code; 05604 if (strchr(ecodes, e[0]) == NULL 05605 && ast_canmatch_extension(chan, chan->context, e, 1, 05606 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 05607 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05608 } 05609 } 05610 } 05611 05612 /* Play the beginning intro if desired */ 05613 if (!ast_strlen_zero(prefile)) { 05614 #ifdef ODBC_STORAGE 05615 int success = 05616 #endif 05617 RETRIEVE(prefile, -1, ext, context); 05618 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05619 if (ast_streamfile(chan, prefile, chan->language) > -1) 05620 res = ast_waitstream(chan, ecodes); 05621 #ifdef ODBC_STORAGE 05622 if (success == -1) { 05623 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05624 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05625 store_file(prefile, vmu->mailbox, vmu->context, -1); 05626 } 05627 #endif 05628 } else { 05629 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05630 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05631 } 05632 DISPOSE(prefile, -1); 05633 if (res < 0) { 05634 ast_debug(1, "Hang up during prefile playback\n"); 05635 free_user(vmu); 05636 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05637 ast_free(tmp); 05638 return -1; 05639 } 05640 } 05641 if (res == '#') { 05642 /* On a '#' we skip the instructions */ 05643 ast_set_flag(options, OPT_SILENT); 05644 res = 0; 05645 } 05646 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 05647 if (vmu->maxmsg == 0) { 05648 if (option_debug > 2) 05649 ast_log(LOG_DEBUG, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 05650 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05651 goto leave_vm_out; 05652 } 05653 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05654 res = ast_stream_and_wait(chan, INTRO, ecodes); 05655 if (res == '#') { 05656 ast_set_flag(options, OPT_SILENT); 05657 res = 0; 05658 } 05659 } 05660 if (res > 0) 05661 ast_stopstream(chan); 05662 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05663 other than the operator -- an automated attendant or mailbox login for example */ 05664 if (res == '*') { 05665 chan->exten[0] = 'a'; 05666 chan->exten[1] = '\0'; 05667 if (!ast_strlen_zero(vmu->exit)) { 05668 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05669 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05670 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05671 } 05672 chan->priority = 0; 05673 free_user(vmu); 05674 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05675 ast_free(tmp); 05676 return 0; 05677 } 05678 05679 /* Check for a '0' here */ 05680 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05681 transfer: 05682 if (ouseexten || ousemacro) { 05683 chan->exten[0] = 'o'; 05684 chan->exten[1] = '\0'; 05685 if (!ast_strlen_zero(vmu->exit)) { 05686 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05687 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05688 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05689 } 05690 ast_play_and_wait(chan, "transfer"); 05691 chan->priority = 0; 05692 free_user(vmu); 05693 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05694 } 05695 ast_free(tmp); 05696 return OPERATOR_EXIT; 05697 } 05698 05699 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05700 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05701 if (!ast_strlen_zero(options->exitcontext)) 05702 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05703 free_user(vmu); 05704 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05705 ast_free(tmp); 05706 return res; 05707 } 05708 05709 if (res < 0) { 05710 free_user(vmu); 05711 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05712 ast_free(tmp); 05713 return -1; 05714 } 05715 /* The meat of recording the message... All the announcements and beeps have been played*/ 05716 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05717 if (!ast_strlen_zero(fmt)) { 05718 msgnum = 0; 05719 05720 #ifdef IMAP_STORAGE 05721 /* Is ext a mailbox? */ 05722 /* must open stream for this user to get info! */ 05723 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05724 if (res < 0) { 05725 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05726 ast_free(tmp); 05727 return -1; 05728 } 05729 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05730 /* It is possible under certain circumstances that inboxcount did not 05731 * create a vm_state when it was needed. This is a catchall which will 05732 * rarely be used. 05733 */ 05734 if (!(vms = create_vm_state_from_user(vmu))) { 05735 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05736 ast_free(tmp); 05737 return -1; 05738 } 05739 } 05740 vms->newmessages++; 05741 05742 /* here is a big difference! We add one to it later */ 05743 msgnum = newmsgs + oldmsgs; 05744 ast_debug(3, "Messagecount set to %d\n", msgnum); 05745 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05746 /* set variable for compatibility */ 05747 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05748 05749 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 05750 goto leave_vm_out; 05751 } 05752 #else 05753 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 05754 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05755 if (!res) 05756 res = ast_waitstream(chan, ""); 05757 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05758 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05759 inprocess_count(vmu->mailbox, vmu->context, -1); 05760 goto leave_vm_out; 05761 } 05762 05763 #endif 05764 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05765 txtdes = mkstemp(tmptxtfile); 05766 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05767 if (txtdes < 0) { 05768 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05769 if (!res) 05770 res = ast_waitstream(chan, ""); 05771 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05772 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05773 inprocess_count(vmu->mailbox, vmu->context, -1); 05774 goto leave_vm_out; 05775 } 05776 05777 /* Now play the beep once we have the message number for our next message. */ 05778 if (res >= 0) { 05779 /* Unless we're *really* silent, try to send the beep */ 05780 res = ast_stream_and_wait(chan, "beep", ""); 05781 } 05782 05783 /* Store information in real-time storage */ 05784 if (ast_check_realtime("voicemail_data")) { 05785 snprintf(priority, sizeof(priority), "%d", chan->priority); 05786 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05787 get_date(date, sizeof(date)); 05788 ast_callerid_merge(callerid, sizeof(callerid), 05789 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05790 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05791 "Unknown"); 05792 ast_store_realtime("voicemail_data", 05793 "origmailbox", ext, 05794 "context", chan->context, 05795 "macrocontext", chan->macrocontext, 05796 "exten", chan->exten, 05797 "priority", priority, 05798 "callerchan", chan->name, 05799 "callerid", callerid, 05800 "origdate", date, 05801 "origtime", origtime, 05802 "category", S_OR(category, ""), 05803 "filename", tmptxtfile, 05804 SENTINEL); 05805 } 05806 05807 /* Store information */ 05808 txt = fdopen(txtdes, "w+"); 05809 if (txt) { 05810 get_date(date, sizeof(date)); 05811 ast_callerid_merge(callerid, sizeof(callerid), 05812 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05813 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05814 "Unknown"); 05815 fprintf(txt, 05816 ";\n" 05817 "; Message Information file\n" 05818 ";\n" 05819 "[message]\n" 05820 "origmailbox=%s\n" 05821 "context=%s\n" 05822 "macrocontext=%s\n" 05823 "exten=%s\n" 05824 "rdnis=%s\n" 05825 "priority=%d\n" 05826 "callerchan=%s\n" 05827 "callerid=%s\n" 05828 "origdate=%s\n" 05829 "origtime=%ld\n" 05830 "category=%s\n", 05831 ext, 05832 chan->context, 05833 chan->macrocontext, 05834 chan->exten, 05835 S_COR(chan->redirecting.from.number.valid, 05836 chan->redirecting.from.number.str, "unknown"), 05837 chan->priority, 05838 chan->name, 05839 callerid, 05840 date, (long) time(NULL), 05841 category ? category : ""); 05842 } else { 05843 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05844 inprocess_count(vmu->mailbox, vmu->context, -1); 05845 if (ast_check_realtime("voicemail_data")) { 05846 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05847 } 05848 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05849 goto leave_vm_out; 05850 } 05851 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05852 05853 if (txt) { 05854 fprintf(txt, "flag=%s\n", flag); 05855 if (duration < vmu->minsecs) { 05856 fclose(txt); 05857 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmu->minsecs); 05858 ast_filedelete(tmptxtfile, NULL); 05859 unlink(tmptxtfile); 05860 if (ast_check_realtime("voicemail_data")) { 05861 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05862 } 05863 inprocess_count(vmu->mailbox, vmu->context, -1); 05864 } else { 05865 fprintf(txt, "duration=%d\n", duration); 05866 fclose(txt); 05867 if (vm_lock_path(dir)) { 05868 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05869 /* Delete files */ 05870 ast_filedelete(tmptxtfile, NULL); 05871 unlink(tmptxtfile); 05872 inprocess_count(vmu->mailbox, vmu->context, -1); 05873 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05874 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05875 unlink(tmptxtfile); 05876 ast_unlock_path(dir); 05877 inprocess_count(vmu->mailbox, vmu->context, -1); 05878 if (ast_check_realtime("voicemail_data")) { 05879 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05880 } 05881 } else { 05882 #ifndef IMAP_STORAGE 05883 msgnum = last_message_index(vmu, dir) + 1; 05884 #endif 05885 make_file(fn, sizeof(fn), dir, msgnum); 05886 05887 /* assign a variable with the name of the voicemail file */ 05888 #ifndef IMAP_STORAGE 05889 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05890 #else 05891 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05892 #endif 05893 05894 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05895 ast_filerename(tmptxtfile, fn, NULL); 05896 rename(tmptxtfile, txtfile); 05897 inprocess_count(vmu->mailbox, vmu->context, -1); 05898 05899 /* Properly set permissions on voicemail text descriptor file. 05900 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05901 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05902 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05903 05904 ast_unlock_path(dir); 05905 if (ast_check_realtime("voicemail_data")) { 05906 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05907 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 05908 } 05909 /* We must store the file first, before copying the message, because 05910 * ODBC storage does the entire copy with SQL. 05911 */ 05912 if (ast_fileexists(fn, NULL, NULL) > 0) { 05913 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05914 } 05915 05916 /* Are there to be more recipients of this message? */ 05917 while (tmpptr) { 05918 struct ast_vm_user recipu, *recip; 05919 char *exten, *cntx; 05920 05921 exten = strsep(&tmpptr, "&"); 05922 cntx = strchr(exten, '@'); 05923 if (cntx) { 05924 *cntx = '\0'; 05925 cntx++; 05926 } 05927 if ((recip = find_user(&recipu, cntx, exten))) { 05928 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05929 free_user(recip); 05930 } 05931 } 05932 #ifndef IMAP_STORAGE 05933 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05934 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05935 char sfn[PATH_MAX]; 05936 char dfn[PATH_MAX]; 05937 int x; 05938 /* It's easier just to try to make it than to check for its existence */ 05939 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05940 x = last_message_index(vmu, urgdir) + 1; 05941 make_file(sfn, sizeof(sfn), dir, msgnum); 05942 make_file(dfn, sizeof(dfn), urgdir, x); 05943 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 05944 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05945 /* Notification must happen for this new message in Urgent folder, not INBOX */ 05946 ast_copy_string(fn, dfn, sizeof(fn)); 05947 msgnum = x; 05948 } 05949 #endif 05950 /* Notification needs to happen after the copy, though. */ 05951 if (ast_fileexists(fn, NULL, NULL)) { 05952 #ifdef IMAP_STORAGE 05953 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, 05954 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05955 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05956 flag); 05957 #else 05958 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, 05959 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 05960 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 05961 flag); 05962 #endif 05963 } 05964 05965 /* Disposal needs to happen after the optional move and copy */ 05966 if (ast_fileexists(fn, NULL, NULL)) { 05967 DISPOSE(dir, msgnum); 05968 } 05969 } 05970 } 05971 } else { 05972 inprocess_count(vmu->mailbox, vmu->context, -1); 05973 } 05974 if (res == '0') { 05975 goto transfer; 05976 } else if (res > 0 && res != 't') 05977 res = 0; 05978 05979 if (duration < vmu->minsecs) 05980 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05981 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05982 else 05983 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05984 } else 05985 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 05986 leave_vm_out: 05987 free_user(vmu); 05988 05989 #ifdef IMAP_STORAGE 05990 /* expunge message - use UID Expunge if supported on IMAP server*/ 05991 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 05992 if (expungeonhangup == 1) { 05993 ast_mutex_lock(&vms->lock); 05994 #ifdef HAVE_IMAP_TK2006 05995 if (LEVELUIDPLUS (vms->mailstream)) { 05996 mail_expunge_full(vms->mailstream, NIL, EX_UID); 05997 } else 05998 #endif 05999 mail_expunge(vms->mailstream); 06000 ast_mutex_unlock(&vms->lock); 06001 } 06002 #endif 06003 06004 ast_free(tmp); 06005 return res; 06006 }
static int load_config | ( | int | reload | ) | [static] |
Definition at line 11512 of file app_voicemail_imapstorage.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_clear_flag, ast_config_destroy(), ast_config_load, 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_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, 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, 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, LOG_ERROR, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerdateformat, pagerfromstring, pagersubject, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, smdi_iface, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, 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_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, and VOICEMAIL_CONFIG.
11513 { 11514 struct ast_vm_user *current; 11515 struct ast_config *cfg, *ucfg; 11516 char *cat; 11517 struct ast_variable *var; 11518 const char *val; 11519 char *q, *stringp, *tmp; 11520 int x; 11521 int tmpadsi[4]; 11522 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 11523 char secretfn[PATH_MAX] = ""; 11524 11525 ast_unload_realtime("voicemail"); 11526 ast_unload_realtime("voicemail_data"); 11527 11528 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11529 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 11530 return 0; 11531 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 11532 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11533 ucfg = NULL; 11534 } 11535 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11536 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 11537 ast_config_destroy(ucfg); 11538 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11539 return 0; 11540 } 11541 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 11542 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 11543 return 0; 11544 } else { 11545 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 11546 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 11547 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 11548 ucfg = NULL; 11549 } 11550 } 11551 #ifdef IMAP_STORAGE 11552 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 11553 #endif 11554 /* set audio control prompts */ 11555 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 11556 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 11557 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 11558 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 11559 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 11560 11561 /* Free all the users structure */ 11562 free_vm_users(); 11563 11564 /* Free all the zones structure */ 11565 free_vm_zones(); 11566 11567 AST_LIST_LOCK(&users); 11568 11569 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 11570 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 11571 11572 if (cfg) { 11573 /* General settings */ 11574 11575 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 11576 val = "default"; 11577 ast_copy_string(userscontext, val, sizeof(userscontext)); 11578 /* Attach voice message to mail message ? */ 11579 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 11580 val = "yes"; 11581 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 11582 11583 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 11584 val = "no"; 11585 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 11586 11587 volgain = 0.0; 11588 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 11589 sscanf(val, "%30lf", &volgain); 11590 11591 #ifdef ODBC_STORAGE 11592 strcpy(odbc_database, "asterisk"); 11593 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 11594 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 11595 } 11596 strcpy(odbc_table, "voicemessages"); 11597 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 11598 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 11599 } 11600 #endif 11601 /* Mail command */ 11602 strcpy(mailcmd, SENDMAIL); 11603 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 11604 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 11605 11606 maxsilence = 0; 11607 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 11608 maxsilence = atoi(val); 11609 if (maxsilence > 0) 11610 maxsilence *= 1000; 11611 } 11612 11613 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 11614 maxmsg = MAXMSG; 11615 } else { 11616 maxmsg = atoi(val); 11617 if (maxmsg < 0) { 11618 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 11619 maxmsg = MAXMSG; 11620 } else if (maxmsg > MAXMSGLIMIT) { 11621 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11622 maxmsg = MAXMSGLIMIT; 11623 } 11624 } 11625 11626 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 11627 maxdeletedmsg = 0; 11628 } else { 11629 if (sscanf(val, "%30d", &x) == 1) 11630 maxdeletedmsg = x; 11631 else if (ast_true(val)) 11632 maxdeletedmsg = MAXMSG; 11633 else 11634 maxdeletedmsg = 0; 11635 11636 if (maxdeletedmsg < 0) { 11637 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 11638 maxdeletedmsg = MAXMSG; 11639 } else if (maxdeletedmsg > MAXMSGLIMIT) { 11640 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 11641 maxdeletedmsg = MAXMSGLIMIT; 11642 } 11643 } 11644 11645 /* Load date format config for voicemail mail */ 11646 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 11647 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 11648 } 11649 11650 /* Load date format config for voicemail pager mail */ 11651 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 11652 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 11653 } 11654 11655 /* External password changing command */ 11656 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 11657 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11658 pwdchange = PWDCHANGE_EXTERNAL; 11659 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 11660 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 11661 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 11662 } 11663 11664 /* External password validation command */ 11665 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 11666 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 11667 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 11668 } 11669 11670 #ifdef IMAP_STORAGE 11671 /* IMAP server address */ 11672 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 11673 ast_copy_string(imapserver, val, sizeof(imapserver)); 11674 } else { 11675 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 11676 } 11677 /* IMAP server port */ 11678 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 11679 ast_copy_string(imapport, val, sizeof(imapport)); 11680 } else { 11681 ast_copy_string(imapport, "143", sizeof(imapport)); 11682 } 11683 /* IMAP server flags */ 11684 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 11685 ast_copy_string(imapflags, val, sizeof(imapflags)); 11686 } 11687 /* IMAP server master username */ 11688 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 11689 ast_copy_string(authuser, val, sizeof(authuser)); 11690 } 11691 /* IMAP server master password */ 11692 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 11693 ast_copy_string(authpassword, val, sizeof(authpassword)); 11694 } 11695 /* Expunge on exit */ 11696 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 11697 if (ast_false(val)) 11698 expungeonhangup = 0; 11699 else 11700 expungeonhangup = 1; 11701 } else { 11702 expungeonhangup = 1; 11703 } 11704 /* IMAP voicemail folder */ 11705 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 11706 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 11707 } else { 11708 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 11709 } 11710 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 11711 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 11712 } 11713 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 11714 imapgreetings = ast_true(val); 11715 } else { 11716 imapgreetings = 0; 11717 } 11718 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 11719 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11720 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 11721 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 11722 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 11723 } else { 11724 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 11725 } 11726 11727 /* There is some very unorthodox casting done here. This is due 11728 * to the way c-client handles the argument passed in. It expects a 11729 * void pointer and casts the pointer directly to a long without 11730 * first dereferencing it. */ 11731 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 11732 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 11733 } else { 11734 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 11735 } 11736 11737 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 11738 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 11739 } else { 11740 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 11741 } 11742 11743 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 11744 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 11745 } else { 11746 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 11747 } 11748 11749 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 11750 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 11751 } else { 11752 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 11753 } 11754 11755 /* Increment configuration version */ 11756 imapversion++; 11757 #endif 11758 /* External voicemail notify application */ 11759 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 11760 ast_copy_string(externnotify, val, sizeof(externnotify)); 11761 ast_debug(1, "found externnotify: %s\n", externnotify); 11762 } else { 11763 externnotify[0] = '\0'; 11764 } 11765 11766 /* SMDI voicemail notification */ 11767 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 11768 ast_debug(1, "Enabled SMDI voicemail notification\n"); 11769 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 11770 smdi_iface = ast_smdi_interface_find(val); 11771 } else { 11772 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 11773 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 11774 } 11775 if (!smdi_iface) { 11776 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 11777 } 11778 } 11779 11780 /* Silence treshold */ 11781 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 11782 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 11783 silencethreshold = atoi(val); 11784 11785 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 11786 val = ASTERISK_USERNAME; 11787 ast_copy_string(serveremail, val, sizeof(serveremail)); 11788 11789 vmmaxsecs = 0; 11790 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 11791 if (sscanf(val, "%30d", &x) == 1) { 11792 vmmaxsecs = x; 11793 } else { 11794 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 11795 } 11796 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 11797 static int maxmessage_deprecate = 0; 11798 if (maxmessage_deprecate == 0) { 11799 maxmessage_deprecate = 1; 11800 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 11801 } 11802 if (sscanf(val, "%30d", &x) == 1) { 11803 vmmaxsecs = x; 11804 } else { 11805 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 11806 } 11807 } 11808 11809 vmminsecs = 0; 11810 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 11811 if (sscanf(val, "%30d", &x) == 1) { 11812 vmminsecs = x; 11813 if (maxsilence / 1000 >= vmminsecs) { 11814 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 11815 } 11816 } else { 11817 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 11818 } 11819 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 11820 static int maxmessage_deprecate = 0; 11821 if (maxmessage_deprecate == 0) { 11822 maxmessage_deprecate = 1; 11823 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 11824 } 11825 if (sscanf(val, "%30d", &x) == 1) { 11826 vmminsecs = x; 11827 if (maxsilence / 1000 >= vmminsecs) { 11828 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 11829 } 11830 } else { 11831 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 11832 } 11833 } 11834 11835 val = ast_variable_retrieve(cfg, "general", "format"); 11836 if (!val) { 11837 val = "wav"; 11838 } else { 11839 tmp = ast_strdupa(val); 11840 val = ast_format_str_reduce(tmp); 11841 if (!val) { 11842 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 11843 val = "wav"; 11844 } 11845 } 11846 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 11847 11848 skipms = 3000; 11849 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 11850 if (sscanf(val, "%30d", &x) == 1) { 11851 maxgreet = x; 11852 } else { 11853 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 11854 } 11855 } 11856 11857 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 11858 if (sscanf(val, "%30d", &x) == 1) { 11859 skipms = x; 11860 } else { 11861 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 11862 } 11863 } 11864 11865 maxlogins = 3; 11866 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 11867 if (sscanf(val, "%30d", &x) == 1) { 11868 maxlogins = x; 11869 } else { 11870 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 11871 } 11872 } 11873 11874 minpassword = MINPASSWORD; 11875 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 11876 if (sscanf(val, "%30d", &x) == 1) { 11877 minpassword = x; 11878 } else { 11879 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 11880 } 11881 } 11882 11883 /* Force new user to record name ? */ 11884 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 11885 val = "no"; 11886 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 11887 11888 /* Force new user to record greetings ? */ 11889 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 11890 val = "no"; 11891 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 11892 11893 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 11894 ast_debug(1, "VM_CID Internal context string: %s\n", val); 11895 stringp = ast_strdupa(val); 11896 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 11897 if (!ast_strlen_zero(stringp)) { 11898 q = strsep(&stringp, ","); 11899 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 11900 q++; 11901 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 11902 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 11903 } else { 11904 cidinternalcontexts[x][0] = '\0'; 11905 } 11906 } 11907 } 11908 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 11909 ast_debug(1, "VM Review Option disabled globally\n"); 11910 val = "no"; 11911 } 11912 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 11913 11914 /* Temporary greeting reminder */ 11915 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 11916 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 11917 val = "no"; 11918 } else { 11919 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 11920 } 11921 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 11922 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 11923 ast_debug(1, "VM next message wrap disabled globally\n"); 11924 val = "no"; 11925 } 11926 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 11927 11928 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 11929 ast_debug(1, "VM Operator break disabled globally\n"); 11930 val = "no"; 11931 } 11932 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 11933 11934 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 11935 ast_debug(1, "VM CID Info before msg disabled globally\n"); 11936 val = "no"; 11937 } 11938 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 11939 11940 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 11941 ast_debug(1, "Send Voicemail msg disabled globally\n"); 11942 val = "no"; 11943 } 11944 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 11945 11946 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 11947 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 11948 val = "yes"; 11949 } 11950 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 11951 11952 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 11953 ast_debug(1, "Move Heard enabled globally\n"); 11954 val = "yes"; 11955 } 11956 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 11957 11958 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 11959 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 11960 val = "no"; 11961 } 11962 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 11963 11964 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 11965 ast_debug(1, "Duration info before msg enabled globally\n"); 11966 val = "yes"; 11967 } 11968 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 11969 11970 saydurationminfo = 2; 11971 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 11972 if (sscanf(val, "%30d", &x) == 1) { 11973 saydurationminfo = x; 11974 } else { 11975 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 11976 } 11977 } 11978 11979 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 11980 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 11981 val = "no"; 11982 } 11983 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 11984 11985 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 11986 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 11987 ast_debug(1, "found dialout context: %s\n", dialcontext); 11988 } else { 11989 dialcontext[0] = '\0'; 11990 } 11991 11992 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 11993 ast_copy_string(callcontext, val, sizeof(callcontext)); 11994 ast_debug(1, "found callback context: %s\n", callcontext); 11995 } else { 11996 callcontext[0] = '\0'; 11997 } 11998 11999 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 12000 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 12001 ast_debug(1, "found operator context: %s\n", exitcontext); 12002 } else { 12003 exitcontext[0] = '\0'; 12004 } 12005 12006 /* load password sounds configuration */ 12007 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 12008 ast_copy_string(vm_password, val, sizeof(vm_password)); 12009 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 12010 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 12011 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 12012 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 12013 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 12014 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 12015 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 12016 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 12017 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 12018 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 12019 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 12020 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 12021 } 12022 /* load configurable audio prompts */ 12023 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 12024 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 12025 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 12026 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 12027 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 12028 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 12029 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 12030 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 12031 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 12032 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 12033 12034 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 12035 val = "no"; 12036 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 12037 12038 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 12039 val = "voicemail.conf"; 12040 } 12041 if (!(strcmp(val, "spooldir"))) { 12042 passwordlocation = OPT_PWLOC_SPOOLDIR; 12043 } else { 12044 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 12045 } 12046 12047 poll_freq = DEFAULT_POLL_FREQ; 12048 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 12049 if (sscanf(val, "%30u", &poll_freq) != 1) { 12050 poll_freq = DEFAULT_POLL_FREQ; 12051 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 12052 } 12053 } 12054 12055 poll_mailboxes = 0; 12056 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 12057 poll_mailboxes = ast_true(val); 12058 12059 if (ucfg) { 12060 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 12061 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 12062 continue; 12063 if ((current = find_or_create(userscontext, cat))) { 12064 populate_defaults(current); 12065 apply_options_full(current, ast_variable_browse(ucfg, cat)); 12066 ast_copy_string(current->context, userscontext, sizeof(current->context)); 12067 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 12068 current->passwordlocation = OPT_PWLOC_USERSCONF; 12069 } 12070 12071 switch (current->passwordlocation) { 12072 case OPT_PWLOC_SPOOLDIR: 12073 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 12074 read_password_from_file(secretfn, current->password, sizeof(current->password)); 12075 } 12076 } 12077 } 12078 ast_config_destroy(ucfg); 12079 } 12080 cat = ast_category_browse(cfg, NULL); 12081 while (cat) { 12082 if (strcasecmp(cat, "general")) { 12083 var = ast_variable_browse(cfg, cat); 12084 if (strcasecmp(cat, "zonemessages")) { 12085 /* Process mailboxes in this context */ 12086 while (var) { 12087 append_mailbox(cat, var->name, var->value); 12088 var = var->next; 12089 } 12090 } else { 12091 /* Timezones in this context */ 12092 while (var) { 12093 struct vm_zone *z; 12094 if ((z = ast_malloc(sizeof(*z)))) { 12095 char *msg_format, *tzone; 12096 msg_format = ast_strdupa(var->value); 12097 tzone = strsep(&msg_format, "|,"); 12098 if (msg_format) { 12099 ast_copy_string(z->name, var->name, sizeof(z->name)); 12100 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 12101 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 12102 AST_LIST_LOCK(&zones); 12103 AST_LIST_INSERT_HEAD(&zones, z, list); 12104 AST_LIST_UNLOCK(&zones); 12105 } else { 12106 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 12107 ast_free(z); 12108 } 12109 } else { 12110 AST_LIST_UNLOCK(&users); 12111 ast_config_destroy(cfg); 12112 return -1; 12113 } 12114 var = var->next; 12115 } 12116 } 12117 } 12118 cat = ast_category_browse(cfg, cat); 12119 } 12120 memset(fromstring, 0, sizeof(fromstring)); 12121 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 12122 strcpy(charset, "ISO-8859-1"); 12123 if (emailbody) { 12124 ast_free(emailbody); 12125 emailbody = NULL; 12126 } 12127 if (emailsubject) { 12128 ast_free(emailsubject); 12129 emailsubject = NULL; 12130 } 12131 if (pagerbody) { 12132 ast_free(pagerbody); 12133 pagerbody = NULL; 12134 } 12135 if (pagersubject) { 12136 ast_free(pagersubject); 12137 pagersubject = NULL; 12138 } 12139 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 12140 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 12141 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 12142 ast_copy_string(fromstring, val, sizeof(fromstring)); 12143 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 12144 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 12145 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 12146 ast_copy_string(charset, val, sizeof(charset)); 12147 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 12148 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12149 for (x = 0; x < 4; x++) { 12150 memcpy(&adsifdn[x], &tmpadsi[x], 1); 12151 } 12152 } 12153 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 12154 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 12155 for (x = 0; x < 4; x++) { 12156 memcpy(&adsisec[x], &tmpadsi[x], 1); 12157 } 12158 } 12159 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 12160 if (atoi(val)) { 12161 adsiver = atoi(val); 12162 } 12163 } 12164 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 12165 ast_copy_string(zonetag, val, sizeof(zonetag)); 12166 } 12167 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 12168 ast_copy_string(locale, val, sizeof(locale)); 12169 } 12170 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 12171 emailsubject = ast_strdup(val); 12172 } 12173 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 12174 emailbody = ast_strdup(substitute_escapes(val)); 12175 } 12176 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 12177 pagersubject = ast_strdup(val); 12178 } 12179 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 12180 pagerbody = ast_strdup(substitute_escapes(val)); 12181 } 12182 AST_LIST_UNLOCK(&users); 12183 ast_config_destroy(cfg); 12184 12185 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 12186 start_poll_thread(); 12187 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 12188 stop_poll_thread();; 12189 12190 return 0; 12191 } else { 12192 AST_LIST_UNLOCK(&users); 12193 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 12194 if (ucfg) 12195 ast_config_destroy(ucfg); 12196 return 0; 12197 } 12198 }
static int load_module | ( | void | ) | [static] |
Definition at line 12690 of file app_voicemail_imapstorage.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_data_register_multiple, ast_install_vm_functions(), ast_log(), ast_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, RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_data_providers, vm_exec(), vm_execmain(), vmauthenticate(), and vmsayname_exec().
12691 { 12692 int res; 12693 my_umask = umask(0); 12694 umask(my_umask); 12695 12696 if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) { 12697 return AST_MODULE_LOAD_DECLINE; 12698 } 12699 12700 /* compute the location of the voicemail spool directory */ 12701 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 12702 12703 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 12704 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 12705 } 12706 12707 if ((res = load_config(0))) 12708 return res; 12709 12710 res = ast_register_application_xml(app, vm_exec); 12711 res |= ast_register_application_xml(app2, vm_execmain); 12712 res |= ast_register_application_xml(app3, vm_box_exists); 12713 res |= ast_register_application_xml(app4, vmauthenticate); 12714 res |= ast_register_application_xml(sayname_app, vmsayname_exec); 12715 res |= ast_custom_function_register(&mailbox_exists_acf); 12716 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 12717 #ifdef TEST_FRAMEWORK 12718 res |= AST_TEST_REGISTER(test_voicemail_vmsayname); 12719 res |= AST_TEST_REGISTER(test_voicemail_msgcount); 12720 res |= AST_TEST_REGISTER(test_voicemail_vmuser); 12721 res |= AST_TEST_REGISTER(test_voicemail_notify_endl); 12722 #endif 12723 12724 if (res) 12725 return res; 12726 12727 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 12728 ast_data_register_multiple(vm_data_providers, ARRAY_LEN(vm_data_providers)); 12729 12730 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 12731 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 12732 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 12733 12734 return res; 12735 }
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 1563 of file app_voicemail_imapstorage.c.
01564 { 01565 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01566 }
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 4394 of file app_voicemail_imapstorage.c.
References add_email_attachment(), ast_channel_release(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_localtime(), ast_log(), ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::locale, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, S_OR, strip_control_and_high(), VM_PBXSKIP, and vmu_tm().
04395 { 04396 char date[256]; 04397 char host[MAXHOSTNAMELEN] = ""; 04398 char who[256]; 04399 char bound[256]; 04400 char dur[256]; 04401 struct ast_tm tm; 04402 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04403 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04404 char *greeting_attachment; 04405 char filename[256]; 04406 04407 if (!str1 || !str2) { 04408 ast_free(str1); 04409 ast_free(str2); 04410 return; 04411 } 04412 04413 if (cidnum) { 04414 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04415 } 04416 if (cidname) { 04417 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04418 } 04419 gethostname(host, sizeof(host) - 1); 04420 04421 if (strchr(srcemail, '@')) { 04422 ast_copy_string(who, srcemail, sizeof(who)); 04423 } else { 04424 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04425 } 04426 04427 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04428 if (greeting_attachment) { 04429 *greeting_attachment++ = '\0'; 04430 } 04431 04432 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04433 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04434 fprintf(p, "Date: %s" ENDL, date); 04435 04436 /* Set date format for voicemail mail */ 04437 ast_strftime_locale(date, sizeof(date), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04438 04439 if (!ast_strlen_zero(fromstring)) { 04440 struct ast_channel *ast; 04441 if ((ast = ast_dummy_channel_alloc())) { 04442 char *ptr; 04443 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04444 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04445 04446 if (check_mime(ast_str_buffer(str1))) { 04447 int first_line = 1; 04448 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04449 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04450 *ptr = '\0'; 04451 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04452 first_line = 0; 04453 /* Substring is smaller, so this will never grow */ 04454 ast_str_set(&str2, 0, "%s", ptr + 1); 04455 } 04456 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04457 } else { 04458 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04459 } 04460 ast = ast_channel_release(ast); 04461 } else { 04462 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04463 } 04464 } else { 04465 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04466 } 04467 04468 if (check_mime(vmu->fullname)) { 04469 int first_line = 1; 04470 char *ptr; 04471 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04472 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04473 *ptr = '\0'; 04474 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04475 first_line = 0; 04476 /* Substring is smaller, so this will never grow */ 04477 ast_str_set(&str2, 0, "%s", ptr + 1); 04478 } 04479 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04480 } else { 04481 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04482 } 04483 04484 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04485 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04486 struct ast_channel *ast; 04487 if ((ast = ast_dummy_channel_alloc())) { 04488 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04489 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04490 if (check_mime(ast_str_buffer(str1))) { 04491 int first_line = 1; 04492 char *ptr; 04493 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04494 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04495 *ptr = '\0'; 04496 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04497 first_line = 0; 04498 /* Substring is smaller, so this will never grow */ 04499 ast_str_set(&str2, 0, "%s", ptr + 1); 04500 } 04501 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04502 } else { 04503 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04504 } 04505 ast = ast_channel_release(ast); 04506 } else { 04507 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04508 } 04509 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04510 if (ast_strlen_zero(flag)) { 04511 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04512 } else { 04513 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04514 } 04515 } else { 04516 if (ast_strlen_zero(flag)) { 04517 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04518 } else { 04519 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04520 } 04521 } 04522 04523 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04524 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04525 if (imap) { 04526 /* additional information needed for IMAP searching */ 04527 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04528 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04529 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04530 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04531 #ifdef IMAP_STORAGE 04532 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04533 #else 04534 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04535 #endif 04536 /* flag added for Urgent */ 04537 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04538 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04539 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04540 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04541 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04542 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04543 if (!ast_strlen_zero(category)) { 04544 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04545 } else { 04546 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04547 } 04548 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04549 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04550 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04551 } 04552 if (!ast_strlen_zero(cidnum)) { 04553 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04554 } 04555 if (!ast_strlen_zero(cidname)) { 04556 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04557 } 04558 fprintf(p, "MIME-Version: 1.0" ENDL); 04559 if (attach_user_voicemail) { 04560 /* Something unique. */ 04561 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04562 (int) getpid(), (unsigned int) ast_random()); 04563 04564 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04565 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04566 fprintf(p, "--%s" ENDL, bound); 04567 } 04568 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04569 if (emailbody || vmu->emailbody) { 04570 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04571 struct ast_channel *ast; 04572 if ((ast = ast_dummy_channel_alloc())) { 04573 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04574 ast_str_substitute_variables(&str1, 0, ast, e_body); 04575 #ifdef IMAP_STORAGE 04576 { 04577 /* Convert body to native line terminators for IMAP backend */ 04578 char *line = ast_str_buffer(str1), *next; 04579 do { 04580 /* Terminate line before outputting it to the file */ 04581 if ((next = strchr(line, '\n'))) { 04582 *next++ = '\0'; 04583 } 04584 fprintf(p, "%s" ENDL, line); 04585 line = next; 04586 } while (!ast_strlen_zero(line)); 04587 } 04588 #else 04589 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04590 #endif 04591 ast = ast_channel_release(ast); 04592 } else { 04593 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04594 } 04595 } else if (msgnum > -1) { 04596 if (strcmp(vmu->mailbox, mailbox)) { 04597 /* Forwarded type */ 04598 struct ast_config *msg_cfg; 04599 const char *v; 04600 int inttime; 04601 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04602 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04603 /* Retrieve info from VM attribute file */ 04604 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04605 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04606 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04607 strcat(fromfile, ".txt"); 04608 } 04609 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04610 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04611 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04612 } 04613 04614 /* You might be tempted to do origdate, except that a) it's in the wrong 04615 * format, and b) it's missing for IMAP recordings. */ 04616 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04617 struct timeval tv = { inttime, }; 04618 struct ast_tm tm; 04619 ast_localtime(&tv, &tm, NULL); 04620 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04621 } 04622 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04623 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04624 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04625 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04626 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04627 date, origcallerid, origdate); 04628 ast_config_destroy(msg_cfg); 04629 } else { 04630 goto plain_message; 04631 } 04632 } else { 04633 plain_message: 04634 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04635 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04636 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04637 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04638 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04639 } 04640 } else { 04641 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04642 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04643 } 04644 04645 if (imap || attach_user_voicemail) { 04646 if (!ast_strlen_zero(attach2)) { 04647 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04648 ast_debug(5, "creating second attachment filename %s\n", filename); 04649 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04650 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04651 ast_debug(5, "creating attachment filename %s\n", filename); 04652 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04653 } else { 04654 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04655 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04656 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04657 } 04658 } 04659 ast_free(str1); 04660 ast_free(str2); 04661 }
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 1580 of file app_voicemail_imapstorage.c.
01581 { 01582 return snprintf(dest, len, "%s/msg%04d", dir, num); 01583 }
static int manager_list_voicemail_users | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager list voicemail users command.
Definition at line 11346 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.
11347 { 11348 struct ast_vm_user *vmu = NULL; 11349 const char *id = astman_get_header(m, "ActionID"); 11350 char actionid[128] = ""; 11351 11352 if (!ast_strlen_zero(id)) 11353 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 11354 11355 AST_LIST_LOCK(&users); 11356 11357 if (AST_LIST_EMPTY(&users)) { 11358 astman_send_ack(s, m, "There are no voicemail users currently defined."); 11359 AST_LIST_UNLOCK(&users); 11360 return RESULT_SUCCESS; 11361 } 11362 11363 astman_send_ack(s, m, "Voicemail user list will follow"); 11364 11365 AST_LIST_TRAVERSE(&users, vmu, list) { 11366 char dirname[256]; 11367 11368 #ifdef IMAP_STORAGE 11369 int new, old; 11370 inboxcount(vmu->mailbox, &new, &old); 11371 #endif 11372 11373 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 11374 astman_append(s, 11375 "%s" 11376 "Event: VoicemailUserEntry\r\n" 11377 "VMContext: %s\r\n" 11378 "VoiceMailbox: %s\r\n" 11379 "Fullname: %s\r\n" 11380 "Email: %s\r\n" 11381 "Pager: %s\r\n" 11382 "ServerEmail: %s\r\n" 11383 "MailCommand: %s\r\n" 11384 "Language: %s\r\n" 11385 "TimeZone: %s\r\n" 11386 "Callback: %s\r\n" 11387 "Dialout: %s\r\n" 11388 "UniqueID: %s\r\n" 11389 "ExitContext: %s\r\n" 11390 "SayDurationMinimum: %d\r\n" 11391 "SayEnvelope: %s\r\n" 11392 "SayCID: %s\r\n" 11393 "AttachMessage: %s\r\n" 11394 "AttachmentFormat: %s\r\n" 11395 "DeleteMessage: %s\r\n" 11396 "VolumeGain: %.2f\r\n" 11397 "CanReview: %s\r\n" 11398 "CallOperator: %s\r\n" 11399 "MaxMessageCount: %d\r\n" 11400 "MaxMessageLength: %d\r\n" 11401 "NewMessageCount: %d\r\n" 11402 #ifdef IMAP_STORAGE 11403 "OldMessageCount: %d\r\n" 11404 "IMAPUser: %s\r\n" 11405 #endif 11406 "\r\n", 11407 actionid, 11408 vmu->context, 11409 vmu->mailbox, 11410 vmu->fullname, 11411 vmu->email, 11412 vmu->pager, 11413 vmu->serveremail, 11414 vmu->mailcmd, 11415 vmu->language, 11416 vmu->zonetag, 11417 vmu->callback, 11418 vmu->dialout, 11419 vmu->uniqueid, 11420 vmu->exit, 11421 vmu->saydurationm, 11422 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 11423 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 11424 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 11425 vmu->attachfmt, 11426 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 11427 vmu->volgain, 11428 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 11429 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 11430 vmu->maxmsg, 11431 vmu->maxsecs, 11432 #ifdef IMAP_STORAGE 11433 new, old, vmu->imapuser 11434 #else 11435 count_messages(vmu, dirname) 11436 #endif 11437 ); 11438 } 11439 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 11440 11441 AST_LIST_UNLOCK(&users); 11442 11443 return RESULT_SUCCESS; 11444 }
static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 11180 of file app_voicemail_imapstorage.c.
References ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_lock, and poll_subscribed_mailboxes().
11181 { 11182 while (poll_thread_run) { 11183 struct timespec ts = { 0, }; 11184 struct timeval wait; 11185 11186 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 11187 ts.tv_sec = wait.tv_sec; 11188 ts.tv_nsec = wait.tv_usec * 1000; 11189 11190 ast_mutex_lock(&poll_lock); 11191 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 11192 ast_mutex_unlock(&poll_lock); 11193 11194 if (!poll_thread_run) 11195 break; 11196 11197 poll_subscribed_mailboxes(); 11198 } 11199 11200 return NULL; 11201 }
static const char* mbox | ( | struct ast_vm_user * | vmu, | |
int | id | |||
) | [static] |
Definition at line 1641 of file app_voicemail_imapstorage.c.
References ARRAY_LEN.
01642 { 01643 #ifdef IMAP_STORAGE 01644 if (vmu && id == 0) { 01645 return vmu->imapfolder; 01646 } 01647 #endif 01648 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01649 }
static int messagecount | ( | const char * | context, | |
const char * | mailbox, | |||
const char * | folder | |||
) | [static] |
Definition at line 5240 of file app_voicemail_imapstorage.c.
References __has_voicemail().
05241 { 05242 return __has_voicemail(context, mailbox, folder, 0) + (folder && strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0)); 05243 }
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 11281 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.
11282 { 11283 struct mwi_sub_task *mwist; 11284 11285 if (ast_event_get_type(event) != AST_EVENT_SUB) 11286 return; 11287 11288 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11289 return; 11290 11291 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 11292 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 11293 return; 11294 } 11295 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 11296 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 11297 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11298 11299 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 11300 ast_free(mwist); 11301 } 11302 }
static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 11265 of file app_voicemail_imapstorage.c.
References ast_calloc, ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_UNSUB, ast_free, ast_taskprocessor_push(), handle_unsubscribe(), mwi_subscription_tps, and mwi_sub_task::uniqueid.
11266 { 11267 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 11268 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 11269 return; 11270 11271 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 11272 return; 11273 11274 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 11275 *uniqueid = u; 11276 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 11277 ast_free(uniqueid); 11278 } 11279 }
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 6876 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, strsep(), VM_ATTACH, vm_delete(), and VM_DELETE.
06877 { 06878 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06879 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06880 const char *category; 06881 char *myserveremail = serveremail; 06882 06883 ast_channel_lock(chan); 06884 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06885 category = ast_strdupa(category); 06886 } 06887 ast_channel_unlock(chan); 06888 06889 #ifndef IMAP_STORAGE 06890 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, !ast_strlen_zero(flag) && !strcmp(flag, "Urgent") ? "Urgent" : "INBOX"); 06891 #else 06892 snprintf(todir, sizeof(todir), "%simap", VM_SPOOL_DIR); 06893 #endif 06894 make_file(fn, sizeof(fn), todir, msgnum); 06895 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06896 06897 if (!ast_strlen_zero(vmu->attachfmt)) { 06898 if (strstr(fmt, vmu->attachfmt)) 06899 fmt = vmu->attachfmt; 06900 else 06901 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); 06902 } 06903 06904 /* Attach only the first format */ 06905 fmt = ast_strdupa(fmt); 06906 stringp = fmt; 06907 strsep(&stringp, "|"); 06908 06909 if (!ast_strlen_zero(vmu->serveremail)) 06910 myserveremail = vmu->serveremail; 06911 06912 if (!ast_strlen_zero(vmu->email)) { 06913 int attach_user_voicemail = ast_test_flag(vmu, VM_ATTACH); 06914 06915 if (attach_user_voicemail) 06916 RETRIEVE(todir, msgnum, vmu->mailbox, vmu->context); 06917 06918 /* XXX possible imap issue, should category be NULL XXX */ 06919 sendmail(myserveremail, vmu, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, fn, NULL, fmt, duration, attach_user_voicemail, chan, category, flag); 06920 06921 if (attach_user_voicemail) 06922 DISPOSE(todir, msgnum); 06923 } 06924 06925 if (!ast_strlen_zero(vmu->pager)) { 06926 sendpage(myserveremail, vmu->pager, msgnum, vmu->context, vmu->mailbox, mbox(vmu, 0), cidnum, cidname, duration, vmu, category, flag); 06927 } 06928 06929 if (ast_test_flag(vmu, VM_DELETE)) 06930 DELETE(todir, msgnum, fn, vmu); 06931 06932 /* Leave voicemail for someone */ 06933 if (ast_app_has_voicemail(ext_context, NULL)) 06934 ast_app_inboxcount2(ext_context, &urgentmsgs, &newmsgs, &oldmsgs); 06935 06936 queue_mwi_event(ext_context, urgentmsgs, newmsgs, oldmsgs); 06937 06938 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); 06939 run_externnotify(vmu->context, vmu->mailbox, flag); 06940 06941 #ifdef IMAP_STORAGE 06942 vm_delete(fn); /* Delete the file, but not the IMAP message */ 06943 if (ast_test_flag(vmu, VM_DELETE)) { /* Delete the IMAP message if delete = yes */ 06944 vm_imap_delete(NULL, vms->curmsg, vmu); 06945 vms->newmessages--; /* Fix new message count */ 06946 } 06947 #endif 06948 06949 return 0; 06950 }
static int ochar | ( | struct baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
utility used by base_encode()
Definition at line 4114 of file app_voicemail_imapstorage.c.
References BASELINELEN, ENDL, and baseio::linelength.
04115 { 04116 if (bio->linelength >= BASELINELEN) { 04117 if (fputs(ENDL, so) == EOF) { 04118 return -1; 04119 } 04120 04121 bio->linelength = 0; 04122 } 04123 04124 if (putc(((unsigned char) c), so) == EOF) { 04125 return -1; 04126 } 04127 04128 bio->linelength++; 04129 04130 return 1; 04131 }
static int open_mailbox | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | box | |||
) | [static] |
Definition at line 7710 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.
07711 { 07712 int count_msg, last_msg; 07713 07714 ast_copy_string(vms->curbox, mbox(vmu, box), sizeof(vms->curbox)); 07715 07716 /* Rename the member vmbox HERE so that we don't try to return before 07717 * we know what's going on. 07718 */ 07719 snprintf(vms->vmbox, sizeof(vms->vmbox), "vm-%s", vms->curbox); 07720 07721 /* Faster to make the directory than to check if it exists. */ 07722 create_dirpath(vms->curdir, sizeof(vms->curdir), vmu->context, vms->username, vms->curbox); 07723 07724 /* traverses directory using readdir (or select query for ODBC) */ 07725 count_msg = count_messages(vmu, vms->curdir); 07726 if (count_msg < 0) { 07727 return count_msg; 07728 } else { 07729 vms->lastmsg = count_msg - 1; 07730 } 07731 07732 if (vm_allocate_dh(vms, vmu, count_msg)) { 07733 return -1; 07734 } 07735 07736 /* 07737 The following test is needed in case sequencing gets messed up. 07738 There appears to be more than one way to mess up sequence, so 07739 we will not try to find all of the root causes--just fix it when 07740 detected. 07741 */ 07742 07743 if (vm_lock_path(vms->curdir)) { 07744 ast_log(AST_LOG_ERROR, "Could not open mailbox %s: mailbox is locked\n", vms->curdir); 07745 return ERROR_LOCK_PATH; 07746 } 07747 07748 /* for local storage, checks directory for messages up to maxmsg limit */ 07749 last_msg = last_message_index(vmu, vms->curdir); 07750 ast_unlock_path(vms->curdir); 07751 07752 if (last_msg < -1) { 07753 return last_msg; 07754 #ifndef ODBC_STORAGE 07755 } else if (vms->lastmsg != last_msg) { 07756 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); 07757 resequence_mailbox(vmu, vms->curdir, count_msg); 07758 #endif 07759 } 07760 07761 return 0; 07762 }
static int play_message | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 7496 of file app_voicemail_imapstorage.c.
References adsi_message(), ast_config_destroy(), ast_config_load, AST_DIGIT_ANY, ast_fileexists(), ast_log(), ast_say_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, DISPOSE, vm_state::fn, vm_state::heard, ast_channel::language, vm_state::lastmsg, LOG_WARNING, ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_category(), play_message_datetime(), play_message_duration(), RETRIEVE, ast_vm_user::saydurationm, vm_state::starting, VM_ENVELOPE, VM_SAYCID, VM_SAYDURATION, wait_file(), and wait_file2().
07497 { 07498 int res = 0; 07499 char filename[256], *cid; 07500 const char *origtime, *context, *category, *duration, *flag; 07501 struct ast_config *msg_cfg; 07502 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 07503 07504 vms->starting = 0; 07505 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07506 adsi_message(chan, vms); 07507 if (!vms->curmsg) 07508 res = wait_file2(chan, vms, "vm-first"); /* "First" */ 07509 else if (vms->curmsg == vms->lastmsg) 07510 res = wait_file2(chan, vms, "vm-last"); /* "last" */ 07511 07512 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 07513 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 07514 msg_cfg = ast_config_load(filename, config_flags); 07515 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 07516 ast_log(LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07517 return 0; 07518 } 07519 flag = ast_variable_retrieve(msg_cfg, "message", "flag"); 07520 07521 /* Play the word urgent if we are listening to urgent messages */ 07522 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { 07523 res = wait_file2(chan, vms, "vm-Urgent"); /* "urgent" */ 07524 } 07525 07526 if (!res) { 07527 /* XXX Why are we playing messages above, and then playing the same language-specific stuff here? */ 07528 /* POLISH syntax */ 07529 if (!strncasecmp(chan->language, "pl", 2)) { 07530 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07531 int ten, one; 07532 char nextmsg[256]; 07533 ten = (vms->curmsg + 1) / 10; 07534 one = (vms->curmsg + 1) % 10; 07535 07536 if (vms->curmsg < 20) { 07537 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", vms->curmsg + 1); 07538 res = wait_file2(chan, vms, nextmsg); 07539 } else { 07540 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", ten * 10); 07541 res = wait_file2(chan, vms, nextmsg); 07542 if (one > 0) { 07543 if (!res) { 07544 snprintf(nextmsg, sizeof(nextmsg), "digits/n-%d", one); 07545 res = wait_file2(chan, vms, nextmsg); 07546 } 07547 } 07548 } 07549 } 07550 if (!res) 07551 res = wait_file2(chan, vms, "vm-message"); 07552 /* HEBREW syntax */ 07553 } else if (!strncasecmp(chan->language, "he", 2)) { 07554 if (!vms->curmsg) { 07555 res = wait_file2(chan, vms, "vm-message"); 07556 res = wait_file2(chan, vms, "vm-first"); 07557 } else if (vms->curmsg == vms->lastmsg) { 07558 res = wait_file2(chan, vms, "vm-message"); 07559 res = wait_file2(chan, vms, "vm-last"); 07560 } else { 07561 res = wait_file2(chan, vms, "vm-message"); 07562 res = wait_file2(chan, vms, "vm-number"); 07563 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07564 } 07565 /* VIETNAMESE syntax */ 07566 } else if (!strncasecmp(chan->language, "vi", 2)) { 07567 if (!vms->curmsg) { 07568 res = wait_file2(chan, vms, "vm-message"); 07569 res = wait_file2(chan, vms, "vm-first"); 07570 } else if (vms->curmsg == vms->lastmsg) { 07571 res = wait_file2(chan, vms, "vm-message"); 07572 res = wait_file2(chan, vms, "vm-last"); 07573 } else { 07574 res = wait_file2(chan, vms, "vm-message"); 07575 res = wait_file2(chan, vms, "vm-number"); 07576 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, "f"); 07577 } 07578 } else { 07579 if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07580 res = wait_file2(chan, vms, "vm-meddelandet"); /* "message" */ 07581 } else { /* DEFAULT syntax */ 07582 res = wait_file2(chan, vms, "vm-message"); 07583 } 07584 if (vms->curmsg && (vms->curmsg != vms->lastmsg)) { 07585 if (!res) { 07586 res = ast_say_number(chan, vms->curmsg + 1, AST_DIGIT_ANY, chan->language, NULL); 07587 } 07588 } 07589 } 07590 } 07591 07592 if (!msg_cfg) { 07593 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 07594 return 0; 07595 } 07596 07597 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 07598 ast_log(AST_LOG_WARNING, "No origtime?!\n"); 07599 DISPOSE(vms->curdir, vms->curmsg); 07600 ast_config_destroy(msg_cfg); 07601 return 0; 07602 } 07603 07604 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 07605 duration = ast_variable_retrieve(msg_cfg, "message", "duration"); 07606 category = ast_variable_retrieve(msg_cfg, "message", "category"); 07607 07608 context = ast_variable_retrieve(msg_cfg, "message", "context"); 07609 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 07610 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 07611 if (!res) { 07612 res = play_message_category(chan, category); 07613 } 07614 if ((!res) && (ast_test_flag(vmu, VM_ENVELOPE))) 07615 res = play_message_datetime(chan, vmu, origtime, filename); 07616 if ((!res) && (ast_test_flag(vmu, VM_SAYCID))) 07617 res = play_message_callerid(chan, vms, cid, context, 0); 07618 if ((!res) && (ast_test_flag(vmu, VM_SAYDURATION))) 07619 res = play_message_duration(chan, vms, duration, vmu->saydurationm); 07620 /* Allow pressing '1' to skip envelope / callerid */ 07621 if (res == '1') 07622 res = 0; 07623 ast_config_destroy(msg_cfg); 07624 07625 if (!res) { 07626 make_file(vms->fn, sizeof(vms->fn), vms->curdir, vms->curmsg); 07627 vms->heard[vms->curmsg] = 1; 07628 #ifdef IMAP_STORAGE 07629 /*IMAP storage stores any prepended message from a forward 07630 * as a separate file from the rest of the message 07631 */ 07632 if (!ast_strlen_zero(vms->introfn) && ast_fileexists(vms->introfn, NULL, NULL) > 0) { 07633 wait_file(chan, vms, vms->introfn); 07634 } 07635 #endif 07636 if ((res = wait_file(chan, vms, vms->fn)) < 0) { 07637 ast_log(AST_LOG_WARNING, "Playback of message %s failed\n", vms->fn); 07638 res = 0; 07639 } 07640 } 07641 DISPOSE(vms->curdir, vms->curmsg); 07642 return res; 07643 }
static int play_message_callerid | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | cid, | |||
const char * | context, | |||
int | callback | |||
) | [static] |
Definition at line 7382 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, and wait_file2().
07383 { 07384 int res = 0; 07385 int i; 07386 char *callerid, *name; 07387 char prefile[PATH_MAX] = ""; 07388 07389 07390 /* If voicemail cid is not enabled, or we didn't get cid or context from 07391 * the attribute file, leave now. 07392 * 07393 * TODO Still need to change this so that if this function is called by the 07394 * message envelope (and someone is explicitly requesting to hear the CID), 07395 * it does not check to see if CID is enabled in the config file. 07396 */ 07397 if ((cid == NULL)||(context == NULL)) 07398 return res; 07399 07400 /* Strip off caller ID number from name */ 07401 ast_debug(1, "VM-CID: composite caller ID received: %s, context: %s\n", cid, context); 07402 ast_callerid_parse(cid, &name, &callerid); 07403 if ((!ast_strlen_zero(callerid)) && strcmp(callerid, "Unknown")) { 07404 /* Check for internal contexts and only */ 07405 /* say extension when the call didn't come from an internal context in the list */ 07406 for (i = 0 ; i < MAX_NUM_CID_CONTEXTS ; i++){ 07407 ast_debug(1, "VM-CID: comparing internalcontext: %s\n", cidinternalcontexts[i]); 07408 if ((strcmp(cidinternalcontexts[i], context) == 0)) 07409 break; 07410 } 07411 if (i != MAX_NUM_CID_CONTEXTS){ /* internal context? */ 07412 if (!res) { 07413 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, context, callerid); 07414 if (!ast_strlen_zero(prefile)) { 07415 /* See if we can find a recorded name for this person instead of their extension number */ 07416 if (ast_fileexists(prefile, NULL, NULL) > 0) { 07417 ast_verb(3, "Playing envelope info: CID number '%s' matches mailbox number, playing recorded name\n", callerid); 07418 if (!callback) 07419 res = wait_file2(chan, vms, "vm-from"); 07420 res = ast_stream_and_wait(chan, prefile, ""); 07421 } else { 07422 ast_verb(3, "Playing envelope info: message from '%s'\n", callerid); 07423 /* Say "from extension" as one saying to sound smoother */ 07424 if (!callback) 07425 res = wait_file2(chan, vms, "vm-from-extension"); 07426 res = ast_say_digit_str(chan, callerid, "", chan->language); 07427 } 07428 } 07429 } 07430 } else if (!res) { 07431 ast_debug(1, "VM-CID: Numeric caller id: (%s)\n", callerid); 07432 /* Since this is all nicely figured out, why not say "from phone number" in this case? */ 07433 if (!callback) 07434 res = wait_file2(chan, vms, "vm-from-phonenumber"); 07435 res = ast_say_digit_str(chan, callerid, AST_DIGIT_ANY, chan->language); 07436 } 07437 } else { 07438 /* Number unknown */ 07439 ast_debug(1, "VM-CID: From an unknown number\n"); 07440 /* Say "from an unknown caller" as one phrase - it is already recorded by "the voice" anyhow */ 07441 res = wait_file2(chan, vms, "vm-unknown-caller"); 07442 } 07443 return res; 07444 }
static int play_message_category | ( | struct ast_channel * | chan, | |
const char * | category | |||
) | [static] |
Definition at line 7293 of file app_voicemail_imapstorage.c.
References ast_log(), ast_play_and_wait(), and ast_strlen_zero().
07294 { 07295 int res = 0; 07296 07297 if (!ast_strlen_zero(category)) 07298 res = ast_play_and_wait(chan, category); 07299 07300 if (res) { 07301 ast_log(AST_LOG_WARNING, "No sound file for category '%s' was found.\n", category); 07302 res = 0; 07303 } 07304 07305 return res; 07306 }
static int play_message_datetime | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
const char * | origtime, | |||
const char * | filename | |||
) | [static] |
Definition at line 7308 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.
07309 { 07310 int res = 0; 07311 struct vm_zone *the_zone = NULL; 07312 time_t t; 07313 07314 if (ast_get_time_t(origtime, &t, 0, NULL)) { 07315 ast_log(AST_LOG_WARNING, "Couldn't find origtime in %s\n", filename); 07316 return 0; 07317 } 07318 07319 /* Does this user have a timezone specified? */ 07320 if (!ast_strlen_zero(vmu->zonetag)) { 07321 /* Find the zone in the list */ 07322 struct vm_zone *z; 07323 AST_LIST_LOCK(&zones); 07324 AST_LIST_TRAVERSE(&zones, z, list) { 07325 if (!strcmp(z->name, vmu->zonetag)) { 07326 the_zone = z; 07327 break; 07328 } 07329 } 07330 AST_LIST_UNLOCK(&zones); 07331 } 07332 07333 /* No internal variable parsing for now, so we'll comment it out for the time being */ 07334 #if 0 07335 /* Set the DIFF_* variables */ 07336 ast_localtime(&t, &time_now, NULL); 07337 tv_now = ast_tvnow(); 07338 ast_localtime(&tv_now, &time_then, NULL); 07339 07340 /* Day difference */ 07341 if (time_now.tm_year == time_then.tm_year) 07342 snprintf(temp, sizeof(temp), "%d", time_now.tm_yday); 07343 else 07344 snprintf(temp, sizeof(temp), "%d", (time_now.tm_year - time_then.tm_year) * 365 + (time_now.tm_yday - time_then.tm_yday)); 07345 pbx_builtin_setvar_helper(chan, "DIFF_DAY", temp); 07346 07347 /* Can't think of how other diffs might be helpful, but I'm sure somebody will think of something. */ 07348 #endif 07349 if (the_zone) { 07350 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, the_zone->msg_format, the_zone->timezone); 07351 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 07352 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07353 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 07354 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q H 'digits/kai' M ", NULL); 07355 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 07356 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); 07357 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 07358 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/nl-om' HM", NULL); 07359 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 07360 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q 'digits/at' HM", NULL); 07361 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 07362 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' Q HM", NULL); 07363 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* Brazillian PORTUGUESE syntax */ 07364 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); 07365 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 07366 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' dB 'digits/at' k 'and' M", NULL); 07367 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 07368 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "qR 'vm-received'", NULL); 07369 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 07370 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); 07371 } else { 07372 res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, chan->language, "'vm-received' q 'digits/at' IMp", NULL); 07373 } 07374 #if 0 07375 pbx_builtin_setvar_helper(chan, "DIFF_DAY", NULL); 07376 #endif 07377 return res; 07378 }
static int play_message_duration | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char * | duration, | |||
int | minduration | |||
) | [static] |
Definition at line 7446 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().
07447 { 07448 int res = 0; 07449 int durationm; 07450 int durations; 07451 /* Verify that we have a duration for the message */ 07452 if (duration == NULL) 07453 return res; 07454 07455 /* Convert from seconds to minutes */ 07456 durations = atoi(duration); 07457 durationm = (durations / 60); 07458 07459 ast_debug(1, "VM-Duration: duration is: %d seconds converted to: %d minutes\n", durations, durationm); 07460 07461 if ((!res) && (durationm >= minduration)) { 07462 res = wait_file2(chan, vms, "vm-duration"); 07463 07464 /* POLISH syntax */ 07465 if (!strncasecmp(chan->language, "pl", 2)) { 07466 div_t num = div(durationm, 10); 07467 07468 if (durationm == 1) { 07469 res = ast_play_and_wait(chan, "digits/1z"); 07470 res = res ? res : ast_play_and_wait(chan, "vm-minute-ta"); 07471 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 07472 if (num.rem == 2) { 07473 if (!num.quot) { 07474 res = ast_play_and_wait(chan, "digits/2-ie"); 07475 } else { 07476 res = say_and_wait(chan, durationm - 2 , chan->language); 07477 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 07478 } 07479 } else { 07480 res = say_and_wait(chan, durationm, chan->language); 07481 } 07482 res = res ? res : ast_play_and_wait(chan, "vm-minute-ty"); 07483 } else { 07484 res = say_and_wait(chan, durationm, chan->language); 07485 res = res ? res : ast_play_and_wait(chan, "vm-minute-t"); 07486 } 07487 /* DEFAULT syntax */ 07488 } else { 07489 res = ast_say_number(chan, durationm, AST_DIGIT_ANY, chan->language, NULL); 07490 res = wait_file2(chan, vms, "vm-minutes"); 07491 } 07492 } 07493 return res; 07494 }
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, | |||
const char * | unlockdir, | |||
signed char | record_gain, | |||
struct vm_state * | vms, | |||
char * | flag | |||
) | [static] |
Definition at line 12997 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, STORE, VERBOSE_PREFIX_3, vm_exec(), VM_OPERATOR, and VM_REVIEW.
13000 { 13001 /* Record message & let caller review or re-record it, or set options if applicable */ 13002 int res = 0; 13003 int cmd = 0; 13004 int max_attempts = 3; 13005 int attempts = 0; 13006 int recorded = 0; 13007 int msg_exists = 0; 13008 signed char zero_gain = 0; 13009 char tempfile[PATH_MAX]; 13010 char *acceptdtmf = "#"; 13011 char *canceldtmf = ""; 13012 int canceleddtmf = 0; 13013 13014 /* Note that urgent and private are for flagging messages as such in the future */ 13015 13016 /* barf if no pointer passed to store duration in */ 13017 if (duration == NULL) { 13018 ast_log(AST_LOG_WARNING, "Error play_record_review called without duration pointer\n"); 13019 return -1; 13020 } 13021 13022 if (!outsidecaller) 13023 snprintf(tempfile, sizeof(tempfile), "%s.tmp", recordfile); 13024 else 13025 ast_copy_string(tempfile, recordfile, sizeof(tempfile)); 13026 13027 cmd = '3'; /* Want to start by recording */ 13028 13029 while ((cmd >= 0) && (cmd != 't')) { 13030 switch (cmd) { 13031 case '1': 13032 if (!msg_exists) { 13033 /* In this case, 1 is to record a message */ 13034 cmd = '3'; 13035 break; 13036 } else { 13037 /* Otherwise 1 is to save the existing message */ 13038 ast_verb(3, "Saving message as is\n"); 13039 if (!outsidecaller) 13040 ast_filerename(tempfile, recordfile, NULL); 13041 ast_stream_and_wait(chan, "vm-msgsaved", ""); 13042 if (!outsidecaller) { 13043 /* Saves to IMAP server only if imapgreeting=yes */ 13044 STORE(recordfile, vmu->mailbox, vmu->context, -1, chan, vmu, fmt, *duration, vms, flag); 13045 DISPOSE(recordfile, -1); 13046 } 13047 cmd = 't'; 13048 return res; 13049 } 13050 case '2': 13051 /* Review */ 13052 ast_verb(3, "Reviewing the message\n"); 13053 cmd = ast_stream_and_wait(chan, tempfile, AST_DIGIT_ANY); 13054 break; 13055 case '3': 13056 msg_exists = 0; 13057 /* Record */ 13058 if (recorded == 1) 13059 ast_verb(3, "Re-recording the message\n"); 13060 else 13061 ast_verb(3, "Recording the message\n"); 13062 13063 if (recorded && outsidecaller) { 13064 cmd = ast_play_and_wait(chan, INTRO); 13065 cmd = ast_play_and_wait(chan, "beep"); 13066 } 13067 recorded = 1; 13068 /* 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 */ 13069 if (record_gain) 13070 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 13071 if (ast_test_flag(vmu, VM_OPERATOR)) 13072 canceldtmf = "0"; 13073 cmd = ast_play_and_record_full(chan, playfile, tempfile, maxtime, fmt, duration, silencethreshold, maxsilence, unlockdir, acceptdtmf, canceldtmf); 13074 if (strchr(canceldtmf, cmd)) { 13075 /* need this flag here to distinguish between pressing '0' during message recording or after */ 13076 canceleddtmf = 1; 13077 } 13078 if (record_gain) 13079 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 13080 if (cmd == -1) { 13081 /* User has hung up, no options to give */ 13082 if (!outsidecaller) { 13083 /* user was recording a greeting and they hung up, so let's delete the recording. */ 13084 ast_filedelete(tempfile, NULL); 13085 } 13086 return cmd; 13087 } 13088 if (cmd == '0') { 13089 break; 13090 } else if (cmd == '*') { 13091 break; 13092 #if 0 13093 } else if (vmu->review && (*duration < 5)) { 13094 /* Message is too short */ 13095 ast_verb(3, "Message too short\n"); 13096 cmd = ast_play_and_wait(chan, "vm-tooshort"); 13097 cmd = ast_filedelete(tempfile, NULL); 13098 break; 13099 } else if (vmu->review && (cmd == 2 && *duration < (maxsilence + 3))) { 13100 /* Message is all silence */ 13101 ast_verb(3, "Nothing recorded\n"); 13102 cmd = ast_filedelete(tempfile, NULL); 13103 cmd = ast_play_and_wait(chan, "vm-nothingrecorded"); 13104 if (!cmd) 13105 cmd = ast_play_and_wait(chan, "vm-speakup"); 13106 break; 13107 #endif 13108 } else { 13109 /* If all is well, a message exists */ 13110 msg_exists = 1; 13111 cmd = 0; 13112 } 13113 break; 13114 case '4': 13115 if (outsidecaller) { /* only mark vm messages */ 13116 /* Mark Urgent */ 13117 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13118 ast_verbose(VERBOSE_PREFIX_3 "marking message as Urgent\n"); 13119 res = ast_play_and_wait(chan, "vm-marked-urgent"); 13120 strcpy(flag, "Urgent"); 13121 } else if (flag) { 13122 ast_verbose(VERBOSE_PREFIX_3 "UNmarking message as Urgent\n"); 13123 res = ast_play_and_wait(chan, "vm-urgent-removed"); 13124 strcpy(flag, ""); 13125 } else { 13126 ast_play_and_wait(chan, "vm-sorry"); 13127 } 13128 cmd = 0; 13129 } else { 13130 cmd = ast_play_and_wait(chan, "vm-sorry"); 13131 } 13132 break; 13133 case '5': 13134 case '6': 13135 case '7': 13136 case '8': 13137 case '9': 13138 case '*': 13139 case '#': 13140 cmd = ast_play_and_wait(chan, "vm-sorry"); 13141 break; 13142 #if 0 13143 /* XXX Commented out for the moment because of the dangers of deleting 13144 a message while recording (can put the message numbers out of sync) */ 13145 case '*': 13146 /* Cancel recording, delete message, offer to take another message*/ 13147 cmd = ast_play_and_wait(chan, "vm-deleted"); 13148 cmd = ast_filedelete(tempfile, NULL); 13149 if (outsidecaller) { 13150 res = vm_exec(chan, NULL); 13151 return res; 13152 } 13153 else 13154 return 1; 13155 #endif 13156 case '0': 13157 if (!ast_test_flag(vmu, VM_OPERATOR) || (!canceleddtmf && !outsidecaller)) { 13158 cmd = ast_play_and_wait(chan, "vm-sorry"); 13159 break; 13160 } 13161 if (msg_exists || recorded) { 13162 cmd = ast_play_and_wait(chan, "vm-saveoper"); 13163 if (!cmd) 13164 cmd = ast_waitfordigit(chan, 3000); 13165 if (cmd == '1') { 13166 ast_filerename(tempfile, recordfile, NULL); 13167 ast_play_and_wait(chan, "vm-msgsaved"); 13168 cmd = '0'; 13169 } else if (cmd == '4') { 13170 if (flag) { 13171 ast_play_and_wait(chan, "vm-marked-urgent"); 13172 strcpy(flag, "Urgent"); 13173 } 13174 ast_play_and_wait(chan, "vm-msgsaved"); 13175 cmd = '0'; 13176 } else { 13177 ast_play_and_wait(chan, "vm-deleted"); 13178 DELETE(tempfile, -1, tempfile, vmu); 13179 cmd = '0'; 13180 } 13181 } 13182 return cmd; 13183 default: 13184 /* If the caller is an ouside caller, and the review option is enabled, 13185 allow them to review the message, but let the owner of the box review 13186 their OGM's */ 13187 if (outsidecaller && !ast_test_flag(vmu, VM_REVIEW)) 13188 return cmd; 13189 if (msg_exists) { 13190 cmd = ast_play_and_wait(chan, "vm-review"); 13191 if (!cmd && outsidecaller) { 13192 if ((flag && ast_strlen_zero(flag)) || (!ast_strlen_zero(flag) && strcmp(flag, "Urgent"))) { 13193 cmd = ast_play_and_wait(chan, "vm-review-urgent"); 13194 } else if (flag) { 13195 cmd = ast_play_and_wait(chan, "vm-review-nonurgent"); 13196 } 13197 } 13198 } else { 13199 cmd = ast_play_and_wait(chan, "vm-torerecord"); 13200 if (!cmd) 13201 cmd = ast_waitfordigit(chan, 600); 13202 } 13203 13204 if (!cmd && outsidecaller && ast_test_flag(vmu, VM_OPERATOR)) { 13205 cmd = ast_play_and_wait(chan, "vm-reachoper"); 13206 if (!cmd) 13207 cmd = ast_waitfordigit(chan, 600); 13208 } 13209 #if 0 13210 if (!cmd) 13211 cmd = ast_play_and_wait(chan, "vm-tocancelmsg"); 13212 #endif 13213 if (!cmd) 13214 cmd = ast_waitfordigit(chan, 6000); 13215 if (!cmd) { 13216 attempts++; 13217 } 13218 if (attempts > max_attempts) { 13219 cmd = 't'; 13220 } 13221 } 13222 } 13223 if (!outsidecaller && (cmd == -1 || cmd == 't')) { 13224 /* Hang up or timeout, so delete the recording. */ 13225 ast_filedelete(tempfile, NULL); 13226 } 13227 13228 if (cmd != 't' && outsidecaller) 13229 ast_play_and_wait(chan, "vm-goodbye"); 13230 13231 return cmd; 13232 }
static void poll_subscribed_mailbox | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 11152 of file app_voicemail_imapstorage.c.
References inboxcount2(), mwi_sub, queue_mwi_event(), and run_externnotify().
11153 { 11154 int new = 0, old = 0, urgent = 0; 11155 11156 inboxcount2(mwi_sub->mailbox, &urgent, &new, &old); 11157 11158 if (urgent != mwi_sub->old_urgent || new != mwi_sub->old_new || old != mwi_sub->old_old) { 11159 mwi_sub->old_urgent = urgent; 11160 mwi_sub->old_new = new; 11161 mwi_sub->old_old = old; 11162 queue_mwi_event(mwi_sub->mailbox, urgent, new, old); 11163 run_externnotify(NULL, mwi_sub->mailbox, NULL); 11164 } 11165 }
static void poll_subscribed_mailboxes | ( | void | ) | [static] |
Definition at line 11167 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().
11168 { 11169 struct mwi_sub *mwi_sub; 11170 11171 AST_RWLIST_RDLOCK(&mwi_subs); 11172 AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { 11173 if (!ast_strlen_zero(mwi_sub->mailbox)) { 11174 poll_subscribed_mailbox(mwi_sub); 11175 } 11176 } 11177 AST_RWLIST_UNLOCK(&mwi_subs); 11178 }
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 969 of file app_voicemail_imapstorage.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, 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.
00970 { 00971 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 00972 vmu->passwordlocation = passwordlocation; 00973 if (saydurationminfo) { 00974 vmu->saydurationm = saydurationminfo; 00975 } 00976 ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback)); 00977 ast_copy_string(vmu->dialout, dialcontext, sizeof(vmu->dialout)); 00978 ast_copy_string(vmu->exit, exitcontext, sizeof(vmu->exit)); 00979 ast_copy_string(vmu->zonetag, zonetag, sizeof(vmu->zonetag)); 00980 ast_copy_string(vmu->locale, locale, sizeof(vmu->locale)); 00981 if (vmminsecs) { 00982 vmu->minsecs = vmminsecs; 00983 } 00984 if (vmmaxsecs) { 00985 vmu->maxsecs = vmmaxsecs; 00986 } 00987 if (maxmsg) { 00988 vmu->maxmsg = maxmsg; 00989 } 00990 if (maxdeletedmsg) { 00991 vmu->maxdeletedmsg = maxdeletedmsg; 00992 } 00993 vmu->volgain = volgain; 00994 vmu->emailsubject = NULL; 00995 vmu->emailbody = NULL; 00996 #ifdef IMAP_STORAGE 00997 ast_copy_string(vmu->imapfolder, imapfolder, sizeof(vmu->imapfolder)); 00998 #endif 00999 }
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 4202 of file app_voicemail_imapstorage.c.
References ast_callerid_merge(), ast_callerid_split(), ast_config_destroy(), ast_config_load, ast_localtime(), ast_log(), ast_strdupa, ast_strftime_locale(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_NOCACHE, config_flags, ast_vm_user::context, emaildateformat, ast_vm_user::fullname, ast_vm_user::locale, LOG_DEBUG, ast_vm_user::mailbox, make_dir(), make_file(), option_debug, pbx_builtin_setvar_helper(), and S_OR.
04203 { 04204 char callerid[256]; 04205 char num[12]; 04206 char fromdir[256], fromfile[256]; 04207 struct ast_config *msg_cfg; 04208 const char *origcallerid, *origtime; 04209 char origcidname[80], origcidnum[80], origdate[80]; 04210 int inttime; 04211 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04212 04213 /* Prepare variables for substitution in email body and subject */ 04214 pbx_builtin_setvar_helper(ast, "VM_NAME", vmu->fullname); 04215 pbx_builtin_setvar_helper(ast, "VM_DUR", dur); 04216 snprintf(num, sizeof(num), "%d", msgnum); 04217 pbx_builtin_setvar_helper(ast, "VM_MSGNUM", num); 04218 pbx_builtin_setvar_helper(ast, "VM_CONTEXT", context); 04219 pbx_builtin_setvar_helper(ast, "VM_MAILBOX", mailbox); 04220 pbx_builtin_setvar_helper(ast, "VM_CALLERID", (!ast_strlen_zero(cidname) || !ast_strlen_zero(cidnum)) ? 04221 ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, NULL) : "an unknown caller"); 04222 pbx_builtin_setvar_helper(ast, "VM_CIDNAME", (!ast_strlen_zero(cidname) ? cidname : "an unknown caller")); 04223 pbx_builtin_setvar_helper(ast, "VM_CIDNUM", (!ast_strlen_zero(cidnum) ? cidnum : "an unknown caller")); 04224 pbx_builtin_setvar_helper(ast, "VM_DATE", date); 04225 pbx_builtin_setvar_helper(ast, "VM_CATEGORY", category ? ast_strdupa(category) : "no category"); 04226 pbx_builtin_setvar_helper(ast, "VM_FLAG", flag); 04227 04228 /* Retrieve info from VM attribute file */ 04229 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04230 make_file(fromfile, sizeof(fromfile), fromdir, msgnum - 1); 04231 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04232 strcat(fromfile, ".txt"); 04233 } 04234 if (!(msg_cfg = ast_config_load(fromfile, config_flags))) { 04235 if (option_debug > 0) { 04236 ast_log(LOG_DEBUG, "Config load for message text file '%s' failed\n", fromfile); 04237 } 04238 return; 04239 } 04240 04241 if ((origcallerid = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04242 pbx_builtin_setvar_helper(ast, "ORIG_VM_CALLERID", origcallerid); 04243 ast_callerid_split(origcallerid, origcidname, sizeof(origcidname), origcidnum, sizeof(origcidnum)); 04244 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNAME", origcidname); 04245 pbx_builtin_setvar_helper(ast, "ORIG_VM_CIDNUM", origcidnum); 04246 } 04247 04248 if ((origtime = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(origtime, "%30d", &inttime) == 1) { 04249 struct timeval tv = { inttime, }; 04250 struct ast_tm tm; 04251 ast_localtime(&tv, &tm, NULL); 04252 ast_strftime_locale(origdate, sizeof(origdate), emaildateformat, &tm, S_OR(vmu->locale, NULL)); 04253 pbx_builtin_setvar_helper(ast, "ORIG_VM_DATE", origdate); 04254 } 04255 ast_config_destroy(msg_cfg); 04256 }
static void queue_mwi_event | ( | const char * | box, | |
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 6839 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().
06840 { 06841 struct ast_event *event; 06842 char *mailbox, *context; 06843 06844 /* Strip off @default */ 06845 context = mailbox = ast_strdupa(box); 06846 strsep(&context, "@"); 06847 if (ast_strlen_zero(context)) 06848 context = "default"; 06849 06850 if (!(event = ast_event_new(AST_EVENT_MWI, 06851 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 06852 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 06853 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 06854 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 06855 AST_EVENT_IE_END))) { 06856 return; 06857 } 06858 06859 ast_event_queue_and_cache(event); 06860 }
static void read_password_from_file | ( | const char * | secretfn, | |
char * | password, | |||
int | passwordlen | |||
) | [static] |
Definition at line 12214 of file app_voicemail_imapstorage.c.
References ast_config_load, ast_copy_string(), ast_log(), ast_variable_retrieve(), config_flags, and LOG_NOTICE.
12214 { 12215 struct ast_config *pwconf; 12216 struct ast_flags config_flags = { 0 }; 12217 12218 pwconf = ast_config_load(secretfn, config_flags); 12219 if (pwconf) { 12220 const char *val = ast_variable_retrieve(pwconf, "general", "password"); 12221 if (val) { 12222 ast_copy_string(password, val, passwordlen); 12223 return; 12224 } 12225 } 12226 ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn); 12227 }
static int reload | ( | void | ) | [static] |
Definition at line 12651 of file app_voicemail_imapstorage.c.
References load_config().
12652 { 12653 return load_config(1); 12654 }
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 3871 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_filerename(), ast_update_realtime(), and SENTINEL.
03872 { 03873 char stxt[PATH_MAX]; 03874 char dtxt[PATH_MAX]; 03875 ast_filerename(sfn, dfn, NULL); 03876 snprintf(stxt, sizeof(stxt), "%s.txt", sfn); 03877 snprintf(dtxt, sizeof(dtxt), "%s.txt", dfn); 03878 if (ast_check_realtime("voicemail_data")) { 03879 ast_update_realtime("voicemail_data", "filename", sfn, "filename", dfn, SENTINEL); 03880 } 03881 rename(stxt, dtxt); 03882 }
static int resequence_mailbox | ( | struct ast_vm_user * | vmu, | |
char * | dir, | |||
int | stopcount | |||
) | [static] |
Definition at line 6009 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().
06010 { 06011 /* we know the actual number of messages, so stop process when number is hit */ 06012 06013 int x, dest; 06014 char sfn[PATH_MAX]; 06015 char dfn[PATH_MAX]; 06016 06017 if (vm_lock_path(dir)) 06018 return ERROR_LOCK_PATH; 06019 06020 for (x = 0, dest = 0; dest != stopcount && x < vmu->maxmsg + 10; x++) { 06021 make_file(sfn, sizeof(sfn), dir, x); 06022 if (EXISTS(dir, x, sfn, NULL)) { 06023 06024 if (x != dest) { 06025 make_file(dfn, sizeof(dfn), dir, dest); 06026 RENAME(dir, x, vmu->mailbox, vmu->context, dir, dest, sfn, dfn); 06027 } 06028 06029 dest++; 06030 } 06031 } 06032 ast_unlock_path(dir); 06033 06034 return dest; 06035 }
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 1413 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.
01414 { 01415 /* This function could be made to generate one from a database, too */ 01416 struct ast_vm_user *cur; 01417 int res = -1; 01418 AST_LIST_LOCK(&users); 01419 AST_LIST_TRAVERSE(&users, cur, list) { 01420 if ((!context || !strcasecmp(context, cur->context)) && 01421 (!strcasecmp(mailbox, cur->mailbox))) 01422 break; 01423 } 01424 if (cur) { 01425 ast_copy_string(cur->password, newpass, sizeof(cur->password)); 01426 res = 0; 01427 } 01428 AST_LIST_UNLOCK(&users); 01429 return res; 01430 }
static void run_externnotify | ( | char * | context, | |
char * | extension, | |||
const char * | flag | |||
) | [static] |
Definition at line 5383 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, ast_smdi_mwi_message::fwd_st, inboxcount2(), smdi_iface, and SMDI_MWI_WAIT_TIMEOUT.
05384 { 05385 char arguments[255]; 05386 char ext_context[256] = ""; 05387 int newvoicemails = 0, oldvoicemails = 0, urgentvoicemails = 0; 05388 struct ast_smdi_mwi_message *mwi_msg; 05389 05390 if (!ast_strlen_zero(context)) 05391 snprintf(ext_context, sizeof(ext_context), "%s@%s", extension, context); 05392 else 05393 ast_copy_string(ext_context, extension, sizeof(ext_context)); 05394 05395 if (smdi_iface) { 05396 if (ast_app_has_voicemail(ext_context, NULL)) 05397 ast_smdi_mwi_set(smdi_iface, extension); 05398 else 05399 ast_smdi_mwi_unset(smdi_iface, extension); 05400 05401 if ((mwi_msg = ast_smdi_mwi_message_wait_station(smdi_iface, SMDI_MWI_WAIT_TIMEOUT, extension))) { 05402 ast_log(AST_LOG_ERROR, "Error executing SMDI MWI change for %s\n", extension); 05403 if (!strncmp(mwi_msg->cause, "INV", 3)) 05404 ast_log(AST_LOG_ERROR, "Invalid MWI extension: %s\n", mwi_msg->fwd_st); 05405 else if (!strncmp(mwi_msg->cause, "BLK", 3)) 05406 ast_log(AST_LOG_WARNING, "MWI light was already on or off for %s\n", mwi_msg->fwd_st); 05407 ast_log(AST_LOG_WARNING, "The switch reported '%s'\n", mwi_msg->cause); 05408 ASTOBJ_UNREF(mwi_msg, ast_smdi_mwi_message_destroy); 05409 } else { 05410 ast_debug(1, "Successfully executed SMDI MWI change for %s\n", extension); 05411 } 05412 } 05413 05414 if (!ast_strlen_zero(externnotify)) { 05415 if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) { 05416 ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension); 05417 } else { 05418 snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails); 05419 ast_debug(1, "Executing %s\n", arguments); 05420 ast_safe_system(arguments); 05421 } 05422 } 05423 }
static int save_to_folder | ( | struct ast_vm_user * | vmu, | |
struct vm_state * | vms, | |||
int | msg, | |||
int | box | |||
) | [static] |
Definition at line 6045 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().
06046 { 06047 #ifdef IMAP_STORAGE 06048 /* we must use mbox(x) folder names, and copy the message there */ 06049 /* simple. huh? */ 06050 char sequence[10]; 06051 char mailbox[256]; 06052 int res; 06053 06054 /* get the real IMAP message number for this message */ 06055 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 06056 06057 ast_debug(3, "Copying sequence %s to mailbox %s\n", sequence, mbox(vmu, box)); 06058 ast_mutex_lock(&vms->lock); 06059 /* if save to Old folder, put in INBOX as read */ 06060 if (box == OLD_FOLDER) { 06061 mail_setflag(vms->mailstream, sequence, "\\Seen"); 06062 mail_clearflag(vms->mailstream, sequence, "\\Unseen"); 06063 } else if (box == NEW_FOLDER) { 06064 mail_setflag(vms->mailstream, sequence, "\\Unseen"); 06065 mail_clearflag(vms->mailstream, sequence, "\\Seen"); 06066 } 06067 if (!strcasecmp(mbox(vmu, NEW_FOLDER), vms->curbox) && (box == NEW_FOLDER || box == OLD_FOLDER)) { 06068 ast_mutex_unlock(&vms->lock); 06069 return 0; 06070 } 06071 /* Create the folder if it don't exist */ 06072 imap_mailbox_name(mailbox, sizeof(mailbox), vms, box, 1); /* Get the full mailbox name */ 06073 ast_debug(5, "Checking if folder exists: %s\n", mailbox); 06074 if (mail_create(vms->mailstream, mailbox) == NIL) 06075 ast_debug(5, "Folder exists.\n"); 06076 else 06077 ast_log(AST_LOG_NOTICE, "Folder %s created!\n", mbox(vmu, box)); 06078 res = !mail_copy(vms->mailstream, sequence, (char *) mbox(vmu, box)); 06079 ast_mutex_unlock(&vms->lock); 06080 return res; 06081 #else 06082 char *dir = vms->curdir; 06083 char *username = vms->username; 06084 char *context = vmu->context; 06085 char sfn[PATH_MAX]; 06086 char dfn[PATH_MAX]; 06087 char ddir[PATH_MAX]; 06088 const char *dbox = mbox(vmu, box); 06089 int x, i; 06090 create_dirpath(ddir, sizeof(ddir), context, username, dbox); 06091 06092 if (vm_lock_path(ddir)) 06093 return ERROR_LOCK_PATH; 06094 06095 x = last_message_index(vmu, ddir) + 1; 06096 06097 if (box == 10 && x >= vmu->maxdeletedmsg) { /* "Deleted" folder*/ 06098 x--; 06099 for (i = 1; i <= x; i++) { 06100 /* Push files down a "slot". The oldest file (msg0000) will be deleted. */ 06101 make_file(sfn, sizeof(sfn), ddir, i); 06102 make_file(dfn, sizeof(dfn), ddir, i - 1); 06103 if (EXISTS(ddir, i, sfn, NULL)) { 06104 RENAME(ddir, i, vmu->mailbox, vmu->context, ddir, i - 1, sfn, dfn); 06105 } else 06106 break; 06107 } 06108 } else { 06109 if (x >= vmu->maxmsg) { 06110 ast_unlock_path(ddir); 06111 return -1; 06112 } 06113 } 06114 make_file(sfn, sizeof(sfn), dir, msg); 06115 make_file(dfn, sizeof(dfn), ddir, x); 06116 if (strcmp(sfn, dfn)) { 06117 COPY(dir, msg, ddir, x, username, context, sfn, dfn); 06118 } 06119 ast_unlock_path(ddir); 06120 #endif 06121 return 0; 06122 }
static int say_and_wait | ( | struct ast_channel * | chan, | |
int | num, | |||
const char * | language | |||
) | [static] |
Definition at line 6038 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, and ast_say_number().
06039 { 06040 int d; 06041 d = ast_say_number(chan, num, AST_DIGIT_ANY, language, NULL); 06042 return d; 06043 }
static int sayname | ( | struct ast_channel * | chan, | |
const char * | mailbox, | |||
const char * | context | |||
) | [static] |
Definition at line 12200 of file app_voicemail_imapstorage.c.
References ast_debug, AST_DIGIT_ANY, ast_fileexists(), ast_stream_and_wait(), DISPOSE, and RETRIEVE.
12201 { 12202 int res = -1; 12203 char dir[PATH_MAX]; 12204 snprintf(dir, sizeof(dir), "%s%s/%s/greet", VM_SPOOL_DIR, context, mailbox); 12205 ast_debug(2, "About to try retrieving name file %s\n", dir); 12206 RETRIEVE(dir, -1, mailbox, context); 12207 if (ast_fileexists(dir, NULL, NULL)) { 12208 res = ast_stream_and_wait(chan, dir, AST_DIGIT_ANY); 12209 } 12210 DISPOSE(dir, -1); 12211 return res; 12212 }
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 4715 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, make_email_file(), strsep(), VM_ATTACH, and vm_mkftemp().
04716 { 04717 FILE *p = NULL; 04718 char tmp[80] = "/tmp/astmail-XXXXXX"; 04719 char tmp2[256]; 04720 char *stringp; 04721 04722 if (vmu && ast_strlen_zero(vmu->email)) { 04723 ast_log(AST_LOG_WARNING, "E-mail address missing for mailbox [%s]. E-mail will not be sent.\n", vmu->mailbox); 04724 return(0); 04725 } 04726 04727 /* Mail only the first format */ 04728 format = ast_strdupa(format); 04729 stringp = format; 04730 strsep(&stringp, "|"); 04731 04732 if (!strcmp(format, "wav49")) 04733 format = "WAV"; 04734 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)); 04735 /* Make a temporary file instead of piping directly to sendmail, in case the mail 04736 command hangs */ 04737 if ((p = vm_mkftemp(tmp)) == NULL) { 04738 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04739 return -1; 04740 } else { 04741 make_email_file(p, srcemail, vmu, msgnum, context, mailbox, fromfolder, cidnum, cidname, attach, attach2, format, duration, attach_user_voicemail, chan, category, 0, flag); 04742 fclose(p); 04743 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04744 ast_safe_system(tmp2); 04745 ast_debug(1, "Sent mail to %s with command '%s'\n", vmu->email, mailcmd); 04746 } 04747 return 0; 04748 }
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 4750 of file app_voicemail_imapstorage.c.
References ast_channel_release(), ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, ast_log(), ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strftime_locale(), ast_strlen_zero(), check_mime(), ENDL, ast_vm_user::fullname, ast_vm_user::locale, MAXHOSTNAMELEN, pagerbody, pagerdateformat, pagerfromstring, pagersubject, prep_email_sub_vars(), S_OR, strip_control_and_high(), vm_mkftemp(), and vmu_tm().
04751 { 04752 char enc_cidnum[256], enc_cidname[256]; 04753 char date[256]; 04754 char host[MAXHOSTNAMELEN] = ""; 04755 char who[256]; 04756 char dur[PATH_MAX]; 04757 char tmp[80] = "/tmp/astmail-XXXXXX"; 04758 char tmp2[PATH_MAX]; 04759 struct ast_tm tm; 04760 FILE *p; 04761 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04762 04763 if (!str1 || !str2) { 04764 ast_free(str1); 04765 ast_free(str2); 04766 return -1; 04767 } 04768 04769 if (cidnum) { 04770 strip_control_and_high(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04771 } 04772 if (cidname) { 04773 strip_control_and_high(cidname, enc_cidname, sizeof(enc_cidname)); 04774 } 04775 04776 if ((p = vm_mkftemp(tmp)) == NULL) { 04777 ast_log(AST_LOG_WARNING, "Unable to launch '%s' (can't create temporary file)\n", mailcmd); 04778 ast_free(str1); 04779 ast_free(str2); 04780 return -1; 04781 } 04782 gethostname(host, sizeof(host)-1); 04783 if (strchr(srcemail, '@')) { 04784 ast_copy_string(who, srcemail, sizeof(who)); 04785 } else { 04786 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04787 } 04788 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04789 ast_strftime_locale(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04790 fprintf(p, "Date: %s\n", date); 04791 04792 /* Reformat for custom pager format */ 04793 ast_strftime_locale(date, sizeof(date), pagerdateformat, vmu_tm(vmu, &tm), S_OR(vmu->locale, NULL)); 04794 04795 if (!ast_strlen_zero(pagerfromstring)) { 04796 struct ast_channel *ast; 04797 if ((ast = ast_dummy_channel_alloc())) { 04798 char *ptr; 04799 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04800 ast_str_substitute_variables(&str1, 0, ast, pagerfromstring); 04801 04802 if (check_mime(ast_str_buffer(str1))) { 04803 int first_line = 1; 04804 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04805 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04806 *ptr = '\0'; 04807 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04808 first_line = 0; 04809 /* Substring is smaller, so this will never grow */ 04810 ast_str_set(&str2, 0, "%s", ptr + 1); 04811 } 04812 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04813 } else { 04814 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04815 } 04816 ast = ast_channel_release(ast); 04817 } else { 04818 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04819 } 04820 } else { 04821 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04822 } 04823 04824 if (check_mime(vmu->fullname)) { 04825 int first_line = 1; 04826 char *ptr; 04827 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(pager) + 3); 04828 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04829 *ptr = '\0'; 04830 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04831 first_line = 0; 04832 /* Substring is smaller, so this will never grow */ 04833 ast_str_set(&str2, 0, "%s", ptr + 1); 04834 } 04835 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), pager); 04836 } else { 04837 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), pager); 04838 } 04839 04840 if (!ast_strlen_zero(pagersubject)) { 04841 struct ast_channel *ast; 04842 if ((ast = ast_dummy_channel_alloc())) { 04843 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04844 ast_str_substitute_variables(&str1, 0, ast, pagersubject); 04845 if (check_mime(ast_str_buffer(str1))) { 04846 int first_line = 1; 04847 char *ptr; 04848 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04849 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04850 *ptr = '\0'; 04851 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04852 first_line = 0; 04853 /* Substring is smaller, so this will never grow */ 04854 ast_str_set(&str2, 0, "%s", ptr + 1); 04855 } 04856 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04857 } else { 04858 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04859 } 04860 ast = ast_channel_release(ast); 04861 } else { 04862 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04863 } 04864 } else { 04865 if (ast_strlen_zero(flag)) { 04866 fprintf(p, "Subject: New VM\n\n"); 04867 } else { 04868 fprintf(p, "Subject: New %s VM\n\n", flag); 04869 } 04870 } 04871 04872 if (pagerbody) { 04873 struct ast_channel *ast; 04874 if ((ast = ast_dummy_channel_alloc())) { 04875 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04876 ast_str_substitute_variables(&str1, 0, ast, pagerbody); 04877 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04878 ast = ast_channel_release(ast); 04879 } else { 04880 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04881 } 04882 } else { 04883 fprintf(p, "New %s long %s msg in box %s\n" 04884 "from %s, on %s", dur, flag, mailbox, (cidname ? cidname : (cidnum ? cidnum : "unknown")), date); 04885 } 04886 04887 fclose(p); 04888 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); 04889 ast_safe_system(tmp2); 04890 ast_debug(1, "Sent page to %s with command '%s'\n", pager, mailcmd); 04891 ast_free(str1); 04892 ast_free(str2); 04893 return 0; 04894 }
static char* show_users_realtime | ( | int | fd, | |
const char * | context | |||
) | [static] |
Definition at line 10809 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.
10810 { 10811 struct ast_config *cfg; 10812 const char *cat = NULL; 10813 10814 if (!(cfg = ast_load_realtime_multientry("voicemail", 10815 "context", context, SENTINEL))) { 10816 return CLI_FAILURE; 10817 } 10818 10819 ast_cli(fd, 10820 "\n" 10821 "=============================================================\n" 10822 "=== Configured Voicemail Users ==============================\n" 10823 "=============================================================\n" 10824 "===\n"); 10825 10826 while ((cat = ast_category_browse(cfg, cat))) { 10827 struct ast_variable *var = NULL; 10828 ast_cli(fd, 10829 "=== Mailbox ...\n" 10830 "===\n"); 10831 for (var = ast_variable_browse(cfg, cat); var; var = var->next) 10832 ast_cli(fd, "=== ==> %s: %s\n", var->name, var->value); 10833 ast_cli(fd, 10834 "===\n" 10835 "=== ---------------------------------------------------------\n" 10836 "===\n"); 10837 } 10838 10839 ast_cli(fd, 10840 "=============================================================\n" 10841 "\n"); 10842 10843 ast_config_destroy(cfg); 10844 10845 return CLI_SUCCESS; 10846 }
static void start_poll_thread | ( | void | ) | [static] |
Definition at line 11304 of file app_voicemail_imapstorage.c.
References AST_EVENT_IE_END, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_report_subs(), AST_EVENT_SUB, ast_event_subscribe(), AST_EVENT_UNSUB, ast_pthread_create, mb_poll_thread(), mwi_sub_event_cb(), mwi_sub_sub, mwi_unsub_event_cb(), and mwi_unsub_sub.
11305 { 11306 mwi_sub_sub = ast_event_subscribe(AST_EVENT_SUB, mwi_sub_event_cb, "Voicemail MWI subscription", NULL, 11307 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11308 AST_EVENT_IE_END); 11309 11310 mwi_unsub_sub = ast_event_subscribe(AST_EVENT_UNSUB, mwi_unsub_event_cb, "Voicemail MWI subscription", NULL, 11311 AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, 11312 AST_EVENT_IE_END); 11313 11314 if (mwi_sub_sub) 11315 ast_event_report_subs(mwi_sub_sub); 11316 11317 poll_thread_run = 1; 11318 11319 ast_pthread_create(&poll_thread, NULL, mb_poll_thread, NULL); 11320 }
static void stop_poll_thread | ( | void | ) | [static] |
Definition at line 11322 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, and poll_lock.
11323 { 11324 poll_thread_run = 0; 11325 11326 if (mwi_sub_sub) { 11327 ast_event_unsubscribe(mwi_sub_sub); 11328 mwi_sub_sub = NULL; 11329 } 11330 11331 if (mwi_unsub_sub) { 11332 ast_event_unsubscribe(mwi_unsub_sub); 11333 mwi_unsub_sub = NULL; 11334 } 11335 11336 ast_mutex_lock(&poll_lock); 11337 ast_cond_signal(&poll_cond); 11338 ast_mutex_unlock(&poll_lock); 11339 11340 pthread_join(poll_thread, NULL); 11341 11342 poll_thread = AST_PTHREADT_NULL; 11343 }
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 940 of file app_voicemail_imapstorage.c.
00941 { 00942 char *bufptr = buf; 00943 for (; *input; input++) { 00944 if (*input < 32) { 00945 continue; 00946 } 00947 *bufptr++ = *input; 00948 if (bufptr == buf + buflen - 1) { 00949 break; 00950 } 00951 } 00952 *bufptr = '\0'; 00953 return buf; 00954 }
static const char* substitute_escapes | ( | const char * | value | ) | [static] |
Definition at line 11468 of file app_voicemail_imapstorage.c.
References ast_log(), AST_LOG_NOTICE, ast_str_append(), ast_str_reset(), ast_str_thread_get(), and str.
11469 { 11470 char *current; 11471 11472 /* Add 16 for fudge factor */ 11473 struct ast_str *str = ast_str_thread_get(&ast_str_thread_global_buf, strlen(value) + 16); 11474 11475 ast_str_reset(str); 11476 11477 /* Substitute strings \r, \n, and \t into the appropriate characters */ 11478 for (current = (char *) value; *current; current++) { 11479 if (*current == '\\') { 11480 current++; 11481 if (!*current) { 11482 ast_log(AST_LOG_NOTICE, "Incomplete escape at end of value.\n"); 11483 break; 11484 } 11485 switch (*current) { 11486 case 'r': 11487 ast_str_append(&str, 0, "\r"); 11488 break; 11489 case 'n': 11490 #ifdef IMAP_STORAGE 11491 if (!str->used || str->str[str->used - 1] != '\r') { 11492 ast_str_append(&str, 0, "\r"); 11493 } 11494 #endif 11495 ast_str_append(&str, 0, "\n"); 11496 break; 11497 case 't': 11498 ast_str_append(&str, 0, "\t"); 11499 break; 11500 default: 11501 ast_log(AST_LOG_NOTICE, "Substitution routine does not support this character: \\%c\n", *current); 11502 break; 11503 } 11504 } else { 11505 ast_str_append(&str, 0, "%c", *current); 11506 } 11507 } 11508 11509 return ast_str_buffer(str); 11510 }
static int unload_module | ( | void | ) | [static] |
Definition at line 12656 of file app_voicemail_imapstorage.c.
References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_data_unregister, ast_manager_unregister(), AST_PTHREADT_NULL, ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_uninstall_vm_functions(), ast_unload_realtime(), ast_unregister_application(), cli_voicemail, free_vm_users(), free_vm_zones(), inprocess_container, mailbox_exists_acf, mwi_subscription_tps, and stop_poll_thread().
12657 { 12658 int res; 12659 12660 res = ast_unregister_application(app); 12661 res |= ast_unregister_application(app2); 12662 res |= ast_unregister_application(app3); 12663 res |= ast_unregister_application(app4); 12664 res |= ast_unregister_application(sayname_app); 12665 res |= ast_custom_function_unregister(&mailbox_exists_acf); 12666 res |= ast_manager_unregister("VoicemailUsersList"); 12667 res |= ast_data_unregister(NULL); 12668 #ifdef TEST_FRAMEWORK 12669 res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname); 12670 res |= AST_TEST_UNREGISTER(test_voicemail_msgcount); 12671 res |= AST_TEST_UNREGISTER(test_voicemail_vmuser); 12672 res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl); 12673 #endif 12674 ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 12675 ast_uninstall_vm_functions(); 12676 ao2_ref(inprocess_container, -1); 12677 12678 if (poll_thread != AST_PTHREADT_NULL) 12679 stop_poll_thread(); 12680 12681 mwi_subscription_tps = ast_taskprocessor_unreference(mwi_subscription_tps); 12682 ast_unload_realtime("voicemail"); 12683 ast_unload_realtime("voicemail_data"); 12684 12685 free_vm_users(); 12686 free_vm_zones(); 12687 return res; 12688 }
static int vm_allocate_dh | ( | struct vm_state * | vms, | |
struct ast_vm_user * | vmu, | |||
int | count_msg | |||
) | [static] |
Definition at line 1679 of file app_voicemail_imapstorage.c.
References ast_calloc, ast_realloc, vm_state::deleted, vm_state::dh_arraysize, vm_state::heard, and ast_vm_user::maxmsg.
01679 { 01680 01681 int arraysize = (vmu->maxmsg > count_msg ? vmu->maxmsg : count_msg); 01682 if (!vms->dh_arraysize) { 01683 /* initial allocation */ 01684 if (!(vms->deleted = ast_calloc(arraysize, sizeof(int)))) { 01685 return -1; 01686 } 01687 if (!(vms->heard = ast_calloc(arraysize, sizeof(int)))) { 01688 return -1; 01689 } 01690 vms->dh_arraysize = arraysize; 01691 } else if (vms->dh_arraysize < arraysize) { 01692 if (!(vms->deleted = ast_realloc(vms->deleted, arraysize * sizeof(int)))) { 01693 return -1; 01694 } 01695 if (!(vms->heard = ast_realloc(vms->heard, arraysize * sizeof(int)))) { 01696 return -1; 01697 } 01698 memset(vms->deleted, 0, arraysize * sizeof(int)); 01699 memset(vms->heard, 0, arraysize * sizeof(int)); 01700 vms->dh_arraysize = arraysize; 01701 } 01702 01703 return 0; 01704 }
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 9541 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_verb, ast_waitstream(), find_user(), ast_vm_user::password, S_COR, and vm_password.
09544 { 09545 int useadsi = 0, valid = 0, logretries = 0; 09546 char password[AST_MAX_EXTENSION]="", *passptr; 09547 struct ast_vm_user vmus, *vmu = NULL; 09548 09549 /* If ADSI is supported, setup login screen */ 09550 adsi_begin(chan, &useadsi); 09551 if (!skipuser && useadsi) 09552 adsi_login(chan); 09553 if (!silent && !skipuser && ast_streamfile(chan, "vm-login", chan->language)) { 09554 ast_log(AST_LOG_WARNING, "Couldn't stream login file\n"); 09555 return -1; 09556 } 09557 09558 /* Authenticate them and get their mailbox/password */ 09559 09560 while (!valid && (logretries < max_logins)) { 09561 /* Prompt for, and read in the username */ 09562 if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) { 09563 ast_log(AST_LOG_WARNING, "Couldn't read username\n"); 09564 return -1; 09565 } 09566 if (ast_strlen_zero(mailbox)) { 09567 if (chan->caller.id.number.valid && chan->caller.id.number.str) { 09568 ast_copy_string(mailbox, chan->caller.id.number.str, mailbox_size); 09569 } else { 09570 ast_verb(3, "Username not entered\n"); 09571 return -1; 09572 } 09573 } else if (mailbox[0] == '*') { 09574 /* user entered '*' */ 09575 if (ast_exists_extension(chan, chan->context, "a", 1, 09576 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09577 return -1; 09578 } 09579 mailbox[0] = '\0'; 09580 } 09581 09582 if (useadsi) 09583 adsi_password(chan); 09584 09585 if (!ast_strlen_zero(prefix)) { 09586 char fullusername[80] = ""; 09587 ast_copy_string(fullusername, prefix, sizeof(fullusername)); 09588 strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername)); 09589 ast_copy_string(mailbox, fullusername, mailbox_size); 09590 } 09591 09592 ast_debug(1, "Before find user for mailbox %s\n", mailbox); 09593 vmu = find_user(&vmus, context, mailbox); 09594 if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) { 09595 /* saved password is blank, so don't bother asking */ 09596 password[0] = '\0'; 09597 } else { 09598 if (ast_streamfile(chan, vm_password, chan->language)) { 09599 ast_log(AST_LOG_WARNING, "Unable to stream password file\n"); 09600 return -1; 09601 } 09602 if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { 09603 ast_log(AST_LOG_WARNING, "Unable to read password\n"); 09604 return -1; 09605 } else if (password[0] == '*') { 09606 /* user entered '*' */ 09607 if (ast_exists_extension(chan, chan->context, "a", 1, 09608 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 09609 mailbox[0] = '*'; 09610 return -1; 09611 } 09612 mailbox[0] = '\0'; 09613 } 09614 } 09615 09616 if (vmu) { 09617 passptr = vmu->password; 09618 if (passptr[0] == '-') passptr++; 09619 } 09620 if (vmu && !strcmp(passptr, password)) 09621 valid++; 09622 else { 09623 ast_verb(3, "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "default"); 09624 if (!ast_strlen_zero(prefix)) 09625 mailbox[0] = '\0'; 09626 } 09627 logretries++; 09628 if (!valid) { 09629 if (skipuser || logretries >= max_logins) { 09630 if (ast_streamfile(chan, "vm-incorrect", chan->language)) { 09631 ast_log(AST_LOG_WARNING, "Unable to stream incorrect message\n"); 09632 return -1; 09633 } 09634 } else { 09635 if (useadsi) 09636 adsi_login(chan); 09637 if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language)) { 09638 ast_log(AST_LOG_WARNING, "Unable to stream incorrect mailbox message\n"); 09639 return -1; 09640 } 09641 } 09642 if (ast_waitstream(chan, "")) /* Channel is hung up */ 09643 return -1; 09644 } 09645 } 09646 if (!valid && (logretries >= max_logins)) { 09647 ast_stopstream(chan); 09648 ast_play_and_wait(chan, "vm-goodbye"); 09649 return -1; 09650 } 09651 if (vmu && !skipuser) { 09652 memcpy(res_vmu, vmu, sizeof(struct ast_vm_user)); 09653 } 09654 return 0; 09655 }
static int vm_box_exists | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10704 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().
10705 { 10706 struct ast_vm_user svm; 10707 char *context, *box; 10708 AST_DECLARE_APP_ARGS(args, 10709 AST_APP_ARG(mbox); 10710 AST_APP_ARG(options); 10711 ); 10712 static int dep_warning = 0; 10713 10714 if (ast_strlen_zero(data)) { 10715 ast_log(AST_LOG_ERROR, "MailboxExists requires an argument: (vmbox[@context][|options])\n"); 10716 return -1; 10717 } 10718 10719 if (!dep_warning) { 10720 dep_warning = 1; 10721 ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data); 10722 } 10723 10724 box = ast_strdupa(data); 10725 10726 AST_STANDARD_APP_ARGS(args, box); 10727 10728 if (args.options) { 10729 } 10730 10731 if ((context = strchr(args.mbox, '@'))) { 10732 *context = '\0'; 10733 context++; 10734 } 10735 10736 if (find_user(&svm, context, args.mbox)) { 10737 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "SUCCESS"); 10738 } else 10739 pbx_builtin_setvar_helper(chan, "VMBOXEXISTSSTATUS", "FAILED"); 10740 10741 return 0; 10742 }
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 9520 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().
09521 { 09522 if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH */ 09523 return vm_browse_messages_es(chan, vms, vmu); 09524 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK */ 09525 return vm_browse_messages_gr(chan, vms, vmu); 09526 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW */ 09527 return vm_browse_messages_he(chan, vms, vmu); 09528 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN */ 09529 return vm_browse_messages_it(chan, vms, vmu); 09530 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE */ 09531 return vm_browse_messages_pt(chan, vms, vmu); 09532 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE */ 09533 return vm_browse_messages_vi(chan, vms, vmu); 09534 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) */ 09535 return vm_browse_messages_zh(chan, vms, vmu); 09536 } else { /* Default to English syntax */ 09537 return vm_browse_messages_en(chan, vms, vmu); 09538 } 09539 }
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 9359 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09360 { 09361 int cmd = 0; 09362 09363 if (vms->lastmsg > -1) { 09364 cmd = play_message(chan, vmu, vms); 09365 } else { 09366 cmd = ast_play_and_wait(chan, "vm-youhave"); 09367 if (!cmd) 09368 cmd = ast_play_and_wait(chan, "vm-no"); 09369 if (!cmd) { 09370 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09371 cmd = ast_play_and_wait(chan, vms->fn); 09372 } 09373 if (!cmd) 09374 cmd = ast_play_and_wait(chan, "vm-messages"); 09375 } 09376 return cmd; 09377 }
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 9413 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09414 { 09415 int cmd; 09416 09417 if (vms->lastmsg > -1) { 09418 cmd = play_message(chan, vmu, vms); 09419 } else { 09420 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09421 if (!cmd) 09422 cmd = ast_play_and_wait(chan, "vm-messages"); 09423 if (!cmd) { 09424 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09425 cmd = ast_play_and_wait(chan, vms->fn); 09426 } 09427 } 09428 return cmd; 09429 }
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 9307 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.
09308 { 09309 int cmd = 0; 09310 09311 if (vms->lastmsg > -1) { 09312 cmd = play_message(chan, vmu, vms); 09313 } else { 09314 cmd = ast_play_and_wait(chan, "vm-youhaveno"); 09315 if (!strcasecmp(vms->vmbox, "vm-INBOX") ||!strcasecmp(vms->vmbox, "vm-Old")){ 09316 if (!cmd) { 09317 snprintf(vms->fn, sizeof(vms->fn), "vm-%ss", vms->curbox); 09318 cmd = ast_play_and_wait(chan, vms->fn); 09319 } 09320 if (!cmd) 09321 cmd = ast_play_and_wait(chan, "vm-messages"); 09322 } else { 09323 if (!cmd) 09324 cmd = ast_play_and_wait(chan, "vm-messages"); 09325 if (!cmd) { 09326 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09327 cmd = ast_play_and_wait(chan, vms->fn); 09328 } 09329 } 09330 } 09331 return cmd; 09332 }
static int vm_browse_messages_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
struct ast_vm_user * | vmu | |||
) | [static] |
Definition at line 9335 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::fn, vm_state::lastmsg, and play_message().
09336 { 09337 int cmd = 0; 09338 09339 if (vms->lastmsg > -1) { 09340 cmd = play_message(chan, vmu, vms); 09341 } else { 09342 if (!strcasecmp(vms->fn, "INBOX")) { 09343 cmd = ast_play_and_wait(chan, "vm-nonewmessages"); 09344 } else { 09345 cmd = ast_play_and_wait(chan, "vm-nomessages"); 09346 } 09347 } 09348 return cmd; 09349 }
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 9387 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09388 { 09389 int cmd; 09390 09391 if (vms->lastmsg > -1) { 09392 cmd = play_message(chan, vmu, vms); 09393 } else { 09394 cmd = ast_play_and_wait(chan, "vm-no"); 09395 if (!cmd) 09396 cmd = ast_play_and_wait(chan, "vm-message"); 09397 if (!cmd) { 09398 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09399 cmd = ast_play_and_wait(chan, vms->fn); 09400 } 09401 } 09402 return cmd; 09403 }
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 9439 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09440 { 09441 int cmd; 09442 09443 if (vms->lastmsg > -1) { 09444 cmd = play_message(chan, vmu, vms); 09445 } else { 09446 cmd = ast_play_and_wait(chan, "vm-no"); 09447 if (!cmd) { 09448 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09449 cmd = ast_play_and_wait(chan, vms->fn); 09450 } 09451 if (!cmd) 09452 cmd = ast_play_and_wait(chan, "vm-messages"); 09453 } 09454 return cmd; 09455 }
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 9493 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09494 { 09495 int cmd = 0; 09496 09497 if (vms->lastmsg > -1) { 09498 cmd = play_message(chan, vmu, vms); 09499 } else { 09500 cmd = ast_play_and_wait(chan, "vm-no"); 09501 if (!cmd) { 09502 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09503 cmd = ast_play_and_wait(chan, vms->fn); 09504 } 09505 } 09506 return cmd; 09507 }
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 9465 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), vm_state::curbox, vm_state::fn, vm_state::lastmsg, and play_message().
09466 { 09467 int cmd; 09468 09469 if (vms->lastmsg > -1) { 09470 cmd = play_message(chan, vmu, vms); 09471 } else { 09472 cmd = ast_play_and_wait(chan, "vm-you"); 09473 if (!cmd) 09474 cmd = ast_play_and_wait(chan, "vm-haveno"); 09475 if (!cmd) 09476 cmd = ast_play_and_wait(chan, "vm-messages"); 09477 if (!cmd) { 09478 snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox); 09479 cmd = ast_play_and_wait(chan, vms->fn); 09480 } 09481 } 09482 return cmd; 09483 }
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 1439 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_variable_append(), ast_variable_new(), ast_variable_retrieve(), ast_variable_update(), ast_verb, change_password_realtime(), CONFIG_FLAG_WITHCOMMENTS, config_flags, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::password, ast_vm_user::passwordlocation, reset_user_pw(), value, var, VOICEMAIL_CONFIG, and write_password_to_file().
01440 { 01441 struct ast_config *cfg = NULL; 01442 struct ast_variable *var = NULL; 01443 struct ast_category *cat = NULL; 01444 char *category = NULL, *value = NULL, *new = NULL; 01445 const char *tmp = NULL; 01446 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }; 01447 char secretfn[PATH_MAX] = ""; 01448 int found = 0; 01449 01450 if (!change_password_realtime(vmu, newpassword)) 01451 return; 01452 01453 /* check if we should store the secret in the spool directory next to the messages */ 01454 switch (vmu->passwordlocation) { 01455 case OPT_PWLOC_SPOOLDIR: 01456 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 01457 if (write_password_to_file(secretfn, newpassword) == 0) { 01458 ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn); 01459 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01460 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01461 break; 01462 } else { 01463 ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn); 01464 } 01465 /* Fall-through */ 01466 case OPT_PWLOC_VOICEMAILCONF: 01467 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01468 while ((category = ast_category_browse(cfg, category))) { 01469 if (!strcasecmp(category, vmu->context)) { 01470 if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) { 01471 ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n"); 01472 break; 01473 } 01474 value = strstr(tmp, ","); 01475 if (!value) { 01476 new = alloca(strlen(newpassword)+1); 01477 sprintf(new, "%s", newpassword); 01478 } else { 01479 new = alloca((strlen(value) + strlen(newpassword) + 1)); 01480 sprintf(new, "%s%s", newpassword, value); 01481 } 01482 if (!(cat = ast_category_get(cfg, category))) { 01483 ast_log(AST_LOG_WARNING, "Failed to get category structure.\n"); 01484 break; 01485 } 01486 ast_variable_update(cat, vmu->mailbox, new, NULL, 0); 01487 found = 1; 01488 } 01489 } 01490 /* save the results */ 01491 if (found) { 01492 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01493 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01494 ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail"); 01495 break; 01496 } 01497 } 01498 /* Fall-through */ 01499 case OPT_PWLOC_USERSCONF: 01500 /* check users.conf and update the password stored for the mailbox */ 01501 /* if no vmsecret entry exists create one. */ 01502 if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) { 01503 ast_debug(4, "we are looking for %s\n", vmu->mailbox); 01504 for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) { 01505 ast_debug(4, "users.conf: %s\n", category); 01506 if (!strcasecmp(category, vmu->mailbox)) { 01507 if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) { 01508 ast_debug(3, "looks like we need to make vmsecret!\n"); 01509 var = ast_variable_new("vmsecret", newpassword, ""); 01510 } else { 01511 var = NULL; 01512 } 01513 new = alloca(strlen(newpassword) + 1); 01514 sprintf(new, "%s", newpassword); 01515 if (!(cat = ast_category_get(cfg, category))) { 01516 ast_debug(4, "failed to get category!\n"); 01517 ast_free(var); 01518 break; 01519 } 01520 if (!var) { 01521 ast_variable_update(cat, "vmsecret", new, NULL, 0); 01522 } else { 01523 ast_variable_append(cat, var); 01524 } 01525 found = 1; 01526 break; 01527 } 01528 } 01529 /* save the results and clean things up */ 01530 if (found) { 01531 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01532 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01533 ast_config_text_file_save("users.conf", cfg, "AppVoicemail"); 01534 } 01535 } 01536 } 01537 }
static void vm_change_password_shell | ( | struct ast_vm_user * | vmu, | |
char * | newpassword | |||
) | [static] |
Definition at line 1539 of file app_voicemail_imapstorage.c.
References ast_copy_string(), ast_safe_system(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and reset_user_pw().
01540 { 01541 char buf[255]; 01542 snprintf(buf, sizeof(buf), "%s %s %s %s", ext_pass_cmd, vmu->context, vmu->mailbox, newpassword); 01543 if (!ast_safe_system(buf)) { 01544 ast_copy_string(vmu->password, newpassword, sizeof(vmu->password)); 01545 /* Reset the password in memory, too */ 01546 reset_user_pw(vmu->context, vmu->mailbox, newpassword); 01547 } 01548 }
static char* vm_check_password_shell | ( | char * | command, | |
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 1130 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.
01131 { 01132 int fds[2], pid = 0; 01133 01134 memset(buf, 0, len); 01135 01136 if (pipe(fds)) { 01137 snprintf(buf, len, "FAILURE: Pipe failed: %s", strerror(errno)); 01138 } else { 01139 /* good to go*/ 01140 pid = ast_safe_fork(0); 01141 01142 if (pid < 0) { 01143 /* ok maybe not */ 01144 close(fds[0]); 01145 close(fds[1]); 01146 snprintf(buf, len, "FAILURE: Fork failed"); 01147 } else if (pid) { 01148 /* parent */ 01149 close(fds[1]); 01150 if (read(fds[0], buf, len) < 0) { 01151 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 01152 } 01153 close(fds[0]); 01154 } else { 01155 /* child */ 01156 AST_DECLARE_APP_ARGS(arg, 01157 AST_APP_ARG(v)[20]; 01158 ); 01159 char *mycmd = ast_strdupa(command); 01160 01161 close(fds[0]); 01162 dup2(fds[1], STDOUT_FILENO); 01163 close(fds[1]); 01164 ast_close_fds_above_n(STDOUT_FILENO); 01165 01166 AST_NONSTANDARD_APP_ARGS(arg, mycmd, ' '); 01167 01168 execv(arg.v[0], arg.v); 01169 printf("FAILURE: %s", strerror(errno)); 01170 _exit(0); 01171 } 01172 } 01173 return buf; 01174 }
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 4056 of file app_voicemail_imapstorage.c.
References ast_check_realtime(), ast_destroy_realtime(), ast_filedelete(), and SENTINEL.
04057 { 04058 char *txt; 04059 int txtsize = 0; 04060 04061 txtsize = (strlen(file) + 5)*sizeof(char); 04062 txt = alloca(txtsize); 04063 /* Sprintf here would safe because we alloca'd exactly the right length, 04064 * but trying to eliminate all sprintf's anyhow 04065 */ 04066 if (ast_check_realtime("voicemail_data")) { 04067 ast_destroy_realtime("voicemail_data", "filename", file, SENTINEL); 04068 } 04069 snprintf(txt, txtsize, "%s.txt", file); 04070 unlink(txt); 04071 return ast_filedelete(file, NULL); 04072 }
static int vm_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10387 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.
10388 { 10389 int res = 0; 10390 char *tmp; 10391 struct leave_vm_options leave_options; 10392 struct ast_flags flags = { 0 }; 10393 char *opts[OPT_ARG_ARRAY_SIZE]; 10394 AST_DECLARE_APP_ARGS(args, 10395 AST_APP_ARG(argv0); 10396 AST_APP_ARG(argv1); 10397 ); 10398 10399 memset(&leave_options, 0, sizeof(leave_options)); 10400 10401 if (chan->_state != AST_STATE_UP) 10402 ast_answer(chan); 10403 10404 if (!ast_strlen_zero(data)) { 10405 tmp = ast_strdupa(data); 10406 AST_STANDARD_APP_ARGS(args, tmp); 10407 if (args.argc == 2) { 10408 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 10409 return -1; 10410 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING | OPT_MESSAGE_Urgent | OPT_MESSAGE_PRIORITY | OPT_DTMFEXIT); 10411 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 10412 int gain; 10413 10414 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 10415 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 10416 return -1; 10417 } else { 10418 leave_options.record_gain = (signed char) gain; 10419 } 10420 } 10421 if (ast_test_flag(&flags, OPT_DTMFEXIT)) { 10422 if (!ast_strlen_zero(opts[OPT_ARG_DTMFEXIT])) 10423 leave_options.exitcontext = opts[OPT_ARG_DTMFEXIT]; 10424 } 10425 } 10426 } else { 10427 char temp[256]; 10428 res = ast_app_getdata(chan, "vm-whichbox", temp, sizeof(temp) - 1, 0); 10429 if (res < 0) 10430 return res; 10431 if (ast_strlen_zero(temp)) 10432 return 0; 10433 args.argv0 = ast_strdupa(temp); 10434 } 10435 10436 res = leave_voicemail(chan, args.argv0, &leave_options); 10437 if (res == 't') { 10438 ast_play_and_wait(chan, "vm-goodbye"); 10439 res = 0; 10440 } 10441 10442 if (res == OPERATOR_EXIT) { 10443 res = 0; 10444 } 10445 10446 if (res == ERROR_LOCK_PATH) { 10447 ast_log(AST_LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 10448 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 10449 res = 0; 10450 } 10451 10452 return res; 10453 }
static int vm_execmain | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 9657 of file app_voicemail_imapstorage.c.
References ast_channel::_state, adsi_begin(), adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_message(), adsi_status(), adsi_status2(), advanced_options(), args, ast_adsi_unload_session(), ast_answer(), AST_APP_ARG, ast_app_inboxcount2(), ast_app_parse_options(), ast_calloc, ast_copy_string(), ast_debug, AST_DECLARE_APP_ARGS, ast_free, ast_goto_if_exists(), ast_log(), AST_LOG_ERROR, ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_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(), 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, and VM_SVMAIL.
09658 { 09659 /* XXX This is, admittedly, some pretty horrendous code. For some 09660 reason it just seemed a lot easier to do with GOTO's. I feel 09661 like I'm back in my GWBASIC days. XXX */ 09662 int res = -1; 09663 int cmd = 0; 09664 int valid = 0; 09665 char prefixstr[80] =""; 09666 char ext_context[256]=""; 09667 int box; 09668 int useadsi = 0; 09669 int skipuser = 0; 09670 struct vm_state vms; 09671 struct ast_vm_user *vmu = NULL, vmus; 09672 char *context = NULL; 09673 int silentexit = 0; 09674 struct ast_flags flags = { 0 }; 09675 signed char record_gain = 0; 09676 int play_auto = 0; 09677 int play_folder = 0; 09678 int in_urgent = 0; 09679 #ifdef IMAP_STORAGE 09680 int deleted = 0; 09681 #endif 09682 09683 /* Add the vm_state to the active list and keep it active */ 09684 memset(&vms, 0, sizeof(vms)); 09685 09686 vms.lastmsg = -1; 09687 09688 memset(&vmus, 0, sizeof(vmus)); 09689 09690 if (chan->_state != AST_STATE_UP) { 09691 ast_debug(1, "Before ast_answer\n"); 09692 ast_answer(chan); 09693 } 09694 09695 if (!ast_strlen_zero(data)) { 09696 char *opts[OPT_ARG_ARRAY_SIZE]; 09697 char *parse; 09698 AST_DECLARE_APP_ARGS(args, 09699 AST_APP_ARG(argv0); 09700 AST_APP_ARG(argv1); 09701 ); 09702 09703 parse = ast_strdupa(data); 09704 09705 AST_STANDARD_APP_ARGS(args, parse); 09706 09707 if (args.argc == 2) { 09708 if (ast_app_parse_options(vm_app_options, &flags, opts, args.argv1)) 09709 return -1; 09710 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 09711 int gain; 09712 if (!ast_strlen_zero(opts[OPT_ARG_RECORDGAIN])) { 09713 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 09714 ast_log(AST_LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 09715 return -1; 09716 } else { 09717 record_gain = (signed char) gain; 09718 } 09719 } else { 09720 ast_log(AST_LOG_WARNING, "Invalid Gain level set with option g\n"); 09721 } 09722 } 09723 if (ast_test_flag(&flags, OPT_AUTOPLAY) ) { 09724 play_auto = 1; 09725 if (!ast_strlen_zero(opts[OPT_ARG_PLAYFOLDER])) { 09726 /* See if it is a folder name first */ 09727 if (isdigit(opts[OPT_ARG_PLAYFOLDER][0])) { 09728 if (sscanf(opts[OPT_ARG_PLAYFOLDER], "%30d", &play_folder) != 1) { 09729 play_folder = -1; 09730 } 09731 } else { 09732 play_folder = get_folder_by_name(opts[OPT_ARG_PLAYFOLDER]); 09733 } 09734 } else { 09735 ast_log(AST_LOG_WARNING, "Invalid folder set with option a\n"); 09736 } 09737 if (play_folder > 9 || play_folder < 0) { 09738 ast_log(AST_LOG_WARNING, 09739 "Invalid value '%s' provided for folder autoplay option. Defaulting to 'INBOX'\n", 09740 opts[OPT_ARG_PLAYFOLDER]); 09741 play_folder = 0; 09742 } 09743 } 09744 } else { 09745 /* old style options parsing */ 09746 while (*(args.argv0)) { 09747 if (*(args.argv0) == 's') 09748 ast_set_flag(&flags, OPT_SILENT); 09749 else if (*(args.argv0) == 'p') 09750 ast_set_flag(&flags, OPT_PREPEND_MAILBOX); 09751 else 09752 break; 09753 (args.argv0)++; 09754 } 09755 09756 } 09757 09758 valid = ast_test_flag(&flags, OPT_SILENT); 09759 09760 if ((context = strchr(args.argv0, '@'))) 09761 *context++ = '\0'; 09762 09763 if (ast_test_flag(&flags, OPT_PREPEND_MAILBOX)) 09764 ast_copy_string(prefixstr, args.argv0, sizeof(prefixstr)); 09765 else 09766 ast_copy_string(vms.username, args.argv0, sizeof(vms.username)); 09767 09768 if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username))) 09769 skipuser++; 09770 else 09771 valid = 0; 09772 } 09773 09774 if (!valid) 09775 res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins, 0); 09776 09777 ast_debug(1, "After vm_authenticate\n"); 09778 09779 if (vms.username[0] == '*') { 09780 ast_debug(1, "user pressed * in context '%s'\n", chan->context); 09781 09782 /* user entered '*' */ 09783 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 09784 res = 0; /* prevent hangup */ 09785 goto out; 09786 } 09787 } 09788 09789 if (!res) { 09790 valid = 1; 09791 if (!skipuser) 09792 vmu = &vmus; 09793 } else { 09794 res = 0; 09795 } 09796 09797 /* If ADSI is supported, setup login screen */ 09798 adsi_begin(chan, &useadsi); 09799 09800 if (!valid) { 09801 goto out; 09802 } 09803 09804 #ifdef IMAP_STORAGE 09805 pthread_once(&ts_vmstate.once, ts_vmstate.key_init); 09806 pthread_setspecific(ts_vmstate.key, &vms); 09807 09808 vms.interactive = 1; 09809 vms.updated = 1; 09810 if (vmu) 09811 ast_copy_string(vms.context, vmu->context, sizeof(vms.context)); 09812 vmstate_insert(&vms); 09813 init_vm_state(&vms); 09814 #endif 09815 /* Avoid allocating a buffer of 0 bytes, because some platforms really don't like that. */ 09816 if (!(vms.deleted = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09817 ast_log(AST_LOG_ERROR, "Could not allocate memory for deleted message storage!\n"); 09818 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09819 return -1; 09820 } 09821 if (!(vms.heard = ast_calloc(vmu->maxmsg ? vmu->maxmsg : 1, sizeof(int)))) { 09822 ast_log(AST_LOG_ERROR, "Could not allocate memory for heard message storage!\n"); 09823 cmd = ast_play_and_wait(chan, "an-error-has-occured"); 09824 return -1; 09825 } 09826 09827 /* Set language from config to override channel language */ 09828 if (!ast_strlen_zero(vmu->language)) 09829 ast_string_field_set(chan, language, vmu->language); 09830 09831 /* Retrieve urgent, old and new message counts */ 09832 ast_debug(1, "Before open_mailbox\n"); 09833 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09834 if (res < 0) 09835 goto out; 09836 vms.oldmessages = vms.lastmsg + 1; 09837 ast_debug(1, "Number of old messages: %d\n", vms.oldmessages); 09838 /* check INBOX */ 09839 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09840 if (res < 0) 09841 goto out; 09842 vms.newmessages = vms.lastmsg + 1; 09843 ast_debug(1, "Number of new messages: %d\n", vms.newmessages); 09844 /* Start in Urgent */ 09845 in_urgent = 1; 09846 res = open_mailbox(&vms, vmu, 11); /*11 is the Urgent folder */ 09847 if (res < 0) 09848 goto out; 09849 vms.urgentmessages = vms.lastmsg + 1; 09850 ast_debug(1, "Number of urgent messages: %d\n", vms.urgentmessages); 09851 09852 /* Select proper mailbox FIRST!! */ 09853 if (play_auto) { 09854 if (vms.urgentmessages) { 09855 in_urgent = 1; 09856 res = open_mailbox(&vms, vmu, 11); 09857 } else { 09858 in_urgent = 0; 09859 res = open_mailbox(&vms, vmu, play_folder); 09860 } 09861 if (res < 0) 09862 goto out; 09863 09864 /* If there are no new messages, inform the user and hangup */ 09865 if (vms.lastmsg == -1) { 09866 in_urgent = 0; 09867 cmd = vm_browse_messages(chan, &vms, vmu); 09868 res = 0; 09869 goto out; 09870 } 09871 } else { 09872 if (!vms.newmessages && !vms.urgentmessages && vms.oldmessages) { 09873 /* If we only have old messages start here */ 09874 res = open_mailbox(&vms, vmu, OLD_FOLDER); /* Count all messages, even Urgent */ 09875 in_urgent = 0; 09876 play_folder = 1; 09877 if (res < 0) 09878 goto out; 09879 } else if (!vms.urgentmessages && vms.newmessages) { 09880 /* If we have new messages but none are urgent */ 09881 in_urgent = 0; 09882 res = open_mailbox(&vms, vmu, NEW_FOLDER); 09883 if (res < 0) 09884 goto out; 09885 } 09886 } 09887 09888 if (useadsi) 09889 adsi_status(chan, &vms); 09890 res = 0; 09891 09892 /* Check to see if this is a new user */ 09893 if (!strcasecmp(vmu->mailbox, vmu->password) && 09894 (ast_test_flag(vmu, VM_FORCENAME | VM_FORCEGREET))) { 09895 if (ast_play_and_wait(chan, "vm-newuser") == -1) 09896 ast_log(AST_LOG_WARNING, "Couldn't stream new user file\n"); 09897 cmd = vm_newuser(chan, vmu, &vms, vmfmts, record_gain); 09898 if ((cmd == 't') || (cmd == '#')) { 09899 /* Timeout */ 09900 res = 0; 09901 goto out; 09902 } else if (cmd < 0) { 09903 /* Hangup */ 09904 res = -1; 09905 goto out; 09906 } 09907 } 09908 #ifdef IMAP_STORAGE 09909 ast_debug(3, "Checking quotas: comparing %u to %u\n", vms.quota_usage, vms.quota_limit); 09910 if (vms.quota_limit && vms.quota_usage >= vms.quota_limit) { 09911 ast_debug(1, "*** QUOTA EXCEEDED!!\n"); 09912 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09913 } 09914 ast_debug(3, "Checking quotas: User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09915 if ((vms.newmessages + vms.oldmessages) >= vmu->maxmsg) { 09916 ast_log(AST_LOG_WARNING, "No more messages possible. User has %d messages and limit is %d.\n", (vms.newmessages + vms.oldmessages), vmu->maxmsg); 09917 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 09918 } 09919 #endif 09920 if (play_auto) { 09921 cmd = '1'; 09922 } else { 09923 cmd = vm_intro(chan, vmu, &vms); 09924 } 09925 09926 vms.repeats = 0; 09927 vms.starting = 1; 09928 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09929 /* Run main menu */ 09930 switch (cmd) { 09931 case '1': /* First message */ 09932 vms.curmsg = 0; 09933 /* Fall through */ 09934 case '5': /* Play current message */ 09935 cmd = vm_browse_messages(chan, &vms, vmu); 09936 break; 09937 case '2': /* Change folders */ 09938 if (useadsi) 09939 adsi_folders(chan, 0, "Change to folder..."); 09940 cmd = get_folder2(chan, "vm-changeto", 0); 09941 if (cmd == '#') { 09942 cmd = 0; 09943 } else if (cmd > 0) { 09944 cmd = cmd - '0'; 09945 res = close_mailbox(&vms, vmu); 09946 if (res == ERROR_LOCK_PATH) 09947 goto out; 09948 /* If folder is not urgent, set in_urgent to zero! */ 09949 if (cmd != 11) in_urgent = 0; 09950 res = open_mailbox(&vms, vmu, cmd); 09951 if (res < 0) 09952 goto out; 09953 play_folder = cmd; 09954 cmd = 0; 09955 } 09956 if (useadsi) 09957 adsi_status2(chan, &vms); 09958 09959 if (!cmd) 09960 cmd = vm_play_folder_name(chan, vms.vmbox); 09961 09962 vms.starting = 1; 09963 break; 09964 case '3': /* Advanced options */ 09965 cmd = 0; 09966 vms.repeats = 0; 09967 while ((cmd > -1) && (cmd != 't') && (cmd != '#')) { 09968 switch (cmd) { 09969 case '1': /* Reply */ 09970 if (vms.lastmsg > -1 && !vms.starting) { 09971 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 1, record_gain); 09972 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 09973 res = cmd; 09974 goto out; 09975 } 09976 } else 09977 cmd = ast_play_and_wait(chan, "vm-sorry"); 09978 cmd = 't'; 09979 break; 09980 case '2': /* Callback */ 09981 if (!vms.starting) 09982 ast_verb(3, "Callback Requested\n"); 09983 if (!ast_strlen_zero(vmu->callback) && vms.lastmsg > -1 && !vms.starting) { 09984 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 2, record_gain); 09985 if (cmd == 9) { 09986 silentexit = 1; 09987 goto out; 09988 } else if (cmd == ERROR_LOCK_PATH) { 09989 res = cmd; 09990 goto out; 09991 } 09992 } else 09993 cmd = ast_play_and_wait(chan, "vm-sorry"); 09994 cmd = 't'; 09995 break; 09996 case '3': /* Envelope */ 09997 if (vms.lastmsg > -1 && !vms.starting) { 09998 cmd = advanced_options(chan, vmu, &vms, vms.curmsg, 3, record_gain); 09999 if (cmd == ERROR_LOCK_PATH) { 10000 res = cmd; 10001 goto out; 10002 } 10003 } else 10004 cmd = ast_play_and_wait(chan, "vm-sorry"); 10005 cmd = 't'; 10006 break; 10007 case '4': /* Dialout */ 10008 if (!ast_strlen_zero(vmu->dialout)) { 10009 cmd = dialout(chan, vmu, NULL, vmu->dialout); 10010 if (cmd == 9) { 10011 silentexit = 1; 10012 goto out; 10013 } 10014 } else 10015 cmd = ast_play_and_wait(chan, "vm-sorry"); 10016 cmd = 't'; 10017 break; 10018 10019 case '5': /* Leave VoiceMail */ 10020 if (ast_test_flag(vmu, VM_SVMAIL)) { 10021 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain, 0); 10022 if (cmd == ERROR_LOCK_PATH || cmd == OPERATOR_EXIT) { 10023 res = cmd; 10024 goto out; 10025 } 10026 } else 10027 cmd = ast_play_and_wait(chan, "vm-sorry"); 10028 cmd = 't'; 10029 break; 10030 10031 case '*': /* Return to main menu */ 10032 cmd = 't'; 10033 break; 10034 10035 default: 10036 cmd = 0; 10037 if (!vms.starting) { 10038 cmd = ast_play_and_wait(chan, "vm-toreply"); 10039 } 10040 if (!ast_strlen_zero(vmu->callback) && !vms.starting && !cmd) { 10041 cmd = ast_play_and_wait(chan, "vm-tocallback"); 10042 } 10043 if (!cmd && !vms.starting) { 10044 cmd = ast_play_and_wait(chan, "vm-tohearenv"); 10045 } 10046 if (!ast_strlen_zero(vmu->dialout) && !cmd) { 10047 cmd = ast_play_and_wait(chan, "vm-tomakecall"); 10048 } 10049 if (ast_test_flag(vmu, VM_SVMAIL) && !cmd) 10050 cmd = ast_play_and_wait(chan, "vm-leavemsg"); 10051 if (!cmd) 10052 cmd = ast_play_and_wait(chan, "vm-starmain"); 10053 if (!cmd) 10054 cmd = ast_waitfordigit(chan, 6000); 10055 if (!cmd) 10056 vms.repeats++; 10057 if (vms.repeats > 3) 10058 cmd = 't'; 10059 } 10060 } 10061 if (cmd == 't') { 10062 cmd = 0; 10063 vms.repeats = 0; 10064 } 10065 break; 10066 case '4': /* Go to the previous message */ 10067 if (vms.curmsg > 0) { 10068 vms.curmsg--; 10069 cmd = play_message(chan, vmu, &vms); 10070 } else { 10071 /* Check if we were listening to new 10072 messages. If so, go to Urgent messages 10073 instead of saying "no more messages" 10074 */ 10075 if (in_urgent == 0 && vms.urgentmessages > 0) { 10076 /* Check for Urgent messages */ 10077 in_urgent = 1; 10078 res = close_mailbox(&vms, vmu); 10079 if (res == ERROR_LOCK_PATH) 10080 goto out; 10081 res = open_mailbox(&vms, vmu, 11); /* Open Urgent folder */ 10082 if (res < 0) 10083 goto out; 10084 ast_debug(1, "No more new messages, opened INBOX and got %d Urgent messages\n", vms.lastmsg + 1); 10085 vms.curmsg = vms.lastmsg; 10086 if (vms.lastmsg < 0) 10087 cmd = ast_play_and_wait(chan, "vm-nomore"); 10088 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10089 vms.curmsg = vms.lastmsg; 10090 cmd = play_message(chan, vmu, &vms); 10091 } else { 10092 cmd = ast_play_and_wait(chan, "vm-nomore"); 10093 } 10094 } 10095 break; 10096 case '6': /* Go to the next message */ 10097 if (vms.curmsg < vms.lastmsg) { 10098 vms.curmsg++; 10099 cmd = play_message(chan, vmu, &vms); 10100 } else { 10101 if (in_urgent && vms.newmessages > 0) { 10102 /* Check if we were listening to urgent 10103 * messages. If so, go to regular new messages 10104 * instead of saying "no more messages" 10105 */ 10106 in_urgent = 0; 10107 res = close_mailbox(&vms, vmu); 10108 if (res == ERROR_LOCK_PATH) 10109 goto out; 10110 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10111 if (res < 0) 10112 goto out; 10113 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10114 vms.curmsg = -1; 10115 if (vms.lastmsg < 0) { 10116 cmd = ast_play_and_wait(chan, "vm-nomore"); 10117 } 10118 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10119 vms.curmsg = 0; 10120 cmd = play_message(chan, vmu, &vms); 10121 } else { 10122 cmd = ast_play_and_wait(chan, "vm-nomore"); 10123 } 10124 } 10125 break; 10126 case '7': /* Delete the current message */ 10127 if (vms.curmsg >= 0 && vms.curmsg <= vms.lastmsg) { 10128 vms.deleted[vms.curmsg] = !vms.deleted[vms.curmsg]; 10129 if (useadsi) 10130 adsi_delete(chan, &vms); 10131 if (vms.deleted[vms.curmsg]) { 10132 if (play_folder == 0) { 10133 if (in_urgent) { 10134 vms.urgentmessages--; 10135 } else { 10136 vms.newmessages--; 10137 } 10138 } 10139 else if (play_folder == 1) 10140 vms.oldmessages--; 10141 cmd = ast_play_and_wait(chan, "vm-deleted"); 10142 } else { 10143 if (play_folder == 0) { 10144 if (in_urgent) { 10145 vms.urgentmessages++; 10146 } else { 10147 vms.newmessages++; 10148 } 10149 } 10150 else if (play_folder == 1) 10151 vms.oldmessages++; 10152 cmd = ast_play_and_wait(chan, "vm-undeleted"); 10153 } 10154 if (ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 10155 if (vms.curmsg < vms.lastmsg) { 10156 vms.curmsg++; 10157 cmd = play_message(chan, vmu, &vms); 10158 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10159 vms.curmsg = 0; 10160 cmd = play_message(chan, vmu, &vms); 10161 } else { 10162 /* Check if we were listening to urgent 10163 messages. If so, go to regular new messages 10164 instead of saying "no more messages" 10165 */ 10166 if (in_urgent == 1) { 10167 /* Check for new messages */ 10168 in_urgent = 0; 10169 res = close_mailbox(&vms, vmu); 10170 if (res == ERROR_LOCK_PATH) 10171 goto out; 10172 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10173 if (res < 0) 10174 goto out; 10175 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10176 vms.curmsg = -1; 10177 if (vms.lastmsg < 0) 10178 cmd = ast_play_and_wait(chan, "vm-nomore"); 10179 } else { 10180 cmd = ast_play_and_wait(chan, "vm-nomore"); 10181 } 10182 } 10183 } 10184 } else /* Delete not valid if we haven't selected a message */ 10185 cmd = 0; 10186 #ifdef IMAP_STORAGE 10187 deleted = 1; 10188 #endif 10189 break; 10190 10191 case '8': /* Forward the current messgae */ 10192 if (vms.lastmsg > -1) { 10193 cmd = forward_message(chan, context, &vms, vmu, vmfmts, 0, record_gain, in_urgent); 10194 if (cmd == ERROR_LOCK_PATH) { 10195 res = cmd; 10196 goto out; 10197 } 10198 } else { 10199 /* Check if we were listening to urgent 10200 messages. If so, go to regular new messages 10201 instead of saying "no more messages" 10202 */ 10203 if (in_urgent == 1 && vms.newmessages > 0) { 10204 /* Check for new messages */ 10205 in_urgent = 0; 10206 res = close_mailbox(&vms, vmu); 10207 if (res == ERROR_LOCK_PATH) 10208 goto out; 10209 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10210 if (res < 0) 10211 goto out; 10212 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10213 vms.curmsg = -1; 10214 if (vms.lastmsg < 0) 10215 cmd = ast_play_and_wait(chan, "vm-nomore"); 10216 } else { 10217 cmd = ast_play_and_wait(chan, "vm-nomore"); 10218 } 10219 } 10220 break; 10221 case '9': /* Save message to folder */ 10222 if (vms.curmsg < 0 || vms.curmsg > vms.lastmsg) { 10223 /* No message selected */ 10224 cmd = 0; 10225 break; 10226 } 10227 if (useadsi) 10228 adsi_folders(chan, 1, "Save to folder..."); 10229 cmd = get_folder2(chan, "vm-savefolder", 1); 10230 box = 0; /* Shut up compiler */ 10231 if (cmd == '#') { 10232 cmd = 0; 10233 break; 10234 } else if (cmd > 0) { 10235 box = cmd = cmd - '0'; 10236 cmd = save_to_folder(vmu, &vms, vms.curmsg, cmd); 10237 if (cmd == ERROR_LOCK_PATH) { 10238 res = cmd; 10239 goto out; 10240 #ifndef IMAP_STORAGE 10241 } else if (!cmd) { 10242 vms.deleted[vms.curmsg] = 1; 10243 #endif 10244 } else { 10245 vms.deleted[vms.curmsg] = 0; 10246 vms.heard[vms.curmsg] = 0; 10247 } 10248 } 10249 make_file(vms.fn, sizeof(vms.fn), vms.curdir, vms.curmsg); 10250 if (useadsi) 10251 adsi_message(chan, &vms); 10252 snprintf(vms.fn, sizeof(vms.fn), "vm-%s", mbox(vmu, box)); 10253 if (!cmd) { 10254 cmd = ast_play_and_wait(chan, "vm-message"); 10255 if (!cmd) 10256 cmd = say_and_wait(chan, vms.curmsg + 1, chan->language); 10257 if (!cmd) 10258 cmd = ast_play_and_wait(chan, "vm-savedto"); 10259 if (!cmd) 10260 cmd = vm_play_folder_name(chan, vms.fn); 10261 } else { 10262 cmd = ast_play_and_wait(chan, "vm-mailboxfull"); 10263 } 10264 if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) { 10265 if (vms.curmsg < vms.lastmsg) { 10266 vms.curmsg++; 10267 cmd = play_message(chan, vmu, &vms); 10268 } else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms.lastmsg > 0) { 10269 vms.curmsg = 0; 10270 cmd = play_message(chan, vmu, &vms); 10271 } else { 10272 /* Check if we were listening to urgent 10273 messages. If so, go to regular new messages 10274 instead of saying "no more messages" 10275 */ 10276 if (in_urgent == 1 && vms.newmessages > 0) { 10277 /* Check for new messages */ 10278 in_urgent = 0; 10279 res = close_mailbox(&vms, vmu); 10280 if (res == ERROR_LOCK_PATH) 10281 goto out; 10282 res = open_mailbox(&vms, vmu, NEW_FOLDER); 10283 if (res < 0) 10284 goto out; 10285 ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms.lastmsg + 1); 10286 vms.curmsg = -1; 10287 if (vms.lastmsg < 0) 10288 cmd = ast_play_and_wait(chan, "vm-nomore"); 10289 } else { 10290 cmd = ast_play_and_wait(chan, "vm-nomore"); 10291 } 10292 } 10293 } 10294 break; 10295 case '*': /* Help */ 10296 if (!vms.starting) { 10297 cmd = ast_play_and_wait(chan, "vm-onefor"); 10298 if (!strncasecmp(chan->language, "he", 2)) { 10299 cmd = ast_play_and_wait(chan, "vm-for"); 10300 } 10301 if (!cmd) 10302 cmd = vm_play_folder_name(chan, vms.vmbox); 10303 if (!cmd) 10304 cmd = ast_play_and_wait(chan, "vm-opts"); 10305 if (!cmd) 10306 cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent); 10307 } else 10308 cmd = 0; 10309 break; 10310 case '0': /* Mailbox options */ 10311 cmd = vm_options(chan, vmu, &vms, vmfmts, record_gain); 10312 if (useadsi) 10313 adsi_status(chan, &vms); 10314 break; 10315 default: /* Nothing */ 10316 cmd = vm_instructions(chan, vmu, &vms, 0, in_urgent); 10317 break; 10318 } 10319 } 10320 if ((cmd == 't') || (cmd == '#')) { 10321 /* Timeout */ 10322 res = 0; 10323 } else { 10324 /* Hangup */ 10325 res = -1; 10326 } 10327 10328 out: 10329 if (res > -1) { 10330 ast_stopstream(chan); 10331 adsi_goodbye(chan); 10332 if (valid && res != OPERATOR_EXIT) { 10333 if (silentexit) 10334 res = ast_play_and_wait(chan, "vm-dialout"); 10335 else 10336 res = ast_play_and_wait(chan, "vm-goodbye"); 10337 } 10338 if ((valid && res > 0) || res == OPERATOR_EXIT) { 10339 res = 0; 10340 } 10341 if (useadsi) 10342 ast_adsi_unload_session(chan); 10343 } 10344 if (vmu) 10345 close_mailbox(&vms, vmu); 10346 if (valid) { 10347 int new = 0, old = 0, urgent = 0; 10348 snprintf(ext_context, sizeof(ext_context), "%s@%s", vms.username, vmu->context); 10349 ast_manager_event(chan, EVENT_FLAG_CALL, "MessageWaiting", "Mailbox: %s\r\nWaiting: %d\r\n", ext_context, has_voicemail(ext_context, NULL)); 10350 /* Urgent flag not passwd to externnotify here */ 10351 run_externnotify(vmu->context, vmu->mailbox, NULL); 10352 ast_app_inboxcount2(ext_context, &urgent, &new, &old); 10353 queue_mwi_event(ext_context, urgent, new, old); 10354 } 10355 #ifdef IMAP_STORAGE 10356 /* expunge message - use UID Expunge if supported on IMAP server*/ 10357 ast_debug(3, "*** Checking if we can expunge, deleted set to %d, expungeonhangup set to %d\n", deleted, expungeonhangup); 10358 if (vmu && deleted == 1 && expungeonhangup == 1 && vms.mailstream != NULL) { 10359 ast_mutex_lock(&vms.lock); 10360 #ifdef HAVE_IMAP_TK2006 10361 if (LEVELUIDPLUS (vms.mailstream)) { 10362 mail_expunge_full(vms.mailstream, NIL, EX_UID); 10363 } else 10364 #endif 10365 mail_expunge(vms.mailstream); 10366 ast_mutex_unlock(&vms.lock); 10367 } 10368 /* before we delete the state, we should copy pertinent info 10369 * back to the persistent model */ 10370 if (vmu) { 10371 vmstate_delete(&vms); 10372 } 10373 #endif 10374 if (vmu) 10375 free_user(vmu); 10376 if (vms.deleted) 10377 ast_free(vms.deleted); 10378 if (vms.heard) 10379 ast_free(vms.heard); 10380 10381 #ifdef IMAP_STORAGE 10382 pthread_setspecific(ts_vmstate.key, NULL); 10383 #endif 10384 return res; 10385 }
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 6694 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_variable_retrieve(), ast_variable_update(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, config_flags, CONFIG_STATUS_FILEINVALID, copy(), INTRO, make_file(), ast_vm_user::maxsecs, and play_record_review().
06696 { 06697 #ifdef IMAP_STORAGE 06698 int res; 06699 #endif 06700 int cmd = 0; 06701 int retries = 0, prepend_duration = 0, already_recorded = 0; 06702 char msgfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 06703 char textfile[PATH_MAX]; 06704 struct ast_config *msg_cfg; 06705 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 06706 #ifndef IMAP_STORAGE 06707 signed char zero_gain = 0; 06708 #endif 06709 const char *duration_str; 06710 06711 /* Must always populate duration correctly */ 06712 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06713 strcpy(textfile, msgfile); 06714 strcpy(backup, msgfile); 06715 strcpy(backup_textfile, msgfile); 06716 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 06717 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 06718 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 06719 06720 if ((msg_cfg = ast_config_load(textfile, config_flags)) && msg_cfg != CONFIG_STATUS_FILEINVALID && (duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) { 06721 *duration = atoi(duration_str); 06722 } else { 06723 *duration = 0; 06724 } 06725 06726 while ((cmd >= 0) && (cmd != 't') && (cmd != '*')) { 06727 if (cmd) 06728 retries = 0; 06729 switch (cmd) { 06730 case '1': 06731 06732 #ifdef IMAP_STORAGE 06733 /* Record new intro file */ 06734 make_file(vms->introfn, sizeof(vms->introfn), curdir, curmsg); 06735 strncat(vms->introfn, "intro", sizeof(vms->introfn)); 06736 res = ast_play_and_wait(chan, INTRO); 06737 res = ast_play_and_wait(chan, "beep"); 06738 res = play_record_review(chan, NULL, vms->introfn, vmu->maxsecs, vm_fmts, 1, vmu, (int *) duration, NULL, record_gain, vms, flag); 06739 cmd = 't'; 06740 #else 06741 06742 /* prepend a message to the current message, update the metadata and return */ 06743 06744 make_file(msgfile, sizeof(msgfile), curdir, curmsg); 06745 strcpy(textfile, msgfile); 06746 strncat(textfile, ".txt", sizeof(textfile) - 1); 06747 *duration = 0; 06748 06749 /* if we can't read the message metadata, stop now */ 06750 if (!msg_cfg) { 06751 cmd = 0; 06752 break; 06753 } 06754 06755 /* Back up the original file, so we can retry the prepend and restore it after forward. */ 06756 #ifndef IMAP_STORAGE 06757 if (already_recorded) { 06758 ast_filecopy(backup, msgfile, NULL); 06759 copy(backup_textfile, textfile); 06760 } 06761 else { 06762 ast_filecopy(msgfile, backup, NULL); 06763 copy(textfile, backup_textfile); 06764 } 06765 #endif 06766 already_recorded = 1; 06767 06768 if (record_gain) 06769 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 06770 06771 cmd = ast_play_and_prepend(chan, NULL, msgfile, 0, vm_fmts, &prepend_duration, 1, silencethreshold, maxsilence); 06772 if (cmd == 'S') { 06773 ast_filerename(backup, msgfile, NULL); 06774 } 06775 06776 if (record_gain) 06777 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 06778 06779 06780 if ((duration_str = ast_variable_retrieve(msg_cfg, "message", "duration"))) 06781 *duration = atoi(duration_str); 06782 06783 if (prepend_duration) { 06784 struct ast_category *msg_cat; 06785 /* need enough space for a maximum-length message duration */ 06786 char duration_buf[12]; 06787 06788 *duration += prepend_duration; 06789 msg_cat = ast_category_get(msg_cfg, "message"); 06790 snprintf(duration_buf, 11, "%ld", *duration); 06791 if (!ast_variable_update(msg_cat, "duration", duration_buf, NULL, 0)) { 06792 ast_config_text_file_save(textfile, msg_cfg, "app_voicemail"); 06793 } 06794 } 06795 06796 #endif 06797 break; 06798 case '2': 06799 /* NULL out introfile so we know there is no intro! */ 06800 #ifdef IMAP_STORAGE 06801 *vms->introfn = '\0'; 06802 #endif 06803 cmd = 't'; 06804 break; 06805 case '*': 06806 cmd = '*'; 06807 break; 06808 default: 06809 cmd = ast_play_and_wait(chan, "vm-forwardoptions"); 06810 /* "Press 1 to prepend a message or 2 to forward the message without prepending" */ 06811 if (!cmd) 06812 cmd = ast_play_and_wait(chan, "vm-starmain"); 06813 /* "press star to return to the main menu" */ 06814 if (!cmd) 06815 cmd = ast_waitfordigit(chan, 6000); 06816 if (!cmd) 06817 retries++; 06818 if (retries > 3) 06819 cmd = 't'; 06820 } 06821 } 06822 06823 if (msg_cfg) 06824 ast_config_destroy(msg_cfg); 06825 if (prepend_duration) 06826 *duration = prepend_duration; 06827 06828 if (already_recorded && cmd == -1) { 06829 /* restore original message if prepention cancelled */ 06830 ast_filerename(backup, msgfile, NULL); 06831 rename(backup_textfile, textfile); 06832 } 06833 06834 if (cmd == 't' || cmd == 'S') 06835 cmd = 0; 06836 return cmd; 06837 }
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 8998 of file app_voicemail_imapstorage.c.
References ast_channel::language, vm_state::starting, vm_instructions_en(), and vm_instructions_zh().
08999 { 09000 if (vms->starting && !strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 09001 return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent); 09002 } else { /* Default to ENGLISH */ 09003 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 09004 } 09005 }
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 8897 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_test_flag, ast_waitfordigit(), vm_state::curmsg, vm_state::deleted, vm_state::lastmsg, vm_state::newmessages, vm_state::repeats, vm_state::starting, vm_state::urgentmessages, VM_MESSAGEWRAP, vm_play_folder_name(), and vm_state::vmbox.
08898 { 08899 int res = 0; 08900 /* Play instructions and wait for new command */ 08901 while (!res) { 08902 if (vms->starting) { 08903 if (vms->lastmsg > -1) { 08904 if (skipadvanced) 08905 res = ast_play_and_wait(chan, "vm-onefor-full"); 08906 else 08907 res = ast_play_and_wait(chan, "vm-onefor"); 08908 if (!res) 08909 res = vm_play_folder_name(chan, vms->vmbox); 08910 } 08911 if (!res) { 08912 if (skipadvanced) 08913 res = ast_play_and_wait(chan, "vm-opts-full"); 08914 else 08915 res = ast_play_and_wait(chan, "vm-opts"); 08916 } 08917 } else { 08918 /* Added for additional help */ 08919 if (skipadvanced) { 08920 res = ast_play_and_wait(chan, "vm-onefor-full"); 08921 if (!res) 08922 res = vm_play_folder_name(chan, vms->vmbox); 08923 res = ast_play_and_wait(chan, "vm-opts-full"); 08924 } 08925 /* Logic: 08926 * If the current message is not the first OR 08927 * if we're listening to the first new message and there are 08928 * also urgent messages, then prompt for navigation to the 08929 * previous message 08930 */ 08931 if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) { 08932 res = ast_play_and_wait(chan, "vm-prev"); 08933 } 08934 if (!res && !skipadvanced) 08935 res = ast_play_and_wait(chan, "vm-advopts"); 08936 if (!res) 08937 res = ast_play_and_wait(chan, "vm-repeat"); 08938 /* Logic: 08939 * If we're not listening to the last message OR 08940 * we're listening to the last urgent message and there are 08941 * also new non-urgent messages, then prompt for navigation 08942 * to the next message 08943 */ 08944 if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) || 08945 (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) { 08946 res = ast_play_and_wait(chan, "vm-next"); 08947 } 08948 if (!res) { 08949 if (!vms->deleted[vms->curmsg]) 08950 res = ast_play_and_wait(chan, "vm-delete"); 08951 else 08952 res = ast_play_and_wait(chan, "vm-undelete"); 08953 if (!res) 08954 res = ast_play_and_wait(chan, "vm-toforward"); 08955 if (!res) 08956 res = ast_play_and_wait(chan, "vm-savemessage"); 08957 } 08958 } 08959 if (!res) { 08960 res = ast_play_and_wait(chan, "vm-helpexit"); 08961 } 08962 if (!res) 08963 res = ast_waitfordigit(chan, 6000); 08964 if (!res) { 08965 vms->repeats++; 08966 if (vms->repeats > 2) { 08967 res = 't'; 08968 } 08969 } 08970 } 08971 return res; 08972 }
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 8974 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.
08975 { 08976 int res = 0; 08977 /* Play instructions and wait for new command */ 08978 while (!res) { 08979 if (vms->lastmsg > -1) { 08980 res = ast_play_and_wait(chan, "vm-listen"); 08981 if (!res) 08982 res = vm_play_folder_name(chan, vms->vmbox); 08983 if (!res) 08984 res = ast_play_and_wait(chan, "press"); 08985 if (!res) 08986 res = ast_play_and_wait(chan, "digits/1"); 08987 } 08988 if (!res) 08989 res = ast_play_and_wait(chan, "vm-opts"); 08990 if (!res) { 08991 vms->starting = 0; 08992 return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent); 08993 } 08994 } 08995 return res; 08996 }
static int vm_intro | ( | struct ast_channel * | chan, | |
struct ast_vm_user * | vmu, | |||
struct vm_state * | vms | |||
) | [static] |
Definition at line 8835 of file app_voicemail_imapstorage.c.
References ast_fileexists(), ast_log(), ast_play_and_wait(), ast_test_flag, ast_vm_user::context, DISPOSE, ast_channel::language, LOG_WARNING, ast_vm_user::mailbox, RETRIEVE, vm_state::username, vm_intro_cs(), vm_intro_de(), vm_intro_en(), vm_intro_es(), vm_intro_fr(), vm_intro_gr(), vm_intro_he(), vm_intro_it(), vm_intro_multilang(), vm_intro_nl(), vm_intro_no(), vm_intro_pl(), vm_intro_pt(), vm_intro_pt_BR(), vm_intro_se(), vm_intro_vi(), vm_intro_zh(), and VM_TEMPGREETWARN.
08836 { 08837 char prefile[256]; 08838 08839 /* Notify the user that the temp greeting is set and give them the option to remove it */ 08840 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 08841 if (ast_test_flag(vmu, VM_TEMPGREETWARN)) { 08842 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 08843 if (ast_fileexists(prefile, NULL, NULL) > 0) { 08844 ast_play_and_wait(chan, "vm-tempgreetactive"); 08845 } 08846 DISPOSE(prefile, -1); 08847 } 08848 08849 /* Play voicemail intro - syntax is different for different languages */ 08850 if (0) { 08851 return 0; 08852 } else if (!strncasecmp(chan->language, "cs", 2)) { /* CZECH syntax */ 08853 return vm_intro_cs(chan, vms); 08854 } else if (!strncasecmp(chan->language, "cz", 2)) { /* deprecated CZECH syntax */ 08855 static int deprecation_warning = 0; 08856 if (deprecation_warning++ % 10 == 0) { 08857 ast_log(LOG_WARNING, "cz is not a standard language code. Please switch to using cs instead.\n"); 08858 } 08859 return vm_intro_cs(chan, vms); 08860 } else if (!strncasecmp(chan->language, "de", 2)) { /* GERMAN syntax */ 08861 return vm_intro_de(chan, vms); 08862 } else if (!strncasecmp(chan->language, "es", 2)) { /* SPANISH syntax */ 08863 return vm_intro_es(chan, vms); 08864 } else if (!strncasecmp(chan->language, "fr", 2)) { /* FRENCH syntax */ 08865 return vm_intro_fr(chan, vms); 08866 } else if (!strncasecmp(chan->language, "gr", 2)) { /* GREEK syntax */ 08867 return vm_intro_gr(chan, vms); 08868 } else if (!strncasecmp(chan->language, "he", 2)) { /* HEBREW syntax */ 08869 return vm_intro_he(chan, vms); 08870 } else if (!strncasecmp(chan->language, "it", 2)) { /* ITALIAN syntax */ 08871 return vm_intro_it(chan, vms); 08872 } else if (!strncasecmp(chan->language, "nl", 2)) { /* DUTCH syntax */ 08873 return vm_intro_nl(chan, vms); 08874 } else if (!strncasecmp(chan->language, "no", 2)) { /* NORWEGIAN syntax */ 08875 return vm_intro_no(chan, vms); 08876 } else if (!strncasecmp(chan->language, "pl", 2)) { /* POLISH syntax */ 08877 return vm_intro_pl(chan, vms); 08878 } else if (!strncasecmp(chan->language, "pt_BR", 5)) { /* BRAZILIAN PORTUGUESE syntax */ 08879 return vm_intro_pt_BR(chan, vms); 08880 } else if (!strncasecmp(chan->language, "pt", 2)) { /* PORTUGUESE syntax */ 08881 return vm_intro_pt(chan, vms); 08882 } else if (!strncasecmp(chan->language, "ru", 2)) { /* RUSSIAN syntax */ 08883 return vm_intro_multilang(chan, vms, "n"); 08884 } else if (!strncasecmp(chan->language, "se", 2)) { /* SWEDISH syntax */ 08885 return vm_intro_se(chan, vms); 08886 } else if (!strncasecmp(chan->language, "ua", 2)) { /* UKRAINIAN syntax */ 08887 return vm_intro_multilang(chan, vms, "n"); 08888 } else if (!strncasecmp(chan->language, "vi", 2)) { /* VIETNAMESE syntax */ 08889 return vm_intro_vi(chan, vms); 08890 } else if (!strncasecmp(chan->language, "zh", 2)) { /* CHINESE (Taiwan) syntax */ 08891 return vm_intro_zh(chan, vms); 08892 } else { /* Default to ENGLISH */ 08893 return vm_intro_en(chan, vms); 08894 } 08895 }
static int vm_intro_cs | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8705 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.
08706 { 08707 int res; 08708 res = ast_play_and_wait(chan, "vm-youhave"); 08709 if (!res) { 08710 if (vms->newmessages) { 08711 if (vms->newmessages == 1) { 08712 res = ast_play_and_wait(chan, "digits/jednu"); 08713 } else { 08714 res = say_and_wait(chan, vms->newmessages, chan->language); 08715 } 08716 if (!res) { 08717 if ((vms->newmessages == 1)) 08718 res = ast_play_and_wait(chan, "vm-novou"); 08719 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08720 res = ast_play_and_wait(chan, "vm-nove"); 08721 if (vms->newmessages > 4) 08722 res = ast_play_and_wait(chan, "vm-novych"); 08723 } 08724 if (vms->oldmessages && !res) 08725 res = ast_play_and_wait(chan, "vm-and"); 08726 else if (!res) { 08727 if ((vms->newmessages == 1)) 08728 res = ast_play_and_wait(chan, "vm-zpravu"); 08729 if ((vms->newmessages) > 1 && (vms->newmessages < 5)) 08730 res = ast_play_and_wait(chan, "vm-zpravy"); 08731 if (vms->newmessages > 4) 08732 res = ast_play_and_wait(chan, "vm-zprav"); 08733 } 08734 } 08735 if (!res && vms->oldmessages) { 08736 res = say_and_wait(chan, vms->oldmessages, chan->language); 08737 if (!res) { 08738 if ((vms->oldmessages == 1)) 08739 res = ast_play_and_wait(chan, "vm-starou"); 08740 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08741 res = ast_play_and_wait(chan, "vm-stare"); 08742 if (vms->oldmessages > 4) 08743 res = ast_play_and_wait(chan, "vm-starych"); 08744 } 08745 if (!res) { 08746 if ((vms->oldmessages == 1)) 08747 res = ast_play_and_wait(chan, "vm-zpravu"); 08748 if ((vms->oldmessages) > 1 && (vms->oldmessages < 5)) 08749 res = ast_play_and_wait(chan, "vm-zpravy"); 08750 if (vms->oldmessages > 4) 08751 res = ast_play_and_wait(chan, "vm-zprav"); 08752 } 08753 } 08754 if (!res) { 08755 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08756 res = ast_play_and_wait(chan, "vm-no"); 08757 if (!res) 08758 res = ast_play_and_wait(chan, "vm-zpravy"); 08759 } 08760 } 08761 } 08762 return res; 08763 }
static int vm_intro_de | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8401 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.
08402 { 08403 /* Introduce messages they have */ 08404 int res; 08405 res = ast_play_and_wait(chan, "vm-youhave"); 08406 if (!res) { 08407 if (vms->newmessages) { 08408 if ((vms->newmessages == 1)) 08409 res = ast_play_and_wait(chan, "digits/1F"); 08410 else 08411 res = say_and_wait(chan, vms->newmessages, chan->language); 08412 if (!res) 08413 res = ast_play_and_wait(chan, "vm-INBOX"); 08414 if (vms->oldmessages && !res) 08415 res = ast_play_and_wait(chan, "vm-and"); 08416 else if (!res) { 08417 if ((vms->newmessages == 1)) 08418 res = ast_play_and_wait(chan, "vm-message"); 08419 else 08420 res = ast_play_and_wait(chan, "vm-messages"); 08421 } 08422 08423 } 08424 if (!res && vms->oldmessages) { 08425 if (vms->oldmessages == 1) 08426 res = ast_play_and_wait(chan, "digits/1F"); 08427 else 08428 res = say_and_wait(chan, vms->oldmessages, chan->language); 08429 if (!res) 08430 res = ast_play_and_wait(chan, "vm-Old"); 08431 if (!res) { 08432 if (vms->oldmessages == 1) 08433 res = ast_play_and_wait(chan, "vm-message"); 08434 else 08435 res = ast_play_and_wait(chan, "vm-messages"); 08436 } 08437 } 08438 if (!res) { 08439 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08440 res = ast_play_and_wait(chan, "vm-no"); 08441 if (!res) 08442 res = ast_play_and_wait(chan, "vm-messages"); 08443 } 08444 } 08445 } 08446 return res; 08447 }
static int vm_intro_en | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8150 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.
08151 { 08152 int res; 08153 08154 /* Introduce messages they have */ 08155 res = ast_play_and_wait(chan, "vm-youhave"); 08156 if (!res) { 08157 if (vms->urgentmessages) { 08158 res = say_and_wait(chan, vms->urgentmessages, chan->language); 08159 if (!res) 08160 res = ast_play_and_wait(chan, "vm-Urgent"); 08161 if ((vms->oldmessages || vms->newmessages) && !res) { 08162 res = ast_play_and_wait(chan, "vm-and"); 08163 } else if (!res) { 08164 if ((vms->urgentmessages == 1)) 08165 res = ast_play_and_wait(chan, "vm-message"); 08166 else 08167 res = ast_play_and_wait(chan, "vm-messages"); 08168 } 08169 } 08170 if (vms->newmessages) { 08171 res = say_and_wait(chan, vms->newmessages, chan->language); 08172 if (!res) 08173 res = ast_play_and_wait(chan, "vm-INBOX"); 08174 if (vms->oldmessages && !res) 08175 res = ast_play_and_wait(chan, "vm-and"); 08176 else if (!res) { 08177 if ((vms->newmessages == 1)) 08178 res = ast_play_and_wait(chan, "vm-message"); 08179 else 08180 res = ast_play_and_wait(chan, "vm-messages"); 08181 } 08182 08183 } 08184 if (!res && vms->oldmessages) { 08185 res = say_and_wait(chan, vms->oldmessages, chan->language); 08186 if (!res) 08187 res = ast_play_and_wait(chan, "vm-Old"); 08188 if (!res) { 08189 if (vms->oldmessages == 1) 08190 res = ast_play_and_wait(chan, "vm-message"); 08191 else 08192 res = ast_play_and_wait(chan, "vm-messages"); 08193 } 08194 } 08195 if (!res) { 08196 if (!vms->urgentmessages && !vms->oldmessages && !vms->newmessages) { 08197 res = ast_play_and_wait(chan, "vm-no"); 08198 if (!res) 08199 res = ast_play_and_wait(chan, "vm-messages"); 08200 } 08201 } 08202 } 08203 return res; 08204 }
static int vm_intro_es | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8450 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.
08451 { 08452 /* Introduce messages they have */ 08453 int res; 08454 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08455 res = ast_play_and_wait(chan, "vm-youhaveno"); 08456 if (!res) 08457 res = ast_play_and_wait(chan, "vm-messages"); 08458 } else { 08459 res = ast_play_and_wait(chan, "vm-youhave"); 08460 } 08461 if (!res) { 08462 if (vms->newmessages) { 08463 if (!res) { 08464 if ((vms->newmessages == 1)) { 08465 res = ast_play_and_wait(chan, "digits/1M"); 08466 if (!res) 08467 res = ast_play_and_wait(chan, "vm-message"); 08468 if (!res) 08469 res = ast_play_and_wait(chan, "vm-INBOXs"); 08470 } else { 08471 res = say_and_wait(chan, vms->newmessages, chan->language); 08472 if (!res) 08473 res = ast_play_and_wait(chan, "vm-messages"); 08474 if (!res) 08475 res = ast_play_and_wait(chan, "vm-INBOX"); 08476 } 08477 } 08478 if (vms->oldmessages && !res) 08479 res = ast_play_and_wait(chan, "vm-and"); 08480 } 08481 if (vms->oldmessages) { 08482 if (!res) { 08483 if (vms->oldmessages == 1) { 08484 res = ast_play_and_wait(chan, "digits/1M"); 08485 if (!res) 08486 res = ast_play_and_wait(chan, "vm-message"); 08487 if (!res) 08488 res = ast_play_and_wait(chan, "vm-Olds"); 08489 } else { 08490 res = say_and_wait(chan, vms->oldmessages, chan->language); 08491 if (!res) 08492 res = ast_play_and_wait(chan, "vm-messages"); 08493 if (!res) 08494 res = ast_play_and_wait(chan, "vm-Old"); 08495 } 08496 } 08497 } 08498 } 08499 return res; 08500 }
static int vm_intro_fr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8548 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.
08549 { 08550 /* Introduce messages they have */ 08551 int res; 08552 res = ast_play_and_wait(chan, "vm-youhave"); 08553 if (!res) { 08554 if (vms->newmessages) { 08555 res = say_and_wait(chan, vms->newmessages, chan->language); 08556 if (!res) 08557 res = ast_play_and_wait(chan, "vm-INBOX"); 08558 if (vms->oldmessages && !res) 08559 res = ast_play_and_wait(chan, "vm-and"); 08560 else if (!res) { 08561 if ((vms->newmessages == 1)) 08562 res = ast_play_and_wait(chan, "vm-message"); 08563 else 08564 res = ast_play_and_wait(chan, "vm-messages"); 08565 } 08566 08567 } 08568 if (!res && vms->oldmessages) { 08569 res = say_and_wait(chan, vms->oldmessages, chan->language); 08570 if (!res) 08571 res = ast_play_and_wait(chan, "vm-Old"); 08572 if (!res) { 08573 if (vms->oldmessages == 1) 08574 res = ast_play_and_wait(chan, "vm-message"); 08575 else 08576 res = ast_play_and_wait(chan, "vm-messages"); 08577 } 08578 } 08579 if (!res) { 08580 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08581 res = ast_play_and_wait(chan, "vm-no"); 08582 if (!res) 08583 res = ast_play_and_wait(chan, "vm-messages"); 08584 } 08585 } 08586 } 08587 return res; 08588 }
static int vm_intro_gr | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 7949 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.
07950 { 07951 int res = 0; 07952 07953 if (vms->newmessages) { 07954 res = ast_play_and_wait(chan, "vm-youhave"); 07955 if (!res) 07956 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, NULL); 07957 if (!res) { 07958 if ((vms->newmessages == 1)) { 07959 res = ast_play_and_wait(chan, "vm-INBOX"); 07960 if (!res) 07961 res = ast_play_and_wait(chan, "vm-message"); 07962 } else { 07963 res = ast_play_and_wait(chan, "vm-INBOXs"); 07964 if (!res) 07965 res = ast_play_and_wait(chan, "vm-messages"); 07966 } 07967 } 07968 } else if (vms->oldmessages){ 07969 res = ast_play_and_wait(chan, "vm-youhave"); 07970 if (!res) 07971 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, NULL); 07972 if ((vms->oldmessages == 1)){ 07973 res = ast_play_and_wait(chan, "vm-Old"); 07974 if (!res) 07975 res = ast_play_and_wait(chan, "vm-message"); 07976 } else { 07977 res = ast_play_and_wait(chan, "vm-Olds"); 07978 if (!res) 07979 res = ast_play_and_wait(chan, "vm-messages"); 07980 } 07981 } else if (!vms->oldmessages && !vms->newmessages) 07982 res = ast_play_and_wait(chan, "vm-denExeteMynhmata"); 07983 return res; 07984 }
static int vm_intro_he | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8083 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.
08084 { 08085 int res = 0; 08086 08087 /* Introduce messages they have */ 08088 if (!res) { 08089 if ((vms->newmessages) || (vms->oldmessages)) { 08090 res = ast_play_and_wait(chan, "vm-youhave"); 08091 } 08092 /* 08093 * The word "shtei" refers to the number 2 in hebrew when performing a count 08094 * of elements. In Hebrew, there are 6 forms of enumerating the number 2 for 08095 * an element, this is one of them. 08096 */ 08097 if (vms->newmessages) { 08098 if (!res) { 08099 if (vms->newmessages == 1) { 08100 res = ast_play_and_wait(chan, "vm-INBOX1"); 08101 } else { 08102 if (vms->newmessages == 2) { 08103 res = ast_play_and_wait(chan, "vm-shtei"); 08104 } else { 08105 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08106 } 08107 res = ast_play_and_wait(chan, "vm-INBOX"); 08108 } 08109 } 08110 if (vms->oldmessages && !res) { 08111 res = ast_play_and_wait(chan, "vm-and"); 08112 if (vms->oldmessages == 1) { 08113 res = ast_play_and_wait(chan, "vm-Old1"); 08114 } else { 08115 if (vms->oldmessages == 2) { 08116 res = ast_play_and_wait(chan, "vm-shtei"); 08117 } else { 08118 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08119 } 08120 res = ast_play_and_wait(chan, "vm-Old"); 08121 } 08122 } 08123 } 08124 if (!res && vms->oldmessages && !vms->newmessages) { 08125 if (!res) { 08126 if (vms->oldmessages == 1) { 08127 res = ast_play_and_wait(chan, "vm-Old1"); 08128 } else { 08129 if (vms->oldmessages == 2) { 08130 res = ast_play_and_wait(chan, "vm-shtei"); 08131 } else { 08132 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08133 } 08134 res = ast_play_and_wait(chan, "vm-Old"); 08135 } 08136 } 08137 } 08138 if (!res) { 08139 if (!vms->oldmessages && !vms->newmessages) { 08140 if (!res) { 08141 res = ast_play_and_wait(chan, "vm-nomessages"); 08142 } 08143 } 08144 } 08145 } 08146 return res; 08147 }
static int vm_intro_it | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8207 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.
08208 { 08209 /* Introduce messages they have */ 08210 int res; 08211 if (!vms->oldmessages && !vms->newmessages &&!vms->urgentmessages) 08212 res = ast_play_and_wait(chan, "vm-no") || 08213 ast_play_and_wait(chan, "vm-message"); 08214 else 08215 res = ast_play_and_wait(chan, "vm-youhave"); 08216 if (!res && vms->newmessages) { 08217 res = (vms->newmessages == 1) ? 08218 ast_play_and_wait(chan, "digits/un") || 08219 ast_play_and_wait(chan, "vm-nuovo") || 08220 ast_play_and_wait(chan, "vm-message") : 08221 /* 2 or more new messages */ 08222 say_and_wait(chan, vms->newmessages, chan->language) || 08223 ast_play_and_wait(chan, "vm-nuovi") || 08224 ast_play_and_wait(chan, "vm-messages"); 08225 if (!res && vms->oldmessages) 08226 res = ast_play_and_wait(chan, "vm-and"); 08227 } 08228 if (!res && vms->oldmessages) { 08229 res = (vms->oldmessages == 1) ? 08230 ast_play_and_wait(chan, "digits/un") || 08231 ast_play_and_wait(chan, "vm-vecchio") || 08232 ast_play_and_wait(chan, "vm-message") : 08233 /* 2 or more old messages */ 08234 say_and_wait(chan, vms->oldmessages, chan->language) || 08235 ast_play_and_wait(chan, "vm-vecchi") || 08236 ast_play_and_wait(chan, "vm-messages"); 08237 } 08238 return res; 08239 }
static int vm_intro_multilang | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
const char | message_gender[] | |||
) | [static] |
Definition at line 8043 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.
08044 { 08045 int res; 08046 int lastnum = 0; 08047 08048 res = ast_play_and_wait(chan, "vm-youhave"); 08049 08050 if (!res && vms->newmessages) { 08051 lastnum = vms->newmessages; 08052 08053 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08054 res = ast_say_counted_adjective(chan, lastnum, "vm-new", message_gender); 08055 } 08056 08057 if (!res && vms->oldmessages) { 08058 res = ast_play_and_wait(chan, "vm-and"); 08059 } 08060 } 08061 08062 if (!res && vms->oldmessages) { 08063 lastnum = vms->oldmessages; 08064 08065 if (!(res = ast_say_number(chan, lastnum, AST_DIGIT_ANY, chan->language, message_gender))) { 08066 res = ast_say_counted_adjective(chan, lastnum, "vm-old", message_gender); 08067 } 08068 } 08069 08070 if (!res) { 08071 if (lastnum == 0) { 08072 res = ast_play_and_wait(chan, "vm-no"); 08073 } 08074 if (!res) { 08075 res = ast_say_counted_noun(chan, lastnum, "vm-message"); 08076 } 08077 } 08078 08079 return res; 08080 }
static int vm_intro_nl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8591 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.
08592 { 08593 /* Introduce messages they have */ 08594 int res; 08595 res = ast_play_and_wait(chan, "vm-youhave"); 08596 if (!res) { 08597 if (vms->newmessages) { 08598 res = say_and_wait(chan, vms->newmessages, chan->language); 08599 if (!res) { 08600 if (vms->newmessages == 1) 08601 res = ast_play_and_wait(chan, "vm-INBOXs"); 08602 else 08603 res = ast_play_and_wait(chan, "vm-INBOX"); 08604 } 08605 if (vms->oldmessages && !res) 08606 res = ast_play_and_wait(chan, "vm-and"); 08607 else if (!res) { 08608 if ((vms->newmessages == 1)) 08609 res = ast_play_and_wait(chan, "vm-message"); 08610 else 08611 res = ast_play_and_wait(chan, "vm-messages"); 08612 } 08613 08614 } 08615 if (!res && vms->oldmessages) { 08616 res = say_and_wait(chan, vms->oldmessages, chan->language); 08617 if (!res) { 08618 if (vms->oldmessages == 1) 08619 res = ast_play_and_wait(chan, "vm-Olds"); 08620 else 08621 res = ast_play_and_wait(chan, "vm-Old"); 08622 } 08623 if (!res) { 08624 if (vms->oldmessages == 1) 08625 res = ast_play_and_wait(chan, "vm-message"); 08626 else 08627 res = ast_play_and_wait(chan, "vm-messages"); 08628 } 08629 } 08630 if (!res) { 08631 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08632 res = ast_play_and_wait(chan, "vm-no"); 08633 if (!res) 08634 res = ast_play_and_wait(chan, "vm-messages"); 08635 } 08636 } 08637 } 08638 return res; 08639 }
static int vm_intro_no | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8357 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.
08358 { 08359 /* Introduce messages they have */ 08360 int res; 08361 08362 res = ast_play_and_wait(chan, "vm-youhave"); 08363 if (res) 08364 return res; 08365 08366 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08367 res = ast_play_and_wait(chan, "vm-no"); 08368 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08369 return res; 08370 } 08371 08372 if (vms->newmessages) { 08373 if ((vms->newmessages == 1)) { 08374 res = ast_play_and_wait(chan, "digits/1"); 08375 res = res ? res : ast_play_and_wait(chan, "vm-ny"); 08376 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08377 } else { 08378 res = say_and_wait(chan, vms->newmessages, chan->language); 08379 res = res ? res : ast_play_and_wait(chan, "vm-nye"); 08380 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08381 } 08382 if (!res && vms->oldmessages) 08383 res = ast_play_and_wait(chan, "vm-and"); 08384 } 08385 if (!res && vms->oldmessages) { 08386 if (vms->oldmessages == 1) { 08387 res = ast_play_and_wait(chan, "digits/1"); 08388 res = res ? res : ast_play_and_wait(chan, "vm-gamel"); 08389 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08390 } else { 08391 res = say_and_wait(chan, vms->oldmessages, chan->language); 08392 res = res ? res : ast_play_and_wait(chan, "vm-gamle"); 08393 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08394 } 08395 } 08396 08397 return res; 08398 }
static int vm_intro_pl | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8242 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08243 { 08244 /* Introduce messages they have */ 08245 int res; 08246 div_t num; 08247 08248 if (!vms->oldmessages && !vms->newmessages) { 08249 res = ast_play_and_wait(chan, "vm-no"); 08250 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08251 return res; 08252 } else { 08253 res = ast_play_and_wait(chan, "vm-youhave"); 08254 } 08255 08256 if (vms->newmessages) { 08257 num = div(vms->newmessages, 10); 08258 if (vms->newmessages == 1) { 08259 res = ast_play_and_wait(chan, "digits/1-a"); 08260 res = res ? res : ast_play_and_wait(chan, "vm-new-a"); 08261 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08262 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08263 if (num.rem == 2) { 08264 if (!num.quot) { 08265 res = ast_play_and_wait(chan, "digits/2-ie"); 08266 } else { 08267 res = say_and_wait(chan, vms->newmessages - 2 , chan->language); 08268 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08269 } 08270 } else { 08271 res = say_and_wait(chan, vms->newmessages, chan->language); 08272 } 08273 res = res ? res : ast_play_and_wait(chan, "vm-new-e"); 08274 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08275 } else { 08276 res = say_and_wait(chan, vms->newmessages, chan->language); 08277 res = res ? res : ast_play_and_wait(chan, "vm-new-ych"); 08278 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08279 } 08280 if (!res && vms->oldmessages) 08281 res = ast_play_and_wait(chan, "vm-and"); 08282 } 08283 if (!res && vms->oldmessages) { 08284 num = div(vms->oldmessages, 10); 08285 if (vms->oldmessages == 1) { 08286 res = ast_play_and_wait(chan, "digits/1-a"); 08287 res = res ? res : ast_play_and_wait(chan, "vm-old-a"); 08288 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08289 } else if (num.rem > 1 && num.rem < 5 && num.quot != 1) { 08290 if (num.rem == 2) { 08291 if (!num.quot) { 08292 res = ast_play_and_wait(chan, "digits/2-ie"); 08293 } else { 08294 res = say_and_wait(chan, vms->oldmessages - 2 , chan->language); 08295 res = res ? res : ast_play_and_wait(chan, "digits/2-ie"); 08296 } 08297 } else { 08298 res = say_and_wait(chan, vms->oldmessages, chan->language); 08299 } 08300 res = res ? res : ast_play_and_wait(chan, "vm-old-e"); 08301 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08302 } else { 08303 res = say_and_wait(chan, vms->oldmessages, chan->language); 08304 res = res ? res : ast_play_and_wait(chan, "vm-old-ych"); 08305 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08306 } 08307 } 08308 08309 return res; 08310 }
static int vm_intro_pt | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8642 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.
08643 { 08644 /* Introduce messages they have */ 08645 int res; 08646 res = ast_play_and_wait(chan, "vm-youhave"); 08647 if (!res) { 08648 if (vms->newmessages) { 08649 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08650 if (!res) { 08651 if ((vms->newmessages == 1)) { 08652 res = ast_play_and_wait(chan, "vm-message"); 08653 if (!res) 08654 res = ast_play_and_wait(chan, "vm-INBOXs"); 08655 } else { 08656 res = ast_play_and_wait(chan, "vm-messages"); 08657 if (!res) 08658 res = ast_play_and_wait(chan, "vm-INBOX"); 08659 } 08660 } 08661 if (vms->oldmessages && !res) 08662 res = ast_play_and_wait(chan, "vm-and"); 08663 } 08664 if (!res && vms->oldmessages) { 08665 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08666 if (!res) { 08667 if (vms->oldmessages == 1) { 08668 res = ast_play_and_wait(chan, "vm-message"); 08669 if (!res) 08670 res = ast_play_and_wait(chan, "vm-Olds"); 08671 } else { 08672 res = ast_play_and_wait(chan, "vm-messages"); 08673 if (!res) 08674 res = ast_play_and_wait(chan, "vm-Old"); 08675 } 08676 } 08677 } 08678 if (!res) { 08679 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08680 res = ast_play_and_wait(chan, "vm-no"); 08681 if (!res) 08682 res = ast_play_and_wait(chan, "vm-messages"); 08683 } 08684 } 08685 } 08686 return res; 08687 }
static int vm_intro_pt_BR | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8503 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.
08503 { 08504 /* Introduce messages they have */ 08505 int res; 08506 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08507 res = ast_play_and_wait(chan, "vm-nomessages"); 08508 return res; 08509 } else { 08510 res = ast_play_and_wait(chan, "vm-youhave"); 08511 } 08512 if (vms->newmessages) { 08513 if (!res) 08514 res = ast_say_number(chan, vms->newmessages, AST_DIGIT_ANY, chan->language, "f"); 08515 if ((vms->newmessages == 1)) { 08516 if (!res) 08517 res = ast_play_and_wait(chan, "vm-message"); 08518 if (!res) 08519 res = ast_play_and_wait(chan, "vm-INBOXs"); 08520 } else { 08521 if (!res) 08522 res = ast_play_and_wait(chan, "vm-messages"); 08523 if (!res) 08524 res = ast_play_and_wait(chan, "vm-INBOX"); 08525 } 08526 if (vms->oldmessages && !res) 08527 res = ast_play_and_wait(chan, "vm-and"); 08528 } 08529 if (vms->oldmessages) { 08530 if (!res) 08531 res = ast_say_number(chan, vms->oldmessages, AST_DIGIT_ANY, chan->language, "f"); 08532 if (vms->oldmessages == 1) { 08533 if (!res) 08534 res = ast_play_and_wait(chan, "vm-message"); 08535 if (!res) 08536 res = ast_play_and_wait(chan, "vm-Olds"); 08537 } else { 08538 if (!res) 08539 res = ast_play_and_wait(chan, "vm-messages"); 08540 if (!res) 08541 res = ast_play_and_wait(chan, "vm-Old"); 08542 } 08543 } 08544 return res; 08545 }
static int vm_intro_se | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8313 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.
08314 { 08315 /* Introduce messages they have */ 08316 int res; 08317 08318 res = ast_play_and_wait(chan, "vm-youhave"); 08319 if (res) 08320 return res; 08321 08322 if (!vms->oldmessages && !vms->newmessages && !vms->urgentmessages) { 08323 res = ast_play_and_wait(chan, "vm-no"); 08324 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08325 return res; 08326 } 08327 08328 if (vms->newmessages) { 08329 if ((vms->newmessages == 1)) { 08330 res = ast_play_and_wait(chan, "digits/ett"); 08331 res = res ? res : ast_play_and_wait(chan, "vm-nytt"); 08332 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08333 } else { 08334 res = say_and_wait(chan, vms->newmessages, chan->language); 08335 res = res ? res : ast_play_and_wait(chan, "vm-nya"); 08336 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08337 } 08338 if (!res && vms->oldmessages) 08339 res = ast_play_and_wait(chan, "vm-and"); 08340 } 08341 if (!res && vms->oldmessages) { 08342 if (vms->oldmessages == 1) { 08343 res = ast_play_and_wait(chan, "digits/ett"); 08344 res = res ? res : ast_play_and_wait(chan, "vm-gammalt"); 08345 res = res ? res : ast_play_and_wait(chan, "vm-message"); 08346 } else { 08347 res = say_and_wait(chan, vms->oldmessages, chan->language); 08348 res = res ? res : ast_play_and_wait(chan, "vm-gamla"); 08349 res = res ? res : ast_play_and_wait(chan, "vm-messages"); 08350 } 08351 } 08352 08353 return res; 08354 }
static int vm_intro_vi | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8805 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08806 { 08807 int res; 08808 08809 /* Introduce messages they have */ 08810 res = ast_play_and_wait(chan, "vm-youhave"); 08811 if (!res) { 08812 if (vms->newmessages) { 08813 res = say_and_wait(chan, vms->newmessages, chan->language); 08814 if (!res) 08815 res = ast_play_and_wait(chan, "vm-INBOX"); 08816 if (vms->oldmessages && !res) 08817 res = ast_play_and_wait(chan, "vm-and"); 08818 } 08819 if (!res && vms->oldmessages) { 08820 res = say_and_wait(chan, vms->oldmessages, chan->language); 08821 if (!res) 08822 res = ast_play_and_wait(chan, "vm-Old"); 08823 } 08824 if (!res) { 08825 if (!vms->oldmessages && !vms->newmessages) { 08826 res = ast_play_and_wait(chan, "vm-no"); 08827 if (!res) 08828 res = ast_play_and_wait(chan, "vm-message"); 08829 } 08830 } 08831 } 08832 return res; 08833 }
static int vm_intro_zh | ( | struct ast_channel * | chan, | |
struct vm_state * | vms | |||
) | [static] |
Definition at line 8766 of file app_voicemail_imapstorage.c.
References ast_play_and_wait(), ast_channel::language, vm_state::newmessages, vm_state::oldmessages, and say_and_wait().
08767 { 08768 int res; 08769 /* Introduce messages they have */ 08770 res = ast_play_and_wait(chan, "vm-you"); 08771 08772 if (!res && vms->newmessages) { 08773 res = ast_play_and_wait(chan, "vm-have"); 08774 if (!res) 08775 res = say_and_wait(chan, vms->newmessages, chan->language); 08776 if (!res) 08777 res = ast_play_and_wait(chan, "vm-tong"); 08778 if (!res) 08779 res = ast_play_and_wait(chan, "vm-INBOX"); 08780 if (vms->oldmessages && !res) 08781 res = ast_play_and_wait(chan, "vm-and"); 08782 else if (!res) 08783 res = ast_play_and_wait(chan, "vm-messages"); 08784 } 08785 if (!res && vms->oldmessages) { 08786 res = ast_play_and_wait(chan, "vm-have"); 08787 if (!res) 08788 res = say_and_wait(chan, vms->oldmessages, chan->language); 08789 if (!res) 08790 res = ast_play_and_wait(chan, "vm-tong"); 08791 if (!res) 08792 res = ast_play_and_wait(chan, "vm-Old"); 08793 if (!res) 08794 res = ast_play_and_wait(chan, "vm-messages"); 08795 } 08796 if (!res && !vms->oldmessages && !vms->newmessages) { 08797 res = ast_play_and_wait(chan, "vm-haveno"); 08798 if (!res) 08799 res = ast_play_and_wait(chan, "vm-messages"); 08800 } 08801 return res; 08802 }
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 3180 of file app_voicemail_imapstorage.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
03181 { 03182 switch (ast_lock_path(path)) { 03183 case AST_LOCK_TIMEOUT: 03184 return -1; 03185 default: 03186 return 0; 03187 } 03188 }
static FILE* vm_mkftemp | ( | char * | template | ) | [static] |
Definition at line 1586 of file app_voicemail_imapstorage.c.
References VOICEMAIL_FILE_MODE.
01587 { 01588 FILE *p = NULL; 01589 int pfd = mkstemp(template); 01590 chmod(template, VOICEMAIL_FILE_MODE & ~my_umask); 01591 if (pfd > -1) { 01592 p = fdopen(pfd, "w+"); 01593 if (!p) { 01594 close(pfd); 01595 pfd = -1; 01596 } 01597 } 01598 return p; 01599 }
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 9008 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, check_password(), play_record_review(), 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, and vm_reenterpassword.
09009 { 09010 int cmd = 0; 09011 int duration = 0; 09012 int tries = 0; 09013 char newpassword[80] = ""; 09014 char newpassword2[80] = ""; 09015 char prefile[PATH_MAX] = ""; 09016 unsigned char buf[256]; 09017 int bytes = 0; 09018 09019 if (ast_adsi_available(chan)) { 09020 bytes += adsi_logo(buf + bytes); 09021 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "New User Setup", ""); 09022 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09023 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09024 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09025 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09026 } 09027 09028 /* First, have the user change their password 09029 so they won't get here again */ 09030 for (;;) { 09031 newpassword[1] = '\0'; 09032 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09033 if (cmd == '#') 09034 newpassword[0] = '\0'; 09035 if (cmd < 0 || cmd == 't' || cmd == '#') 09036 return cmd; 09037 cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); 09038 if (cmd < 0 || cmd == 't' || cmd == '#') 09039 return cmd; 09040 cmd = check_password(vmu, newpassword); /* perform password validation */ 09041 if (cmd != 0) { 09042 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09043 cmd = ast_play_and_wait(chan, vm_invalid_password); 09044 } else { 09045 newpassword2[1] = '\0'; 09046 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09047 if (cmd == '#') 09048 newpassword2[0] = '\0'; 09049 if (cmd < 0 || cmd == 't' || cmd == '#') 09050 return cmd; 09051 cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); 09052 if (cmd < 0 || cmd == 't' || cmd == '#') 09053 return cmd; 09054 if (!strcmp(newpassword, newpassword2)) 09055 break; 09056 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09057 cmd = ast_play_and_wait(chan, vm_mismatch); 09058 } 09059 if (++tries == 3) 09060 return -1; 09061 if (cmd != 0) { 09062 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09063 } 09064 } 09065 if (pwdchange & PWDCHANGE_INTERNAL) 09066 vm_change_password(vmu, newpassword); 09067 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09068 vm_change_password_shell(vmu, newpassword); 09069 09070 ast_debug(1, "User %s set password to %s of length %d\n", vms->username, newpassword, (int) strlen(newpassword)); 09071 cmd = ast_play_and_wait(chan, vm_passchanged); 09072 09073 /* If forcename is set, have the user record their name */ 09074 if (ast_test_flag(vmu, VM_FORCENAME)) { 09075 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09076 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09077 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09078 if (cmd < 0 || cmd == 't' || cmd == '#') 09079 return cmd; 09080 } 09081 } 09082 09083 /* If forcegreetings is set, have the user record their greetings */ 09084 if (ast_test_flag(vmu, VM_FORCEGREET)) { 09085 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09086 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09087 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09088 if (cmd < 0 || cmd == 't' || cmd == '#') 09089 return cmd; 09090 } 09091 09092 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09093 if (ast_fileexists(prefile, NULL, NULL) < 1) { 09094 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09095 if (cmd < 0 || cmd == 't' || cmd == '#') 09096 return cmd; 09097 } 09098 } 09099 09100 return cmd; 09101 }
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 9103 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_waitfordigit(), check_password(), ast_vm_user::context, DISPOSE, ast_vm_user::password, play_record_review(), 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, and vm_tempgreeting().
09104 { 09105 int cmd = 0; 09106 int retries = 0; 09107 int duration = 0; 09108 char newpassword[80] = ""; 09109 char newpassword2[80] = ""; 09110 char prefile[PATH_MAX] = ""; 09111 unsigned char buf[256]; 09112 int bytes = 0; 09113 09114 if (ast_adsi_available(chan)) { 09115 bytes += adsi_logo(buf + bytes); 09116 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Options Menu", ""); 09117 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09118 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09119 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09120 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09121 } 09122 while ((cmd >= 0) && (cmd != 't')) { 09123 if (cmd) 09124 retries = 0; 09125 switch (cmd) { 09126 case '1': /* Record your unavailable message */ 09127 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, vms->username); 09128 cmd = play_record_review(chan, "vm-rec-unv", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09129 break; 09130 case '2': /* Record your busy message */ 09131 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, vms->username); 09132 cmd = play_record_review(chan, "vm-rec-busy", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09133 break; 09134 case '3': /* Record greeting */ 09135 snprintf(prefile, sizeof(prefile), "%s%s/%s/greet", VM_SPOOL_DIR, vmu->context, vms->username); 09136 cmd = play_record_review(chan, "vm-rec-name", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09137 break; 09138 case '4': /* manage the temporary greeting */ 09139 cmd = vm_tempgreeting(chan, vmu, vms, fmtc, record_gain); 09140 break; 09141 case '5': /* change password */ 09142 if (vmu->password[0] == '-') { 09143 cmd = ast_play_and_wait(chan, "vm-no"); 09144 break; 09145 } 09146 newpassword[1] = '\0'; 09147 newpassword[0] = cmd = ast_play_and_wait(chan, vm_newpassword); 09148 if (cmd == '#') 09149 newpassword[0] = '\0'; 09150 else { 09151 if (cmd < 0) 09152 break; 09153 if ((cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#")) < 0) { 09154 break; 09155 } 09156 } 09157 cmd = check_password(vmu, newpassword); /* perform password validation */ 09158 if (cmd != 0) { 09159 ast_log(AST_LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); 09160 cmd = ast_play_and_wait(chan, vm_invalid_password); 09161 if (!cmd) { 09162 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09163 } 09164 break; 09165 } 09166 newpassword2[1] = '\0'; 09167 newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); 09168 if (cmd == '#') 09169 newpassword2[0] = '\0'; 09170 else { 09171 if (cmd < 0) 09172 break; 09173 09174 if ((cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#")) < 0) { 09175 break; 09176 } 09177 } 09178 if (strcmp(newpassword, newpassword2)) { 09179 ast_log(AST_LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); 09180 cmd = ast_play_and_wait(chan, vm_mismatch); 09181 if (!cmd) { 09182 cmd = ast_play_and_wait(chan, vm_pls_try_again); 09183 } 09184 break; 09185 } 09186 if (pwdchange & PWDCHANGE_INTERNAL) 09187 vm_change_password(vmu, newpassword); 09188 if ((pwdchange & PWDCHANGE_EXTERNAL) && !ast_strlen_zero(ext_pass_cmd)) 09189 vm_change_password_shell(vmu, newpassword); 09190 09191 ast_debug(1, "User %s set password to %s of length %d\n", 09192 vms->username, newpassword, (int) strlen(newpassword)); 09193 cmd = ast_play_and_wait(chan, vm_passchanged); 09194 break; 09195 case '*': 09196 cmd = 't'; 09197 break; 09198 default: 09199 cmd = 0; 09200 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09201 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09202 if (ast_fileexists(prefile, NULL, NULL)) { 09203 cmd = ast_play_and_wait(chan, "vm-tmpexists"); 09204 } 09205 DISPOSE(prefile, -1); 09206 if (!cmd) { 09207 cmd = ast_play_and_wait(chan, "vm-options"); 09208 } 09209 if (!cmd) { 09210 cmd = ast_waitfordigit(chan, 6000); 09211 } 09212 if (!cmd) { 09213 retries++; 09214 } 09215 if (retries > 3) { 09216 cmd = 't'; 09217 } 09218 } 09219 } 09220 if (cmd == 't') 09221 cmd = 0; 09222 return cmd; 09223 }
static int vm_play_folder_name | ( | struct ast_channel * | chan, | |
char * | mbox | |||
) | [static] |
Definition at line 7912 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().
07913 { 07914 int cmd; 07915 07916 if ( !strncasecmp(chan->language, "it", 2) || 07917 !strncasecmp(chan->language, "es", 2) || 07918 !strncasecmp(chan->language, "pt", 2)) { /* Italian, Spanish, or Portuguese syntax */ 07919 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07920 return cmd ? cmd : ast_play_and_wait(chan, box); 07921 } else if (!strncasecmp(chan->language, "gr", 2)) { 07922 return vm_play_folder_name_gr(chan, box); 07923 } else if (!strncasecmp(chan->language, "he", 2)) { /* Hebrew syntax */ 07924 return ast_play_and_wait(chan, box); 07925 } else if (!strncasecmp(chan->language, "pl", 2)) { 07926 return vm_play_folder_name_pl(chan, box); 07927 } else if (!strncasecmp(chan->language, "ua", 2)) { /* Ukrainian syntax */ 07928 return vm_play_folder_name_ua(chan, box); 07929 } else if (!strncasecmp(chan->language, "vi", 2)) { 07930 return ast_play_and_wait(chan, box); 07931 } else { /* Default English */ 07932 cmd = ast_play_and_wait(chan, box); 07933 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages */ 07934 } 07935 }
static int vm_play_folder_name_gr | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7865 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
07866 { 07867 int cmd; 07868 char *buf; 07869 07870 buf = alloca(strlen(box) + 2); 07871 strcpy(buf, box); 07872 strcat(buf, "s"); 07873 07874 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")){ 07875 cmd = ast_play_and_wait(chan, buf); /* "NEA / PALIA" */ 07876 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07877 } else { 07878 cmd = ast_play_and_wait(chan, "vm-messages"); /* "messages" -> "MYNHMATA" */ 07879 return cmd ? cmd : ast_play_and_wait(chan, box); /* friends/family/work... -> "FILWN"/"OIKOGENIAS"/"DOULEIAS"*/ 07880 } 07881 }
static int vm_play_folder_name_pl | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7883 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
07884 { 07885 int cmd; 07886 07887 if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) { 07888 if (!strcasecmp(box, "vm-INBOX")) 07889 cmd = ast_play_and_wait(chan, "vm-new-e"); 07890 else 07891 cmd = ast_play_and_wait(chan, "vm-old-e"); 07892 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07893 } else { 07894 cmd = ast_play_and_wait(chan, "vm-messages"); 07895 return cmd ? cmd : ast_play_and_wait(chan, box); 07896 } 07897 }
static int vm_play_folder_name_ua | ( | struct ast_channel * | chan, | |
char * | box | |||
) | [static] |
Definition at line 7899 of file app_voicemail_imapstorage.c.
References ast_play_and_wait().
07900 { 07901 int cmd; 07902 07903 if (!strcasecmp(box, "vm-Family") || !strcasecmp(box, "vm-Friends") || !strcasecmp(box, "vm-Work")){ 07904 cmd = ast_play_and_wait(chan, "vm-messages"); 07905 return cmd ? cmd : ast_play_and_wait(chan, box); 07906 } else { 07907 cmd = ast_play_and_wait(chan, box); 07908 return cmd ? cmd : ast_play_and_wait(chan, "vm-messages"); 07909 } 07910 }
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 9241 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_waitfordigit(), ast_vm_user::context, DELETE, DISPOSE, ast_vm_user::mailbox, play_record_review(), RETRIEVE, and vm_state::username.
09242 { 09243 int cmd = 0; 09244 int retries = 0; 09245 int duration = 0; 09246 char prefile[PATH_MAX] = ""; 09247 unsigned char buf[256]; 09248 int bytes = 0; 09249 09250 if (ast_adsi_available(chan)) { 09251 bytes += adsi_logo(buf + bytes); 09252 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Temp Greeting Menu", ""); 09253 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Not Done", ""); 09254 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 09255 bytes += ast_adsi_voice_mode(buf + bytes, 0); 09256 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 09257 } 09258 09259 snprintf(prefile, sizeof(prefile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, vms->username); 09260 while ((cmd >= 0) && (cmd != 't')) { 09261 if (cmd) 09262 retries = 0; 09263 RETRIEVE(prefile, -1, vmu->mailbox, vmu->context); 09264 if (ast_fileexists(prefile, NULL, NULL) <= 0) { 09265 play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09266 cmd = 't'; 09267 } else { 09268 switch (cmd) { 09269 case '1': 09270 cmd = play_record_review(chan, "vm-rec-temp", prefile, maxgreet, fmtc, 0, vmu, &duration, NULL, record_gain, vms, NULL); 09271 break; 09272 case '2': 09273 DELETE(prefile, -1, prefile, vmu); 09274 ast_play_and_wait(chan, "vm-tempremoved"); 09275 cmd = 't'; 09276 break; 09277 case '*': 09278 cmd = 't'; 09279 break; 09280 default: 09281 cmd = ast_play_and_wait(chan, 09282 ast_fileexists(prefile, NULL, NULL) > 0 ? /* XXX always true ? */ 09283 "vm-tempgreeting2" : "vm-tempgreeting"); 09284 if (!cmd) 09285 cmd = ast_waitfordigit(chan, 6000); 09286 if (!cmd) 09287 retries++; 09288 if (retries > 3) 09289 cmd = 't'; 09290 } 09291 } 09292 DISPOSE(prefile, -1); 09293 } 09294 if (cmd == 't') 09295 cmd = 0; 09296 return cmd; 09297 }
static int vm_users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 11129 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().
11131 { 11132 struct ast_vm_user *user; 11133 11134 AST_LIST_LOCK(&users); 11135 AST_LIST_TRAVERSE(&users, user, list) { 11136 vm_users_data_provider_get_helper(search, data_root, user); 11137 } 11138 AST_LIST_UNLOCK(&users); 11139 11140 return 0; 11141 }
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 11082 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.
11084 { 11085 struct ast_data *data_user, *data_zone; 11086 struct ast_data *data_state; 11087 struct vm_zone *zone = NULL; 11088 int urgentmsg = 0, newmsg = 0, oldmsg = 0; 11089 char ext_context[256] = ""; 11090 11091 data_user = ast_data_add_node(data_root, "user"); 11092 if (!data_user) { 11093 return -1; 11094 } 11095 11096 ast_data_add_structure(ast_vm_user, data_user, user); 11097 11098 AST_LIST_LOCK(&zones); 11099 AST_LIST_TRAVERSE(&zones, zone, list) { 11100 if (!strcmp(zone->name, user->zonetag)) { 11101 break; 11102 } 11103 } 11104 AST_LIST_UNLOCK(&zones); 11105 11106 /* state */ 11107 data_state = ast_data_add_node(data_user, "state"); 11108 if (!data_state) { 11109 return -1; 11110 } 11111 snprintf(ext_context, sizeof(ext_context), "%s@%s", user->mailbox, user->context); 11112 inboxcount2(ext_context, &urgentmsg, &newmsg, &oldmsg); 11113 ast_data_add_int(data_state, "urgentmsg", urgentmsg); 11114 ast_data_add_int(data_state, "newmsg", newmsg); 11115 ast_data_add_int(data_state, "oldmsg", oldmsg); 11116 11117 if (zone) { 11118 data_zone = ast_data_add_node(data_user, "zone"); 11119 ast_data_add_structure(vm_zone, data_zone, zone); 11120 } 11121 11122 if (!ast_data_search_match(search, data_user)) { 11123 ast_data_remove_node(data_root, data_user); 11124 } 11125 11126 return 0; 11127 }
static int vmauthenticate | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 10768 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().
10769 { 10770 char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = ""; 10771 struct ast_vm_user vmus; 10772 char *options = NULL; 10773 int silent = 0, skipuser = 0; 10774 int res = -1; 10775 10776 if (data) { 10777 s = ast_strdupa(data); 10778 user = strsep(&s, ","); 10779 options = strsep(&s, ","); 10780 if (user) { 10781 s = user; 10782 user = strsep(&s, "@"); 10783 context = strsep(&s, ""); 10784 if (!ast_strlen_zero(user)) 10785 skipuser++; 10786 ast_copy_string(mailbox, user, sizeof(mailbox)); 10787 } 10788 } 10789 10790 if (options) { 10791 silent = (strchr(options, 's')) != NULL; 10792 } 10793 10794 if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) { 10795 pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox); 10796 pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context); 10797 ast_play_and_wait(chan, "auth-thankyou"); 10798 res = 0; 10799 } else if (mailbox[0] == '*') { 10800 /* user entered '*' */ 10801 if (!ast_goto_if_exists(chan, chan->context, "a", 1)) { 10802 res = 0; /* prevent hangup */ 10803 } 10804 } 10805 10806 return res; 10807 }
static int vmsayname_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 12255 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().
12256 { 12257 char *context; 12258 char *args_copy; 12259 int res; 12260 12261 if (ast_strlen_zero(data)) { 12262 ast_log(LOG_WARNING, "VMSayName requires argument mailbox@context"); 12263 return -1; 12264 } 12265 12266 args_copy = ast_strdupa(data); 12267 if ((context = strchr(args_copy, '@'))) { 12268 *context++ = '\0'; 12269 } else { 12270 context = "default"; 12271 } 12272 12273 if ((res = sayname(chan, args_copy, context) < 0)) { 12274 ast_debug(3, "Greeting not found for '%s@%s', falling back to mailbox number.\n", args_copy, context); 12275 res = ast_stream_and_wait(chan, "vm-extension", AST_DIGIT_ANY); 12276 if (!res) { 12277 res = ast_say_character_str(chan, args_copy, AST_DIGIT_ANY, chan->language); 12278 } 12279 } 12280 12281 return res; 12282 }
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 4288 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.
04289 { 04290 const struct vm_zone *z = NULL; 04291 struct timeval t = ast_tvnow(); 04292 04293 /* Does this user have a timezone specified? */ 04294 if (!ast_strlen_zero(vmu->zonetag)) { 04295 /* Find the zone in the list */ 04296 AST_LIST_LOCK(&zones); 04297 AST_LIST_TRAVERSE(&zones, z, list) { 04298 if (!strcmp(z->name, vmu->zonetag)) 04299 break; 04300 } 04301 AST_LIST_UNLOCK(&zones); 04302 } 04303 ast_localtime(&t, tm, z ? z->timezone : NULL); 04304 return tm; 04305 }
static int wait_file | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7288 of file app_voicemail_imapstorage.c.
References ast_control_streamfile(), listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, and listen_control_stop_key.
07289 { 07290 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); 07291 }
static int wait_file2 | ( | struct ast_channel * | chan, | |
struct vm_state * | vms, | |||
char * | file | |||
) | [static] |
Definition at line 7280 of file app_voicemail_imapstorage.c.
References AST_DIGIT_ANY, ast_log(), and ast_stream_and_wait().
07281 { 07282 int res; 07283 if ((res = ast_stream_and_wait(chan, file, AST_DIGIT_ANY)) < 0) 07284 ast_log(AST_LOG_WARNING, "Unable to play message %s\n", file); 07285 return res; 07286 }
static int write_password_to_file | ( | const char * | secretfn, | |
const char * | password | |||
) | [static] |
Definition at line 12229 of file app_voicemail_imapstorage.c.
References ast_category_append(), ast_category_new(), ast_config_new(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), LOG_ERROR, and var.
12229 { 12230 struct ast_config *conf; 12231 struct ast_category *cat; 12232 struct ast_variable *var; 12233 12234 if (!(conf=ast_config_new())) { 12235 ast_log(LOG_ERROR, "Error creating new config structure\n"); 12236 return -1; 12237 } 12238 if (!(cat=ast_category_new("general","",1))) { 12239 ast_log(LOG_ERROR, "Error creating new category structure\n"); 12240 return -1; 12241 } 12242 if (!(var=ast_variable_new("password",password,""))) { 12243 ast_log(LOG_ERROR, "Error creating new variable structure\n"); 12244 return -1; 12245 } 12246 ast_category_append(conf,cat); 12247 ast_variable_append(cat,var); 12248 if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) { 12249 ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn); 12250 return -1; 12251 } 12252 return 0; 12253 }
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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } [static] |
Definition at line 13243 of file app_voicemail_imapstorage.c.
char* addesc = "Comedian Mail" [static] |
Definition at line 739 of file app_voicemail_imapstorage.c.
unsigned char adsifdn[4] = "\x00\x00\x00\x0F" [static] |
Definition at line 854 of file app_voicemail_imapstorage.c.
unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC" [static] |
Definition at line 855 of file app_voicemail_imapstorage.c.
int adsiver = 1 [static] |
Definition at line 856 of file app_voicemail_imapstorage.c.
char* app = "VoiceMail" [static] |
Definition at line 742 of file app_voicemail_imapstorage.c.
char* app2 = "VoiceMailMain" [static] |
Definition at line 745 of file app_voicemail_imapstorage.c.
char* app3 = "MailboxExists" [static] |
Definition at line 747 of file app_voicemail_imapstorage.c.
char* app4 = "VMAuthenticate" [static] |
Definition at line 748 of file app_voicemail_imapstorage.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13243 of file app_voicemail_imapstorage.c.
char callcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 840 of file app_voicemail_imapstorage.c.
char charset[32] = "ISO-8859-1" [static] |
Definition at line 852 of file app_voicemail_imapstorage.c.
char cidinternalcontexts[MAX_NUM_CID_CONTEXTS][64] [static] |
Definition at line 843 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 11005 of file app_voicemail_imapstorage.c.
char dialcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 839 of file app_voicemail_imapstorage.c.
char* emailbody = NULL [static] |
Definition at line 846 of file app_voicemail_imapstorage.c.
char emaildateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 857 of file app_voicemail_imapstorage.c.
char* emailsubject = NULL [static] |
Definition at line 847 of file app_voicemail_imapstorage.c.
char exitcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 841 of file app_voicemail_imapstorage.c.
char ext_pass_check_cmd[128] [static] |
Definition at line 719 of file app_voicemail_imapstorage.c.
char ext_pass_cmd[128] [static] |
Definition at line 718 of file app_voicemail_imapstorage.c.
char externnotify[160] [static] |
Definition at line 762 of file app_voicemail_imapstorage.c.
char fromstring[100] [static] |
Definition at line 850 of file app_voicemail_imapstorage.c.
struct ast_flags globalflags = {0} [static] |
Definition at line 835 of file app_voicemail_imapstorage.c.
struct ao2_container* inprocess_container |
Definition at line 877 of file app_voicemail_imapstorage.c.
char listen_control_forward_key[12] [static] |
Definition at line 820 of file app_voicemail_imapstorage.c.
char listen_control_pause_key[12] [static] |
Definition at line 822 of file app_voicemail_imapstorage.c.
char listen_control_restart_key[12] [static] |
Definition at line 823 of file app_voicemail_imapstorage.c.
char listen_control_reverse_key[12] [static] |
Definition at line 821 of file app_voicemail_imapstorage.c.
char listen_control_stop_key[12] [static] |
Definition at line 824 of file app_voicemail_imapstorage.c.
char locale[20] [static] |
Definition at line 755 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 10763 of file app_voicemail_imapstorage.c.
const char* const mailbox_folders[] [static] |
Definition at line 1622 of file app_voicemail_imapstorage.c.
char mailcmd[160] [static] |
Definition at line 761 of file app_voicemail_imapstorage.c.
int maxdeletedmsg [static] |
Definition at line 758 of file app_voicemail_imapstorage.c.
int maxgreet [static] |
Definition at line 768 of file app_voicemail_imapstorage.c.
int maxlogins [static] |
Definition at line 770 of file app_voicemail_imapstorage.c.
int maxmsg [static] |
Definition at line 757 of file app_voicemail_imapstorage.c.
int maxsilence [static] |
Definition at line 756 of file app_voicemail_imapstorage.c.
int minpassword [static] |
Definition at line 771 of file app_voicemail_imapstorage.c.
struct ast_event_sub* mwi_sub_sub [static] |
Subscription to ... MWI event subscriptions
Definition at line 789 of file app_voicemail_imapstorage.c.
struct ast_taskprocessor* mwi_subscription_tps [static] |
Definition at line 815 of file app_voicemail_imapstorage.c.
struct ast_event_sub* mwi_unsub_sub [static] |
Subscription to ... MWI event un-subscriptions
Definition at line 791 of file app_voicemail_imapstorage.c.
int my_umask [static] |
Definition at line 721 of file app_voicemail_imapstorage.c.
char* pagerbody = NULL [static] |
Definition at line 848 of file app_voicemail_imapstorage.c.
char pagerdateformat[32] = "%A, %B %d, %Y at %r" [static] |
Definition at line 858 of file app_voicemail_imapstorage.c.
char pagerfromstring[100] [static] |
Definition at line 851 of file app_voicemail_imapstorage.c.
char* pagersubject = NULL [static] |
Definition at line 849 of file app_voicemail_imapstorage.c.
int passwordlocation [static] |
Definition at line 772 of file app_voicemail_imapstorage.c.
ast_cond_t poll_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 784 of file app_voicemail_imapstorage.c.
unsigned int poll_freq [static] |
Polling frequency
Definition at line 779 of file app_voicemail_imapstorage.c.
ast_mutex_t poll_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 783 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 776 of file app_voicemail_imapstorage.c.
pthread_t poll_thread = AST_PTHREADT_NULL [static] |
Definition at line 785 of file app_voicemail_imapstorage.c.
unsigned char poll_thread_run [static] |
Definition at line 786 of file app_voicemail_imapstorage.c.
int pwdchange = PWDCHANGE_INTERNAL [static] |
Definition at line 725 of file app_voicemail_imapstorage.c.
int saydurationminfo [static] |
Definition at line 837 of file app_voicemail_imapstorage.c.
char* sayname_app = "VMSayName" [static] |
Definition at line 750 of file app_voicemail_imapstorage.c.
char serveremail[80] [static] |
Definition at line 760 of file app_voicemail_imapstorage.c.
int silencethreshold = 128 [static] |
Definition at line 759 of file app_voicemail_imapstorage.c.
int skipms [static] |
Definition at line 769 of file app_voicemail_imapstorage.c.
struct ast_smdi_interface* smdi_iface = NULL [static] |
Definition at line 763 of file app_voicemail_imapstorage.c.
char userscontext[AST_MAX_EXTENSION] = "default" [static] |
Definition at line 737 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 506 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 832 of file app_voicemail_imapstorage.c.
char vm_mismatch[80] = "vm-mismatch" [static] |
Definition at line 831 of file app_voicemail_imapstorage.c.
char vm_newpassword[80] = "vm-newpassword" [static] |
Definition at line 828 of file app_voicemail_imapstorage.c.
char vm_passchanged[80] = "vm-passchanged" [static] |
Definition at line 829 of file app_voicemail_imapstorage.c.
char vm_password[80] = "vm-password" [static] |
Definition at line 827 of file app_voicemail_imapstorage.c.
char vm_pls_try_again[80] = "vm-pls-try-again" [static] |
Definition at line 833 of file app_voicemail_imapstorage.c.
char vm_reenterpassword[80] = "vm-reenterpassword" [static] |
Definition at line 830 of file app_voicemail_imapstorage.c.
char VM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 716 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 11143 of file app_voicemail_imapstorage.c.
char vmfmts[80] [static] |
Definition at line 764 of file app_voicemail_imapstorage.c.
int vmmaxsecs [static] |
Definition at line 767 of file app_voicemail_imapstorage.c.
int vmminsecs [static] |
Definition at line 766 of file app_voicemail_imapstorage.c.
double volgain [static] |
Definition at line 765 of file app_voicemail_imapstorage.c.
char zonetag[80] [static] |
Definition at line 754 of file app_voicemail_imapstorage.c.