#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/event.h"
#include "asterisk/taskprocessor.h"

Go to the source code of this file.
Data Structures | |
| struct | ast_vm_user |
| struct | baseio |
| 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 | 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 | eol "\r\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 | 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 void | __fini_mwi_subs (void) |
| static int | __has_voicemail (const char *context, const char *mailbox, const char *folder, int shortcircuit) |
| static void | __init_mwi_subs (void) |
| 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. | |
| 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. | |
| 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 | 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 (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 | 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 (const char *input, char *buf, size_t buflen) |
| static const char * | substitute_escapes (const char *value) |
| static int | unload_module (void) |
| 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_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_cz (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_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 | vmauthenticate (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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| 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} |
| 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 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 | 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 = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
| 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 | 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 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 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.c.
| #define ASTERISK_USERNAME "asterisk" |
Definition at line 393 of file app_voicemail.c.
| #define BASELINELEN 72 |
| #define BASEMAXINLINE 256 |
| #define CHUNKSIZE 65536 |
Definition at line 390 of file app_voicemail.c.
| #define COMMAND_TIMEOUT 5000 |
Definition at line 386 of file app_voicemail.c.
| #define COPY | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (copy_plain_file(g,h)); |
| #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 |
By default, poll every 30 seconds
Definition at line 757 of file app_voicemail.c.
Referenced by load_config().
| #define DELETE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (vm_delete(c)) |
Definition at line 691 of file app_voicemail.c.
Referenced by close_mailbox(), notify_new_message(), play_record_review(), and vm_tempgreeting().
| #define DISPOSE | ( | a, | |||
| b | ) |
Definition at line 686 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), play_record_review(), sayname(), vm_intro(), vm_options(), and vm_tempgreeting().
| #define ENDL "\n" |
Referenced by add_email_attachment(), make_email_file(), and sendpage().
| #define eol "\r\n" |
| #define ERROR_LOCK_PATH -100 |
Definition at line 442 of file app_voicemail.c.
| #define EXISTS | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 688 of file app_voicemail.c.
Referenced by close_mailbox(), copy_message(), and save_to_folder().
| #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
Referenced by handle_voicemail_show_users().
| #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_voicemail_show_zones().
| #define INTRO "vm-intro" |
Definition at line 409 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 420 of file app_voicemail.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 421 of file app_voicemail.c.
| #define MAXMSG 100 |
| #define MAXMSGLIMIT 9999 |
Definition at line 412 of file app_voicemail.c.
Referenced by apply_option(), last_message_index(), and load_config().
| #define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 414 of file app_voicemail.c.
Referenced by load_config().
| #define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 703 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
| #define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 702 of file app_voicemail.c.
Referenced by load_config(), vm_newuser(), and vm_options().
| #define RENAME | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (rename_file(g,h)); |
Definition at line 689 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), and save_to_folder().
| #define RETRIEVE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) |
Definition at line 685 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), notify_new_message(), play_message(), sayname(), vm_intro(), vm_options(), and vm_tempgreeting().
| #define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 407 of file app_voicemail.c.
| #define SMDI_MWI_WAIT_TIMEOUT 1000 |
| #define STORE | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h, | |||||
| i, | |||||
| j | ) |
Definition at line 687 of file app_voicemail.c.
Referenced by copy_message(), forward_message(), leave_voicemail(), and play_record_review().
| #define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 712 of file app_voicemail.c.
| #define VALID_DTMF "1234567890*#" |
| #define VM_ALLOCED (1 << 13) |
Structure was malloc'ed, instead of placed in a return (usually static) buffer
Definition at line 436 of file app_voicemail.c.
Referenced by find_user(), find_user_realtime(), free_user(), and free_vm_users().
| #define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 434 of file app_voicemail.c.
Referenced by apply_option(), forward_message(), load_config(), manager_list_voicemail_users(), notify_new_message(), and sendmail().
| #define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 435 of file app_voicemail.c.
Referenced by apply_option(), manager_list_voicemail_users(), and notify_new_message().
| #define VM_DIRECFORWARD (1 << 10) |
Permit caller to use the Directory app for selecting to which mailbox to forward a VM
Definition at line 433 of file app_voicemail.c.
Referenced by forward_message(), and load_config().
| #define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 427 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_message().
| #define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 431 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().
| #define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 430 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_newuser().
| #define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 441 of file app_voicemail.c.
Referenced by forward_message(), and load_config().
| #define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 440 of file app_voicemail.c.
Referenced by apply_option(), load_config(), vm_execmain(), and vm_instructions_en().
| #define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 439 of file app_voicemail.c.
Referenced by apply_option(), close_mailbox(), and load_config().
| #define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 424 of file app_voicemail.c.
Referenced by apply_option(), leave_voicemail(), load_config(), manager_list_voicemail_users(), and play_record_review().
| #define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 432 of file app_voicemail.c.
Referenced by load_config(), and make_email_file().
| #define VM_REVIEW (1 << 0) |
After recording, permit the caller to review the recording before saving
Definition at line 423 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_record_review().
| #define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 425 of file app_voicemail.c.
Referenced by apply_option(), load_config(), manager_list_voicemail_users(), and play_message().
| #define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 428 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and play_message().
| #define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 437 of file app_voicemail.c.
Referenced by find_or_create(), find_user(), find_user_realtime(), and load_config().
| #define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 429 of file app_voicemail.c.
Referenced by load_config(), and vm_execmain().
| #define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 426 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_execmain().
| #define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 438 of file app_voicemail.c.
Referenced by apply_option(), load_config(), and vm_intro().
| #define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 629 of file app_voicemail.c.
| #define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 392 of file app_voicemail.c.
| #define VOICEMAIL_DIR_MODE 0777 |
Definition at line 388 of file app_voicemail.c.
| #define VOICEMAIL_FILE_MODE 0666 |
Definition at line 389 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), and vm_mkftemp().
| enum vm_box |
Definition at line 445 of file app_voicemail.c.
00445 { 00446 NEW_FOLDER, 00447 OLD_FOLDER, 00448 WORK_FOLDER, 00449 FAMILY_FOLDER, 00450 FRIENDS_FOLDER, 00451 GREETINGS_FOLDER 00452 };
| enum vm_option_args |
Definition at line 466 of file app_voicemail.c.
00466 { 00467 OPT_ARG_RECORDGAIN = 0, 00468 OPT_ARG_PLAYFOLDER = 1, 00469 OPT_ARG_DTMFEXIT = 2, 00470 /* This *must* be the last value in this enum! */ 00471 OPT_ARG_ARRAY_SIZE = 3, 00472 };
| 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 454 of file app_voicemail.c.
00454 { 00455 OPT_SILENT = (1 << 0), 00456 OPT_BUSY_GREETING = (1 << 1), 00457 OPT_UNAVAIL_GREETING = (1 << 2), 00458 OPT_RECORDGAIN = (1 << 3), 00459 OPT_PREPEND_MAILBOX = (1 << 4), 00460 OPT_AUTOPLAY = (1 << 6), 00461 OPT_DTMFEXIT = (1 << 7), 00462 OPT_MESSAGE_Urgent = (1 << 8), 00463 OPT_MESSAGE_PRIORITY = (1 << 9) 00464 };
| enum vm_passwordlocation |
Definition at line 474 of file app_voicemail.c.
00474 { 00475 OPT_PWLOC_VOICEMAILCONF = 0, 00476 OPT_PWLOC_SPOOLDIR = 1, 00477 OPT_PWLOC_USERSCONF = 2, 00478 };
| static void __fini_mwi_subs | ( | void | ) | [static] |
| static int __has_voicemail | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder, | |||
| int | shortcircuit | |||
| ) | [static] |
Definition at line 4991 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
04992 { 04993 DIR *dir; 04994 struct dirent *de; 04995 char fn[256]; 04996 int ret = 0; 04997 04998 /* If no mailbox, return immediately */ 04999 if (ast_strlen_zero(mailbox)) 05000 return 0; 05001 05002 if (ast_strlen_zero(folder)) 05003 folder = "INBOX"; 05004 if (ast_strlen_zero(context)) 05005 context = "default"; 05006 05007 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05008 05009 if (!(dir = opendir(fn))) 05010 return 0; 05011 05012 while ((de = readdir(dir))) { 05013 if (!strncasecmp(de->d_name, "msg", 3)) { 05014 if (shortcircuit) { 05015 ret = 1; 05016 break; 05017 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05018 if (shortcircuit) return 1; 05019 ret++; 05020 } 05021 } 05022 } 05023 05024 closedir(dir); 05025 05026 /* If we are checking INBOX, we should check Urgent as well */ 05027 if (strcmp(folder, "INBOX") == 0) { 05028 return (ret + __has_voicemail(context, mailbox, "Urgent", shortcircuit)); 05029 } else { 05030 return ret; 05031 } 05032 }
| static void __init_mwi_subs | ( | void | ) | [static] |
| static void __reg_module | ( | void | ) | [static] |
Definition at line 11897 of file app_voicemail.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 11897 of file app_voicemail.c.
| static int acf_mailbox_exists | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | args, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9992 of file app_voicemail.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().
09993 { 09994 struct ast_vm_user svm; 09995 AST_DECLARE_APP_ARGS(arg, 09996 AST_APP_ARG(mbox); 09997 AST_APP_ARG(context); 09998 ); 09999 10000 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 10001 10002 if (ast_strlen_zero(arg.mbox)) { 10003 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 10004 return -1; 10005 } 10006 10007 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 10008 return 0; 10009 }
| 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 4424 of file app_voicemail.c.
References ast_debug, ast_log(), ast_safe_system(), base_encode(), ast_vm_user::context, create_dirpath(), ENDL, LOG_WARNING, ast_vm_user::mailbox, VOICEMAIL_FILE_MODE, and ast_vm_user::volgain.
Referenced by make_email_file().
04425 { 04426 char tmpdir[256], newtmp[256]; 04427 char fname[256]; 04428 char tmpcmd[256]; 04429 int tmpfd = -1; 04430 04431 /* Eww. We want formats to tell us their own MIME type */ 04432 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 04433 04434 if (vmu->volgain < -.001 || vmu->volgain > .001) { 04435 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 04436 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 04437 tmpfd = mkstemp(newtmp); 04438 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 04439 ast_debug(3, "newtmp: %s\n", newtmp); 04440 if (tmpfd > -1) { 04441 int soxstatus; 04442 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 04443 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 04444 attach = newtmp; 04445 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 04446 } else { 04447 ast_log(LOG_WARNING, "Sox failed to reencode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 04448 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 04449 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 04450 } 04451 } 04452 } 04453 fprintf(p, "--%s" ENDL, bound); 04454 if (msgnum > -1) 04455 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 04456 else 04457 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 04458 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 04459 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 04460 if (msgnum > -1) 04461 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 04462 else 04463 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 04464 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 04465 base_encode(fname, p); 04466 if (last) 04467 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 04468 if (tmpfd > -1) { 04469 unlink(fname); 04470 close(tmpfd); 04471 unlink(newtmp); 04472 } 04473 return 0; 04474 }
| static void adsi_begin | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 5910 of file app_voicemail.c.
References adsi_load_vmail(), adsifdn, adsiver, ast_adsi_available, ast_adsi_load_session, ast_log(), and AST_LOG_WARNING.
Referenced by vm_authenticate(), and vm_execmain().
05911 { 05912 int x; 05913 if (!ast_adsi_available(chan)) 05914 return; 05915 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 05916 if (x < 0) 05917 return; 05918 if (!x) { 05919 if (adsi_load_vmail(chan, useadsi)) { 05920 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 05921 return; 05922 } 05923 } else 05924 *useadsi = 1; 05925 }
| static void adsi_delete | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6099 of file app_voicemail.c.
References ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_set_keys, ast_adsi_transmit_message, ast_adsi_voice_mode, vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.
Referenced by vm_execmain().
06100 { 06101 int bytes = 0; 06102 unsigned char buf[256]; 06103 unsigned char keys[8]; 06104 06105 int x; 06106 06107 if (!ast_adsi_available(chan)) 06108 return; 06109 06110 /* New meaning for keys */ 06111 for (x = 0; x < 5; x++) 06112 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06113 06114 keys[6] = 0x0; 06115 keys[7] = 0x0; 06116 06117 if (!vms->curmsg) { 06118 /* No prev key, provide "Folder" instead */ 06119 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06120 } 06121 if (vms->curmsg >= vms->lastmsg) { 06122 /* If last message ... */ 06123 if (vms->curmsg) { 06124 /* but not only message, provide "Folder" instead */ 06125 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06126 } else { 06127 /* Otherwise if only message, leave blank */ 06128 keys[3] = 1; 06129 } 06130 } 06131 06132 /* If deleted, show "undeleted" */ 06133 if (vms->deleted[vms->curmsg]) 06134 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06135 06136 /* Except "Exit" */ 06137 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06138 bytes += ast_adsi_set_keys(buf + bytes, keys); 06139 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06140 06141 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06142 }
| static void adsi_folders | ( | struct ast_channel * | chan, | |
| int | start, | |||
| char * | label | |||
| ) | [static] |
Definition at line 5975 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_execmain().
05976 { 05977 unsigned char buf[256]; 05978 int bytes = 0; 05979 unsigned char keys[8]; 05980 int x, y; 05981 05982 if (!ast_adsi_available(chan)) 05983 return; 05984 05985 for (x = 0; x < 5; x++) { 05986 y = ADSI_KEY_APPS + 12 + start + x; 05987 if (y > ADSI_KEY_APPS + 12 + 4) 05988 y = 0; 05989 keys[x] = ADSI_KEY_SKT | y; 05990 } 05991 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 05992 keys[6] = 0; 05993 keys[7] = 0; 05994 05995 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 05996 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 05997 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05998 bytes += ast_adsi_set_keys(buf + bytes, keys); 05999 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06000 06001 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06002 }
| static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 6247 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, ADSI_JUST_LEFT, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_execmain().
06248 { 06249 unsigned char buf[256]; 06250 int bytes = 0; 06251 06252 if (!ast_adsi_available(chan)) 06253 return; 06254 bytes += adsi_logo(buf + bytes); 06255 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 06256 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 06257 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06258 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06259 06260 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06261 }
| static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 5781 of file app_voicemail.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, mbox(), and num.
Referenced by adsi_begin().
05782 { 05783 unsigned char buf[256]; 05784 int bytes = 0; 05785 int x; 05786 char num[5]; 05787 05788 *useadsi = 0; 05789 bytes += ast_adsi_data_mode(buf + bytes); 05790 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05791 05792 bytes = 0; 05793 bytes += adsi_logo(buf); 05794 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05795 #ifdef DISPLAY 05796 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 05797 #endif 05798 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05799 bytes += ast_adsi_data_mode(buf + bytes); 05800 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05801 05802 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 05803 bytes = 0; 05804 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 05805 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05806 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05807 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05808 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05809 return 0; 05810 } 05811 05812 #ifdef DISPLAY 05813 /* Add a dot */ 05814 bytes = 0; 05815 bytes += ast_adsi_logo(buf); 05816 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 05817 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 05818 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05819 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05820 #endif 05821 bytes = 0; 05822 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 05823 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 05824 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 05825 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 05826 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 05827 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 05828 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05829 05830 #ifdef DISPLAY 05831 /* Add another dot */ 05832 bytes = 0; 05833 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 05834 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05835 05836 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05837 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05838 #endif 05839 05840 bytes = 0; 05841 /* These buttons we load but don't use yet */ 05842 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 05843 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 05844 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 05845 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 05846 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 05847 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 05848 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05849 05850 #ifdef DISPLAY 05851 /* Add another dot */ 05852 bytes = 0; 05853 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 05854 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05855 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05856 #endif 05857 05858 bytes = 0; 05859 for (x = 0; x < 5; x++) { 05860 snprintf(num, sizeof(num), "%d", x); 05861 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(x), mbox(x), num, 1); 05862 } 05863 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 05864 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05865 05866 #ifdef DISPLAY 05867 /* Add another dot */ 05868 bytes = 0; 05869 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 05870 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05871 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05872 #endif 05873 05874 if (ast_adsi_end_download(chan)) { 05875 bytes = 0; 05876 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 05877 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 05878 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05879 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05880 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05881 return 0; 05882 } 05883 bytes = 0; 05884 bytes += ast_adsi_download_disconnect(buf + bytes); 05885 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05886 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 05887 05888 ast_debug(1, "Done downloading scripts...\n"); 05889 05890 #ifdef DISPLAY 05891 /* Add last dot */ 05892 bytes = 0; 05893 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 05894 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05895 #endif 05896 ast_debug(1, "Restarting session...\n"); 05897 05898 bytes = 0; 05899 /* Load the session now */ 05900 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 05901 *useadsi = 1; 05902 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 05903 } else 05904 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 05905 05906 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05907 return 0; 05908 }
| static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5927 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_KEY_APPS, adsi_logo(), ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_input_control, ast_adsi_input_format, ast_adsi_load_soft_key, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_authenticate().
05928 { 05929 unsigned char buf[256]; 05930 int bytes = 0; 05931 unsigned char keys[8]; 05932 int x; 05933 if (!ast_adsi_available(chan)) 05934 return; 05935 05936 for (x = 0; x < 8; x++) 05937 keys[x] = 0; 05938 /* Set one key for next */ 05939 keys[3] = ADSI_KEY_APPS + 3; 05940 05941 bytes += adsi_logo(buf + bytes); 05942 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 05943 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 05944 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05945 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 05946 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 05947 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 05948 bytes += ast_adsi_set_keys(buf + bytes, keys); 05949 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05950 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05951 }
| static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 5773 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_CENT, and ast_adsi_display.
Referenced by adsi_goodbye(), adsi_load_vmail(), adsi_login(), vm_newuser(), vm_options(), and vm_tempgreeting().
05774 { 05775 int bytes = 0; 05776 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 05777 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 05778 return bytes; 05779 }
| static void adsi_message | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6004 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, ast_callerid_parse(), ast_copy_string(), ast_strlen_zero(), buf1, buf2, vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, num, and strsep().
Referenced by play_message(), and vm_execmain().
06005 { 06006 int bytes = 0; 06007 unsigned char buf[256]; 06008 char buf1[256], buf2[256]; 06009 char fn2[PATH_MAX]; 06010 06011 char cid[256] = ""; 06012 char *val; 06013 char *name, *num; 06014 char datetime[21] = ""; 06015 FILE *f; 06016 06017 unsigned char keys[8]; 06018 06019 int x; 06020 06021 if (!ast_adsi_available(chan)) 06022 return; 06023 06024 /* Retrieve important info */ 06025 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 06026 f = fopen(fn2, "r"); 06027 if (f) { 06028 while (!feof(f)) { 06029 if (!fgets((char *) buf, sizeof(buf), f)) { 06030 continue; 06031 } 06032 if (!feof(f)) { 06033 char *stringp = NULL; 06034 stringp = (char *) buf; 06035 strsep(&stringp, "="); 06036 val = strsep(&stringp, "="); 06037 if (!ast_strlen_zero(val)) { 06038 if (!strcmp((char *) buf, "callerid")) 06039 ast_copy_string(cid, val, sizeof(cid)); 06040 if (!strcmp((char *) buf, "origdate")) 06041 ast_copy_string(datetime, val, sizeof(datetime)); 06042 } 06043 } 06044 } 06045 fclose(f); 06046 } 06047 /* New meaning for keys */ 06048 for (x = 0; x < 5; x++) 06049 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 06050 keys[6] = 0x0; 06051 keys[7] = 0x0; 06052 06053 if (!vms->curmsg) { 06054 /* No prev key, provide "Folder" instead */ 06055 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06056 } 06057 if (vms->curmsg >= vms->lastmsg) { 06058 /* If last message ... */ 06059 if (vms->curmsg) { 06060 /* but not only message, provide "Folder" instead */ 06061 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 06062 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06063 06064 } else { 06065 /* Otherwise if only message, leave blank */ 06066 keys[3] = 1; 06067 } 06068 } 06069 06070 if (!ast_strlen_zero(cid)) { 06071 ast_callerid_parse(cid, &name, &num); 06072 if (!name) 06073 name = num; 06074 } else 06075 name = "Unknown Caller"; 06076 06077 /* If deleted, show "undeleted" */ 06078 06079 if (vms->deleted[vms->curmsg]) 06080 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 06081 06082 /* Except "Exit" */ 06083 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 06084 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 06085 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 06086 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 06087 06088 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06089 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06090 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 06091 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 06092 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06093 bytes += ast_adsi_set_keys(buf + bytes, keys); 06094 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06095 06096 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06097 }
| static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 5953 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_DIR_FROM_LEFT, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_input_control, ast_adsi_input_format, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, and ast_adsi_voice_mode.
Referenced by vm_authenticate().
05954 { 05955 unsigned char buf[256]; 05956 int bytes = 0; 05957 unsigned char keys[8]; 05958 int x; 05959 if (!ast_adsi_available(chan)) 05960 return; 05961 05962 for (x = 0; x < 8; x++) 05963 keys[x] = 0; 05964 /* Set one key for next */ 05965 keys[3] = ADSI_KEY_APPS + 3; 05966 05967 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 05968 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 05969 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 05970 bytes += ast_adsi_set_keys(buf + bytes, keys); 05971 bytes += ast_adsi_voice_mode(buf + bytes, 0); 05972 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 05973 }
| static void adsi_status | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6144 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, buf1, buf2, vm_state::lastmsg, vm_state::newmessages, and vm_state::oldmessages.
Referenced by vm_execmain().
06145 { 06146 unsigned char buf[256] = ""; 06147 char buf1[256] = "", buf2[256] = ""; 06148 int bytes = 0; 06149 unsigned char keys[8]; 06150 int x; 06151 06152 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 06153 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 06154 if (!ast_adsi_available(chan)) 06155 return; 06156 if (vms->newmessages) { 06157 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 06158 if (vms->oldmessages) { 06159 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 06160 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 06161 } else { 06162 snprintf(buf2, sizeof(buf2), "%s.", newm); 06163 } 06164 } else if (vms->oldmessages) { 06165 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 06166 snprintf(buf2, sizeof(buf2), "%s.", oldm); 06167 } else { 06168 strcpy(buf1, "You have no messages."); 06169 buf2[0] = ' '; 06170 buf2[1] = '\0'; 06171 } 06172 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06173 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06174 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06175 06176 for (x = 0; x < 6; x++) 06177 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06178 keys[6] = 0; 06179 keys[7] = 0; 06180 06181 /* Don't let them listen if there are none */ 06182 if (vms->lastmsg < 0) 06183 keys[0] = 1; 06184 bytes += ast_adsi_set_keys(buf + bytes, keys); 06185 06186 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06187 06188 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06189 }
| static void adsi_status2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 6191 of file app_voicemail.c.
References ADSI_COMM_PAGE, ADSI_JUST_LEFT, ADSI_KEY_APPS, ADSI_KEY_SKT, ADSI_MSG_DISPLAY, ast_adsi_available, ast_adsi_display, ast_adsi_set_keys, ast_adsi_set_line, ast_adsi_transmit_message, ast_adsi_voice_mode, buf1, buf2, vm_state::curbox, and vm_state::lastmsg.
Referenced by vm_execmain().
06192 { 06193 unsigned char buf[256] = ""; 06194 char buf1[256] = "", buf2[256] = ""; 06195 int bytes = 0; 06196 unsigned char keys[8]; 06197 int x; 06198 06199 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 06200 06201 if (!ast_adsi_available(chan)) 06202 return; 06203 06204 /* Original command keys */ 06205 for (x = 0; x < 6; x++) 06206 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 06207 06208 keys[6] = 0; 06209 keys[7] = 0; 06210 06211 if ((vms->lastmsg + 1) < 1) 06212 keys[0] = 0; 06213 06214 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 06215 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 06216 06217 if (vms->lastmsg + 1) 06218 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 06219 else 06220 strcpy(buf2, "no messages."); 06221 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 06222 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 06223 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 06224 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06225 bytes += ast_adsi_set_keys(buf + bytes, keys); 06226 06227 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06228 06229 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06230 06231 }
| 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 11473 of file app_voicemail.c.
References ast_callerid_parse(), ast_config_destroy(), ast_config_load, ast_log(), AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_strdupa, ast_strlen_zero(), ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), num, play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
11474 { 11475 int res = 0; 11476 char filename[PATH_MAX]; 11477 struct ast_config *msg_cfg = NULL; 11478 const char *origtime, *context; 11479 char *name, *num; 11480 int retries = 0; 11481 char *cid; 11482 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 11483 11484 vms->starting = 0; 11485 11486 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11487 11488 /* Retrieve info from VM attribute file */ 11489 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 11490 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 11491 msg_cfg = ast_config_load(filename, config_flags); 11492 DISPOSE(vms->curdir, vms->curmsg); 11493 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 11494 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 11495 return 0; 11496 } 11497 11498 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 11499 ast_config_destroy(msg_cfg); 11500 return 0; 11501 } 11502 11503 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 11504 11505 context = ast_variable_retrieve(msg_cfg, "message", "context"); 11506 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 11507 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 11508 switch (option) { 11509 case 3: /* Play message envelope */ 11510 if (!res) 11511 res = play_message_datetime(chan, vmu, origtime, filename); 11512 if (!res) 11513 res = play_message_callerid(chan, vms, cid, context, 0); 11514 11515 res = 't'; 11516 break; 11517 11518 case 2: /* Call back */ 11519 11520 if (ast_strlen_zero(cid)) 11521 break; 11522 11523 ast_callerid_parse(cid, &name, &num); 11524 while ((res > -1) && (res != 't')) { 11525 switch (res) { 11526 case '1': 11527 if (num) { 11528 /* Dial the CID number */ 11529 res = dialout(chan, vmu, num, vmu->callback); 11530 if (res) { 11531 ast_config_destroy(msg_cfg); 11532 return 9; 11533 } 11534 } else { 11535 res = '2'; 11536 } 11537 break; 11538 11539 case '2': 11540 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 11541 if (!ast_strlen_zero(vmu->dialout)) { 11542 res = dialout(chan, vmu, NULL, vmu->dialout); 11543 if (res) { 11544 ast_config_destroy(msg_cfg); 11545 return 9; 11546 } 11547 } else { 11548 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 11549 res = ast_play_and_wait(chan, "vm-sorry"); 11550 } 11551 ast_config_destroy(msg_cfg); 11552 return res; 11553 case '*': 11554 res = 't'; 11555 break; 11556 case '3': 11557 case '4': 11558 case '5': 11559 case '6': 11560 case '7': 11561 case '8': 11562 case '9': 11563 case '0': 11564 11565 res = ast_play_and_wait(chan, "vm-sorry"); 11566 retries++; 11567 break; 11568 default: 11569 if (num) { 11570 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 11571 res = ast_play_and_wait(chan, "vm-num-i-have"); 11572 if (!res) 11573 res = play_message_callerid(chan, vms, num, vmu->context, 1); 11574 if (!res) 11575 res = ast_play_and_wait(chan, "vm-tocallnum"); 11576 /* Only prompt for a caller-specified number if there is a dialout context specified */ 11577 if (!ast_strlen_zero(vmu->dialout)) { 11578 if (!res) 11579 res = ast_play_and_wait(chan, "vm-calldiffnum"); 11580 } 11581 } else { 11582 res = ast_play_and_wait(chan, "vm-nonumber"); 11583 if (!ast_strlen_zero(vmu->dialout)) { 11584 if (!res) 11585 res = ast_play_and_wait(chan, "vm-toenternumber"); 11586 } 11587 } 11588 if (!res) 11589 res = ast_play_and_wait(chan, "vm-star-cancel"); 11590 if (!res) 11591 res = ast_waitfordigit(chan, 6000); 11592 if (!res) { 11593 retries++; 11594 if (retries > 3) 11595 res = 't'; 11596 } 11597 break; 11598 11599 } 11600 if (res == 't') 11601 res = 0; 11602 else if (res == '*') 11603 res = -1; 11604 } 11605 break; 11606 11607 case 1: /* Reply */ 11608 /* Send reply directly to sender */ 11609 if (ast_strlen_zero(cid)) 11610 break; 11611 11612 ast_callerid_parse(cid, &name, &num); 11613 if (!num) { 11614 ast_verb(3, "No CID number available, no reply sent\n"); 11615 if (!res) 11616 res = ast_play_and_wait(chan, "vm-nonumber"); 11617 ast_config_destroy(msg_cfg); 11618 return res; 11619 } else { 11620 struct ast_vm_user vmu2; 11621 if (find_user(&vmu2, vmu->context, num)) { 11622 struct leave_vm_options leave_options; 11623 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 11624 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 11625 11626 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 11627 11628 memset(&leave_options, 0, sizeof(leave_options)); 11629 leave_options.record_gain = record_gain; 11630 res = leave_voicemail(chan, mailbox, &leave_options); 11631 if (!res) 11632 res = 't'; 11633 ast_config_destroy(msg_cfg); 11634 return res; 11635 } else { 11636 /* Sender has no mailbox, can't reply */ 11637 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 11638 ast_play_and_wait(chan, "vm-nobox"); 11639 res = 't'; 11640 ast_config_destroy(msg_cfg); 11641 return res; 11642 } 11643 } 11644 res = 0; 11645 11646 break; 11647 } 11648 11649 #ifndef IMAP_STORAGE 11650 ast_config_destroy(msg_cfg); 11651 11652 if (!res) { 11653 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 11654 vms->heard[msg] = 1; 11655 res = wait_file(chan, vms, vms->fn); 11656 } 11657 #endif 11658 return res; 11659 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | box, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 9900 of file app_voicemail.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(), s, and strsep().
Referenced by load_config().
09901 { 09902 /* Assumes lock is already held */ 09903 char *tmp; 09904 char *stringp; 09905 char *s; 09906 struct ast_vm_user *vmu; 09907 char *mailbox_full; 09908 int new = 0, old = 0, urgent = 0; 09909 char secretfn[PATH_MAX] = ""; 09910 09911 tmp = ast_strdupa(data); 09912 09913 if (!(vmu = find_or_create(context, box))) 09914 return -1; 09915 09916 populate_defaults(vmu); 09917 09918 stringp = tmp; 09919 if ((s = strsep(&stringp, ","))) { 09920 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 09921 } 09922 if (stringp && (s = strsep(&stringp, ","))) { 09923 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 09924 } 09925 if (stringp && (s = strsep(&stringp, ","))) { 09926 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 09927 } 09928 if (stringp && (s = strsep(&stringp, ","))) { 09929 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 09930 } 09931 if (stringp && (s = strsep(&stringp, ","))) { 09932 apply_options(vmu, s); 09933 } 09934 09935 switch (vmu->passwordlocation) { 09936 case OPT_PWLOC_SPOOLDIR: 09937 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 09938 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 09939 } 09940 09941 mailbox_full = alloca(strlen(box) + strlen(context) + 1); 09942 strcpy(mailbox_full, box); 09943 strcat(mailbox_full, "@"); 09944 strcat(mailbox_full, context); 09945 09946 inboxcount2(mailbox_full, &urgent, &new, &old); 09947 queue_mwi_event(mailbox_full, urgent, new, old); 09948 09949 return 0; 09950 }
| 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 914 of file app_voicemail.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::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, 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_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
00915 { 00916 int x; 00917 if (!strcasecmp(var, "attach")) { 00918 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 00919 } else if (!strcasecmp(var, "attachfmt")) { 00920 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 00921 } else if (!strcasecmp(var, "serveremail")) { 00922 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 00923 } else if (!strcasecmp(var, "language")) { 00924 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 00925 } else if (!strcasecmp(var, "tz")) { 00926 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 00927 #ifdef IMAP_STORAGE 00928 } else if (!strcasecmp(var, "imapuser")) { 00929 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 00930 vmu->imapversion = imapversion; 00931 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 00932 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 00933 vmu->imapversion = imapversion; 00934 } else if (!strcasecmp(var, "imapvmshareid")) { 00935 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 00936 vmu->imapversion = imapversion; 00937 #endif 00938 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 00939 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 00940 } else if (!strcasecmp(var, "saycid")){ 00941 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 00942 } else if (!strcasecmp(var, "sendvoicemail")){ 00943 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 00944 } else if (!strcasecmp(var, "review")){ 00945 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 00946 } else if (!strcasecmp(var, "tempgreetwarn")){ 00947 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 00948 } else if (!strcasecmp(var, "messagewrap")){ 00949 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 00950 } else if (!strcasecmp(var, "operator")) { 00951 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 00952 } else if (!strcasecmp(var, "envelope")){ 00953 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 00954 } else if (!strcasecmp(var, "moveheard")){ 00955 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 00956 } else if (!strcasecmp(var, "sayduration")){ 00957 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 00958 } else if (!strcasecmp(var, "saydurationm")){ 00959 if (sscanf(value, "%30d", &x) == 1) { 00960 vmu->saydurationm = x; 00961 } else { 00962 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 00963 } 00964 } else if (!strcasecmp(var, "forcename")){ 00965 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 00966 } else if (!strcasecmp(var, "forcegreetings")){ 00967 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 00968 } else if (!strcasecmp(var, "callback")) { 00969 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 00970 } else if (!strcasecmp(var, "dialout")) { 00971 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 00972 } else if (!strcasecmp(var, "exitcontext")) { 00973 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 00974 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 00975 vmu->maxsecs = atoi(value); 00976 if (vmu->maxsecs <= 0) { 00977 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 00978 vmu->maxsecs = vmmaxsecs; 00979 } else { 00980 vmu->maxsecs = atoi(value); 00981 } 00982 if (!strcasecmp(var, "maxmessage")) 00983 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 00984 } else if (!strcasecmp(var, "maxmsg")) { 00985 vmu->maxmsg = atoi(value); 00986 if (vmu->maxmsg <= 0) { 00987 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 00988 vmu->maxmsg = MAXMSG; 00989 } else if (vmu->maxmsg > MAXMSGLIMIT) { 00990 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 00991 vmu->maxmsg = MAXMSGLIMIT; 00992 } 00993 } else if (!strcasecmp(var, "backupdeleted")) { 00994 if (sscanf(value, "%30d", &x) == 1) 00995 vmu->maxdeletedmsg = x; 00996 else if (ast_true(value)) 00997 vmu->maxdeletedmsg = MAXMSG; 00998 else 00999 vmu->maxdeletedmsg = 0; 01000 01001 if (vmu->maxdeletedmsg < 0) { 01002 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01003 vmu->maxdeletedmsg = MAXMSG; 01004 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01005 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01006 vmu->maxdeletedmsg = MAXMSGLIMIT; 01007 } 01008 } else if (!strcasecmp(var, "volgain")) { 01009 sscanf(value, "%30lf", &vmu->volgain); 01010 } else if (!strcasecmp(var, "passwordlocation")) { 01011 if (!strcasecmp(value, "spooldir")) { 01012 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01013 } else { 01014 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01015 } 01016 } else if (!strcasecmp(var, "options")) { 01017 apply_options(vmu, value); 01018 } 01019 }
| static void apply_options | ( | struct ast_vm_user * | vmu, | |
| const char * | options | |||
| ) | [static] |
Destructively Parse options and apply.
Definition at line 1133 of file app_voicemail.c.
References apply_option(), ast_strdupa, s, strsep(), value, and var.
Referenced by append_mailbox(), and apply_option().
01134 { 01135 char *stringp; 01136 char *s; 01137 char *var, *value; 01138 stringp = ast_strdupa(options); 01139 while ((s = strsep(&stringp, "|"))) { 01140 value = s; 01141 if ((var = strsep(&value, "=")) && value) { 01142 apply_option(vmu, var, value); 01143 } 01144 } 01145 }
| 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 1152 of file app_voicemail.c.
References apply_option(), ast_copy_string(), ast_strdup, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::fullname, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::uniqueid, and ast_variable::value.
Referenced by find_user_realtime(), and load_config().
01153 { 01154 for (; var; var = var->next) { 01155 if (!strcasecmp(var->name, "vmsecret")) { 01156 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01157 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01158 if (ast_strlen_zero(retval->password)) 01159 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01160 } else if (!strcasecmp(var->name, "uniqueid")) { 01161 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01162 } else if (!strcasecmp(var->name, "pager")) { 01163 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01164 } else if (!strcasecmp(var->name, "email")) { 01165 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01166 } else if (!strcasecmp(var->name, "fullname")) { 01167 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01168 } else if (!strcasecmp(var->name, "context")) { 01169 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01170 } else if (!strcasecmp(var->name, "emailsubject")) { 01171 retval->emailsubject = ast_strdup(var->value); 01172 } else if (!strcasecmp(var->name, "emailbody")) { 01173 retval->emailbody = ast_strdup(var->value); 01174 #ifdef IMAP_STORAGE 01175 } else if (!strcasecmp(var->name, "imapuser")) { 01176 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01177 retval->imapversion = imapversion; 01178 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01179 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01180 retval->imapversion = imapversion; 01181 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01182 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01183 retval->imapversion = imapversion; 01184 #endif 01185 } else 01186 apply_option(retval, var->name, var->value); 01187 } 01188 }
| 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 4112 of file app_voicemail.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), ast_str_strlen(), and charset.
04113 { 04114 struct ast_str *tmp = ast_str_alloca(80); 04115 int first_section = 1; 04116 04117 ast_str_reset(*end); 04118 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04119 for (; *start; start++) { 04120 int need_encoding = 0; 04121 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04122 need_encoding = 1; 04123 } 04124 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04125 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04126 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04127 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04128 /* Start new line */ 04129 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04130 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04131 first_section = 0; 04132 } 04133 if (need_encoding && *start == ' ') { 04134 ast_str_append(&tmp, -1, "_"); 04135 } else if (need_encoding) { 04136 ast_str_append(&tmp, -1, "=%hhX", *start); 04137 } else { 04138 ast_str_append(&tmp, -1, "%c", *start); 04139 } 04140 } 04141 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04142 return ast_str_buffer(*end); 04143 }
| 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 4040 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04041 { 04042 const char *ptr; 04043 04044 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04045 ast_str_set(buf, maxlen, "\""); 04046 for (ptr = from; *ptr; ptr++) { 04047 if (*ptr == '"' || *ptr == '\\') { 04048 ast_str_append(buf, maxlen, "\\%c", *ptr); 04049 } else { 04050 ast_str_append(buf, maxlen, "%c", *ptr); 04051 } 04052 } 04053 ast_str_append(buf, maxlen, "\""); 04054 04055 return ast_str_buffer(*buf); 04056 }
| 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 3917 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, eol, errno, inchar(), baseio::iocp, and ochar().
03918 { 03919 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 03920 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 03921 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 03922 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 03923 int i, hiteof = 0; 03924 FILE *fi; 03925 struct baseio bio; 03926 03927 memset(&bio, 0, sizeof(bio)); 03928 bio.iocp = BASEMAXINLINE; 03929 03930 if (!(fi = fopen(filename, "rb"))) { 03931 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 03932 return -1; 03933 } 03934 03935 while (!hiteof){ 03936 unsigned char igroup[3], ogroup[4]; 03937 int c, n; 03938 03939 memset(igroup, 0, sizeof(igroup)); 03940 03941 for (n = 0; n < 3; n++) { 03942 if ((c = inchar(&bio, fi)) == EOF) { 03943 hiteof = 1; 03944 break; 03945 } 03946 03947 igroup[n] = (unsigned char) c; 03948 } 03949 03950 if (n > 0) { 03951 ogroup[0]= dtable[igroup[0] >> 2]; 03952 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 03953 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 03954 ogroup[3]= dtable[igroup[2] & 0x3F]; 03955 03956 if (n < 3) { 03957 ogroup[3] = '='; 03958 03959 if (n < 2) 03960 ogroup[2] = '='; 03961 } 03962 03963 for (i = 0; i < 4; i++) 03964 ochar(&bio, ogroup[i], so); 03965 } 03966 } 03967 03968 fclose(fi); 03969 03970 if (fputs(eol, so) == EOF) 03971 return 0; 03972 03973 return 1; 03974 }
| 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 1112 of file app_voicemail.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.
Referenced by vm_change_password().
01113 { 01114 int res = -1; 01115 if (!strcmp(vmu->password, password)) { 01116 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01117 return 0; 01118 } 01119 01120 if (strlen(password) > 10) { 01121 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01122 } 01123 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01124 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01125 res = 0; 01126 } 01127 return res; 01128 }
| 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 4085 of file app_voicemail.c.
04086 { 04087 for (; *str; str++) { 04088 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04089 return 1; 04090 } 04091 } 04092 return 0; 04093 }
| 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 1074 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_DEBUG, AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), buf, ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().
Referenced by network_thread(), vm_newuser(), and vm_options().
01075 { 01076 /* check minimum length */ 01077 if (strlen(password) < minpassword) 01078 return 1; 01079 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01080 char cmd[255], buf[255]; 01081 01082 ast_log(AST_LOG_DEBUG, "Verify password policies for %s\n", password); 01083 01084 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01085 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01086 ast_debug(5, "Result: %s\n", buf); 01087 if (!strncasecmp(buf, "VALID", 5)) { 01088 ast_debug(3, "Passed password check: '%s'\n", buf); 01089 return 0; 01090 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01091 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01092 return 0; 01093 } else { 01094 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01095 return 1; 01096 } 01097 } 01098 } 01099 return 0; 01100 }
| static int close_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 7300 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_log(), AST_LOG_WARNING, ast_test_flag, ast_unlock_path(), 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, ast_vm_user::maxmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by vm_execmain().
07301 { 07302 int x = 0; 07303 #ifndef IMAP_STORAGE 07304 int res = 0, nummsg; 07305 char fn2[PATH_MAX]; 07306 #endif 07307 07308 if (vms->lastmsg <= -1) 07309 goto done; 07310 07311 vms->curmsg = -1; 07312 #ifndef IMAP_STORAGE 07313 /* Get the deleted messages fixed */ 07314 if (vm_lock_path(vms->curdir)) 07315 return ERROR_LOCK_PATH; 07316 07317 for (x = 0; x < vmu->maxmsg; x++) { 07318 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 07319 /* Save this message. It's not in INBOX or hasn't been heard */ 07320 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07321 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 07322 break; 07323 vms->curmsg++; 07324 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 07325 if (strcmp(vms->fn, fn2)) { 07326 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 07327 } 07328 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 07329 /* Move to old folder before deleting */ 07330 res = save_to_folder(vmu, vms, x, 1); 07331 if (res == ERROR_LOCK_PATH) { 07332 /* If save failed do not delete the message */ 07333 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 07334 vms->deleted[x] = 0; 07335 vms->heard[x] = 0; 07336 --x; 07337 } 07338 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 07339 /* Move to deleted folder */ 07340 res = save_to_folder(vmu, vms, x, 10); 07341 if (res == ERROR_LOCK_PATH) { 07342 /* If save failed do not delete the message */ 07343 vms->deleted[x] = 0; 07344 vms->heard[x] = 0; 07345 --x; 07346 } 07347 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 07348 /* If realtime storage enabled - we should explicitly delete this message, 07349 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 07350 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07351 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07352 DELETE(vms->curdir, x, vms->fn, vmu); 07353 } 07354 } 07355 07356 /* Delete ALL remaining messages */ 07357 nummsg = x - 1; 07358 for (x = vms->curmsg + 1; x <= nummsg; x++) { 07359 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 07360 if (EXISTS(vms->curdir, x, vms->fn, NULL)) 07361 DELETE(vms->curdir, x, vms->fn, vmu); 07362 } 07363 ast_unlock_path(vms->curdir); 07364 #else 07365 if (vms->deleted) { 07366 for (x = 0; x < vmu->maxmsg; x++) { 07367 if (vms->deleted[x]) { 07368 ast_debug(3, "IMAP delete of %d\n", x); 07369 DELETE(vms->curdir, x, vms->fn, vmu); 07370 } 07371 } 07372 } 07373 #endif 07374 07375 done: 07376 if (vms->deleted) 07377 memset(vms->deleted, 0, vmu->maxmsg * sizeof(int)); 07378 if (vms->heard) 07379 memset(vms->heard, 0, vmu->maxmsg * sizeof(int)); 07380 07381 return 0; 07382 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 10091 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
10092 { 10093 int which = 0; 10094 int wordlen; 10095 struct ast_vm_user *vmu; 10096 const char *context = ""; 10097 10098 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 10099 if (pos > 4) 10100 return NULL; 10101 if (pos == 3) 10102 return (state == 0) ? ast_strdup("for") : NULL; 10103 wordlen = strlen(word); 10104 AST_LIST_TRAVERSE(&users, vmu, list) { 10105 if (!strncasecmp(word, vmu->context, wordlen)) { 10106 if (context && strcmp(context, vmu->context) && ++which > state) 10107 return ast_strdup(vmu->context); 10108 /* ignore repeated contexts ? */ 10109 context = vmu->context; 10110 } 10111 } 10112 return NULL; 10113 }
| 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 3723 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by ast_filehelper(), ast_func_read(), ast_func_read2(), ast_func_write(), copy_plain_file(), and iax2_register().
03724 { 03725 int ifd; 03726 int ofd; 03727 int res; 03728 int len; 03729 char buf[4096]; 03730 03731 #ifdef HARDLINK_WHEN_POSSIBLE 03732 /* Hard link if possible; saves disk space & is faster */ 03733 if (link(infile, outfile)) { 03734 #endif 03735 if ((ifd = open(infile, O_RDONLY)) < 0) { 03736 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 03737 return -1; 03738 } 03739 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 03740 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 03741 close(ifd); 03742 return -1; 03743 } 03744 do { 03745 len = read(ifd, buf, sizeof(buf)); 03746 if (len < 0) { 03747 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 03748 close(ifd); 03749 close(ofd); 03750 unlink(outfile); 03751 } 03752 if (len) { 03753 res = write(ofd, buf, len); 03754 if (errno == ENOMEM || errno == ENOSPC || res != len) { 03755 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 03756 close(ifd); 03757 close(ofd); 03758 unlink(outfile); 03759 } 03760 } 03761 } while (len); 03762 close(ifd); 03763 close(ofd); 03764 return 0; 03765 #ifdef HARDLINK_WHEN_POSSIBLE 03766 } else { 03767 /* Hard link succeeded */ 03768 return 0; 03769 } 03770 #endif 03771 }
| 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 | This is only used by file storage based mailboxes. |
Definition at line 4935 of file app_voicemail.c.
References ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_channel::language, last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), mbox(), notify_new_message(), S_OR, STORE, vm_delete(), and vm_lock_path().
Referenced by forward_message(), and leave_voicemail().
04936 { 04937 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 04938 const char *frombox = mbox(imbox); 04939 int recipmsgnum; 04940 04941 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 04942 04943 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 04944 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "Urgent"); 04945 } else { 04946 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04947 } 04948 04949 if (!dir) 04950 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 04951 else 04952 ast_copy_string(fromdir, dir, sizeof(fromdir)); 04953 04954 make_file(frompath, sizeof(frompath), fromdir, msgnum); 04955 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX"); 04956 04957 if (vm_lock_path(todir)) 04958 return ERROR_LOCK_PATH; 04959 04960 recipmsgnum = last_message_index(recip, todir) + 1; 04961 if (recipmsgnum < recip->maxmsg) { 04962 make_file(topath, sizeof(topath), todir, recipmsgnum); 04963 if (EXISTS(fromdir, msgnum, frompath, chan->language)) { 04964 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 04965 } else { 04966 /* For ODBC storage, if the file we want to copy isn't yet in the database, then the SQL 04967 * copy will fail. Instead, we need to create a local copy, store it, and delete the local 04968 * copy. We don't have to #ifdef this because if file storage reaches this point, there's a 04969 * much worse problem happening and IMAP storage doesn't call this function 04970 */ 04971 copy_plain_file(frompath, topath); 04972 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL); 04973 vm_delete(topath); 04974 } 04975 } else { 04976 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 04977 } 04978 ast_unlock_path(todir); 04979 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 04980 04981 return 0; 04982 }
| static void copy_plain_file | ( | char * | frompath, | |
| char * | topath | |||
| ) | [static] |
Copies a voicemail information (envelope) file.
| frompath | ||
| topath |
Definition at line 3782 of file app_voicemail.c.
References ast_check_realtime(), ast_filecopy(), ast_load_realtime(), ast_store_realtime(), ast_variables_destroy(), copy(), exten, ast_variable::name, ast_variable::next, SENTINEL, and ast_variable::value.
Referenced by copy_message().
03783 { 03784 char frompath2[PATH_MAX], topath2[PATH_MAX]; 03785 struct ast_variable *tmp,*var = NULL; 03786 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 03787 ast_filecopy(frompath, topath, NULL); 03788 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 03789 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 03790 if (ast_check_realtime("voicemail_data")) { 03791 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 03792 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 03793 for (tmp = var; tmp; tmp = tmp->next) { 03794 if (!strcasecmp(tmp->name, "origmailbox")) { 03795 origmailbox = tmp->value; 03796 } else if (!strcasecmp(tmp->name, "context")) { 03797 context = tmp->value; 03798 } else if (!strcasecmp(tmp->name, "macrocontext")) { 03799 macrocontext = tmp->value; 03800 } else if (!strcasecmp(tmp->name, "exten")) { 03801 exten = tmp->value; 03802 } else if (!strcasecmp(tmp->name, "priority")) { 03803 priority = tmp->value; 03804 } else if (!strcasecmp(tmp->name, "callerchan")) { 03805 callerchan = tmp->value; 03806 } else if (!strcasecmp(tmp->name, "callerid")) { 03807 callerid = tmp->value; 03808 } else if (!strcasecmp(tmp->name, "origdate")) { 03809 origdate = tmp->value; 03810 } else if (!strcasecmp(tmp->name, "origtime")) { 03811 origtime = tmp->value; 03812 } else if (!strcasecmp(tmp->name, "category")) { 03813 category = tmp->value; 03814 } else if (!strcasecmp(tmp->name, "duration")) { 03815 duration = tmp->value; 03816 } 03817 } 03818 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); 03819 } 03820 copy(frompath2, topath2); 03821 ast_variables_destroy(var); 03822 }
| 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 3626 of file app_voicemail.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), and open_mailbox().
03627 { 03628 03629 int vmcount = 0; 03630 DIR *vmdir = NULL; 03631 struct dirent *vment = NULL; 03632 03633 if (vm_lock_path(dir)) 03634 return ERROR_LOCK_PATH; 03635 03636 if ((vmdir = opendir(dir))) { 03637 while ((vment = readdir(vmdir))) { 03638 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 03639 vmcount++; 03640 } 03641 } 03642 closedir(vmdir); 03643 } 03644 ast_unlock_path(dir); 03645 03646 return vmcount; 03647 }
| 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 1492 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01493 { 01494 mode_t mode = VOICEMAIL_DIR_MODE; 01495 int res; 01496 01497 make_dir(dest, len, context, ext, folder); 01498 if ((res = ast_mkdir(dest, mode))) { 01499 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01500 return -1; 01501 } 01502 return 0; 01503 }
| static int dialout | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | num, | |||
| char * | outgoing_context | |||
| ) | [static] |
Definition at line 11401 of file app_voicemail.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.
Referenced by advanced_options(), and vm_execmain().
11402 { 11403 int cmd = 0; 11404 char destination[80] = ""; 11405 int retries = 0; 11406 11407 if (!num) { 11408 ast_verb(3, "Destination number will be entered manually\n"); 11409 while (retries < 3 && cmd != 't') { 11410 destination[1] = '\0'; 11411 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 11412 if (!cmd) 11413 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 11414 if (!cmd) 11415 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 11416 if (!cmd) { 11417 cmd = ast_waitfordigit(chan, 6000); 11418 if (cmd) 11419 destination[0] = cmd; 11420 } 11421 if (!cmd) { 11422 retries++; 11423 } else { 11424 11425 if (cmd < 0) 11426 return 0; 11427 if (cmd == '*') { 11428 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 11429 return 0; 11430 } 11431 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 11432 retries++; 11433 else 11434 cmd = 't'; 11435 } 11436 } 11437 if (retries >= 3) { 11438 return 0; 11439 } 11440 11441 } else { 11442 if (option_verbose > 2) 11443 ast_verbose( VERBOSE_PREFIX_3 "Destination number is CID number '%s'\n", num); 11444 ast_copy_string(destination, num, sizeof(destination)); 11445 } 11446 11447 if (!ast_strlen_zero(destination)) { 11448 if (destination[strlen(destination) -1 ] == '*') 11449 return 0; 11450 if (option_verbose > 2) 11451 ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, chan->context); 11452 ast_copy_string(chan->exten, destination, sizeof(chan->exten)); 11453 ast_copy_string(chan->context, outgoing_context, sizeof(chan->context)); 11454 chan->priority = 0; 11455 return 9; 11456 } 11457 return 0; 11458 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | box | |||
| ) | [static, read] |
Definition at line 9868 of file app_voicemail.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_vm_user::context, globalflags, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by append_mailbox(), and load_config().
09869 { 09870 struct ast_vm_user *vmu; 09871 09872 AST_LIST_TRAVERSE(&users, vmu, list) { 09873 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 09874 if (strcasecmp(vmu->context, context)) { 09875 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 09876 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 09877 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 09878 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 09879 } 09880 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 09881 return NULL; 09882 } 09883 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 09884 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 09885 return NULL; 09886 } 09887 } 09888 09889 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 09890 return NULL; 09891 09892 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 09893 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 09894 09895 AST_LIST_INSERT_TAIL(&users, vmu, list); 09896 09897 return vmu; 09898 }
| static struct ast_vm_user* find_user | ( | struct ast_vm_user * | ivm, | |
| const char * | context, | |||
| const char * | mailbox | |||
| ) | [static, read] |
Finds a voicemail user from the users file or the realtime engine.
| ivm | ||
| context | ||
| mailbox |
Definition at line 1259 of file app_voicemail.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, VM_ALLOCED, and VM_SEARCH.
01260 { 01261 /* This function could be made to generate one from a database, too */ 01262 struct ast_vm_user *vmu = NULL, *cur; 01263 AST_LIST_LOCK(&users); 01264 01265 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01266 context = "default"; 01267 01268 AST_LIST_TRAVERSE(&users, cur, list) { 01269 #ifdef IMAP_STORAGE 01270 if (cur->imapversion != imapversion) { 01271 continue; 01272 } 01273 #endif 01274 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01275 break; 01276 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01277 break; 01278 } 01279 if (cur) { 01280 /* Make a copy, so that on a reload, we have no race */ 01281 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01282 memcpy(vmu, cur, sizeof(*vmu)); 01283 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01284 AST_LIST_NEXT(vmu, list) = NULL; 01285 } 01286 } else 01287 vmu = find_user_realtime(ivm, context, mailbox); 01288 AST_LIST_UNLOCK(&users); 01289 return vmu; 01290 }
| static struct ast_vm_user* find_user_realtime | ( | struct ast_vm_user * | ivm, | |
| const char * | context, | |||
| const char * | mailbox | |||
| ) | [static, read] |
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 1222 of file app_voicemail.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, ast_vm_user::mailbox, populate_defaults(), SENTINEL, var, VM_ALLOCED, and VM_SEARCH.
01223 { 01224 struct ast_variable *var; 01225 struct ast_vm_user *retval; 01226 01227 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01228 if (!ivm) 01229 ast_set_flag(retval, VM_ALLOCED); 01230 else 01231 memset(retval, 0, sizeof(*retval)); 01232 if (mailbox) 01233 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01234 populate_defaults(retval); 01235 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) 01236 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01237 else 01238 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01239 if (var) { 01240 apply_options_full(retval, var); 01241 ast_variables_destroy(var); 01242 } else { 01243 if (!ivm) 01244 ast_free(retval); 01245 retval = NULL; 01246 } 01247 } 01248 return retval; 01249 }
| 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.
| ast_channel | ||
| 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 |
When in the leave message mode (is_new_message == 1):
When in the forward message mode (is_new_message == 0):
Definition at line 6601 of file app_voicemail.c.
References ast_clear_flag, ast_copy_string(), ast_fileexists(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitfordigit(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_vm_user::context, ast_channel::context, copy_message(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, ast_channel::exten, find_user(), vm_state::fn, free_user(), globalflags, ast_channel::language, leave_voicemail(), LOG_NOTICE, ast_vm_user::mailbox, pbx_exec(), pbx_findapp(), ast_channel::priority, leave_vm_options::record_gain, RETRIEVE, run_externnotify(), s, S_OR, sendmail(), STORE, strsep(), vm_state::username, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
Referenced by vm_execmain().
06602 { 06603 #ifdef IMAP_STORAGE 06604 int todircount = 0; 06605 struct vm_state *dstvms; 06606 #endif 06607 char username[70]=""; 06608 char fn[PATH_MAX]; /* for playback of name greeting */ 06609 char ecodes[16] = "#"; 06610 int res = 0, cmd = 0; 06611 struct ast_vm_user *receiver = NULL, *vmtmp; 06612 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 06613 char *stringp; 06614 const char *s; 06615 int saved_messages = 0, found = 0; 06616 int valid_extensions = 0; 06617 char *dir; 06618 int curmsg; 06619 char urgent_str[7] = ""; 06620 char tmptxtfile[PATH_MAX]; 06621 06622 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 06623 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 06624 } 06625 06626 if (vms == NULL) return -1; 06627 dir = vms->curdir; 06628 curmsg = vms->curmsg; 06629 06630 tmptxtfile[0] = '\0'; 06631 while (!res && !valid_extensions) { 06632 int use_directory = 0; 06633 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 06634 int done = 0; 06635 int retries = 0; 06636 cmd = 0; 06637 while ((cmd >= 0) && !done ){ 06638 if (cmd) 06639 retries = 0; 06640 switch (cmd) { 06641 case '1': 06642 use_directory = 0; 06643 done = 1; 06644 break; 06645 case '2': 06646 use_directory = 1; 06647 done = 1; 06648 break; 06649 case '*': 06650 cmd = 't'; 06651 done = 1; 06652 break; 06653 default: 06654 /* Press 1 to enter an extension press 2 to use the directory */ 06655 cmd = ast_play_and_wait(chan, "vm-forward"); 06656 if (!cmd) 06657 cmd = ast_waitfordigit(chan, 3000); 06658 if (!cmd) 06659 retries++; 06660 if (retries > 3) { 06661 cmd = 't'; 06662 done = 1; 06663 } 06664 06665 } 06666 } 06667 if (cmd < 0 || cmd == 't') 06668 break; 06669 } 06670 06671 if (use_directory) { 06672 /* use app_directory */ 06673 06674 char old_context[sizeof(chan->context)]; 06675 char old_exten[sizeof(chan->exten)]; 06676 int old_priority; 06677 struct ast_app* directory_app; 06678 06679 directory_app = pbx_findapp("Directory"); 06680 if (directory_app) { 06681 char vmcontext[256]; 06682 /* make backup copies */ 06683 memcpy(old_context, chan->context, sizeof(chan->context)); 06684 memcpy(old_exten, chan->exten, sizeof(chan->exten)); 06685 old_priority = chan->priority; 06686 06687 /* call the the Directory, changes the channel */ 06688 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 06689 res = pbx_exec(chan, directory_app, vmcontext); 06690 06691 ast_copy_string(username, chan->exten, sizeof(username)); 06692 06693 /* restore the old context, exten, and priority */ 06694 memcpy(chan->context, old_context, sizeof(chan->context)); 06695 memcpy(chan->exten, old_exten, sizeof(chan->exten)); 06696 chan->priority = old_priority; 06697 } else { 06698 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 06699 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 06700 } 06701 } else { 06702 /* Ask for an extension */ 06703 res = ast_streamfile(chan, "vm-extension", chan->language); /* "extension" */ 06704 if (res) 06705 break; 06706 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0)) 06707 break; 06708 } 06709 06710 /* start all over if no username */ 06711 if (ast_strlen_zero(username)) 06712 continue; 06713 stringp = username; 06714 s = strsep(&stringp, "*"); 06715 /* start optimistic */ 06716 valid_extensions = 1; 06717 while (s) { 06718 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 06719 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 06720 found++; 06721 } else { 06722 /* XXX Optimization for the future. When we encounter a single bad extension, 06723 * bailing out on all of the extensions may not be the way to go. We should 06724 * probably just bail on that single extension, then allow the user to enter 06725 * several more. XXX 06726 */ 06727 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 06728 free_user(receiver); 06729 } 06730 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 06731 valid_extensions = 0; 06732 break; 06733 } 06734 06735 /* play name if available, else play extension number */ 06736 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 06737 RETRIEVE(fn, -1, s, receiver->context); 06738 if (ast_fileexists(fn, NULL, NULL) > 0) { 06739 res = ast_stream_and_wait(chan, fn, ecodes); 06740 if (res) { 06741 DISPOSE(fn, -1); 06742 return res; 06743 } 06744 } else { 06745 res = ast_say_digit_str(chan, s, ecodes, chan->language); 06746 } 06747 DISPOSE(fn, -1); 06748 06749 s = strsep(&stringp, "*"); 06750 } 06751 /* break from the loop of reading the extensions */ 06752 if (valid_extensions) 06753 break; 06754 /* "I am sorry, that's not a valid extension. Please try again." */ 06755 res = ast_play_and_wait(chan, "pbx-invalid"); 06756 } 06757 /* check if we're clear to proceed */ 06758 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 06759 return res; 06760 if (is_new_message == 1) { 06761 struct leave_vm_options leave_options; 06762 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 06763 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 06764 06765 /* Send VoiceMail */ 06766 memset(&leave_options, 0, sizeof(leave_options)); 06767 leave_options.record_gain = record_gain; 06768 cmd = leave_voicemail(chan, mailbox, &leave_options); 06769 } else { 06770 /* Forward VoiceMail */ 06771 long duration = 0; 06772 struct vm_state vmstmp; 06773 memcpy(&vmstmp, vms, sizeof(vmstmp)); 06774 06775 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 06776 06777 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 06778 if (!cmd) { 06779 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 06780 #ifdef IMAP_STORAGE 06781 int attach_user_voicemail; 06782 char *myserveremail = serveremail; 06783 06784 /* get destination mailbox */ 06785 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 06786 if (!dstvms) { 06787 dstvms = create_vm_state_from_user(vmtmp); 06788 } 06789 if (dstvms) { 06790 init_mailstream(dstvms, 0); 06791 if (!dstvms->mailstream) { 06792 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 06793 } else { 06794 STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str); 06795 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 06796 } 06797 } else { 06798 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 06799 } 06800 if (!ast_strlen_zero(vmtmp->serveremail)) 06801 myserveremail = vmtmp->serveremail; 06802 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 06803 /* NULL category for IMAP storage */ 06804 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, dstvms->curbox, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, NULL, urgent_str); 06805 #else 06806 copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str); 06807 #endif 06808 saved_messages++; 06809 AST_LIST_REMOVE_CURRENT(list); 06810 free_user(vmtmp); 06811 if (res) 06812 break; 06813 } 06814 AST_LIST_TRAVERSE_SAFE_END; 06815 if (saved_messages > 0) { 06816 /* give confirmation that the message was saved */ 06817 /* commented out since we can't forward batches yet 06818 if (saved_messages == 1) 06819 res = ast_play_and_wait(chan, "vm-message"); 06820 else 06821 res = ast_play_and_wait(chan, "vm-messages"); 06822 if (!res) 06823 res = ast_play_and_wait(chan, "vm-saved"); */ 06824 #ifdef IMAP_STORAGE 06825 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 06826 if (ast_strlen_zero(vmstmp.introfn)) 06827 #endif 06828 res = ast_play_and_wait(chan, "vm-msgsaved"); 06829 } 06830 } 06831 DISPOSE(dir, curmsg); 06832 } 06833 06834 /* If anything failed above, we still have this list to free */ 06835 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) 06836 free_user(vmtmp); 06837 return res ? res : cmd; 06838 }
| static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1542 of file app_voicemail.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01543 { 01544 if (ast_test_flag(vmu, VM_ALLOCED)) { 01545 if (vmu->emailbody != NULL) { 01546 ast_free(vmu->emailbody); 01547 vmu->emailbody = NULL; 01548 } 01549 if (vmu->emailsubject != NULL) { 01550 ast_free(vmu->emailsubject); 01551 vmu->emailsubject = NULL; 01552 } 01553 ast_free(vmu); 01554 } 01555 }
| static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 10548 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_set_flag, free_user(), and VM_ALLOCED.
Referenced by load_config(), and unload_module().
10549 { 10550 struct ast_vm_user *current; 10551 AST_LIST_LOCK(&users); 10552 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 10553 ast_set_flag(current, VM_ALLOCED); 10554 free_user(current); 10555 } 10556 AST_LIST_UNLOCK(&users); 10557 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 10560 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by load_config(), and unload_module().
10561 { 10562 struct vm_zone *zcur; 10563 AST_LIST_LOCK(&zones); 10564 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 10565 free_zone(zcur); 10566 AST_LIST_UNLOCK(&zones); 10567 }
| static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 4702 of file app_voicemail.c.
References ast_free.
04703 { 04704 ast_free(z); 04705 }
| 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 4658 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
04659 { 04660 struct ast_tm tm; 04661 struct timeval t = ast_tvnow(); 04662 04663 ast_localtime(&t, &tm, "UTC"); 04664 04665 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 04666 }
| 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 6267 of file app_voicemail.c.
References AST_DIGIT_ANY, ast_play_and_wait(), ast_say_number(), ast_waitfordigit(), ast_channel::language, mbox(), and vm_play_folder_name().
Referenced by get_folder2().
06268 { 06269 int x; 06270 int d; 06271 char fn[PATH_MAX]; 06272 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 06273 if (d) 06274 return d; 06275 for (x = start; x < 5; x++) { /* For all folders */ 06276 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, chan->language, NULL))) 06277 return d; 06278 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 06279 if (d) 06280 return d; 06281 snprintf(fn, sizeof(fn), "vm-%s", mbox(x)); /* Folder name */ 06282 d = vm_play_folder_name(chan, fn); 06283 if (d) 06284 return d; 06285 d = ast_waitfordigit(chan, 500); 06286 if (d) 06287 return d; 06288 } 06289 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 06290 if (d) 06291 return d; 06292 d = ast_waitfordigit(chan, 4000); 06293 return d; 06294 }
| 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 6308 of file app_voicemail.c.
References ast_play_and_wait(), and get_folder().
Referenced by vm_execmain().
06309 { 06310 int res = 0; 06311 res = ast_play_and_wait(chan, fn); /* Folder name */ 06312 while (((res < '0') || (res > '9')) && 06313 (res != '#') && (res >= 0)) { 06314 res = get_folder(chan, 0); 06315 } 06316 return res; 06317 }
| static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1529 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by vm_execmain().
01530 { 01531 size_t i; 01532 01533 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01534 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01535 return i; 01536 } 01537 } 01538 01539 return -1; 01540 }
| static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 10331 of file app_voicemail.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::mailbox, mwi_sub_task::mailbox, poll_subscribed_mailbox(), mwi_sub_task::uniqueid, and mwi_sub::uniqueid.
Referenced by mwi_sub_event_cb().
10332 { 10333 unsigned int len; 10334 struct mwi_sub *mwi_sub; 10335 struct mwi_sub_task *p = datap; 10336 10337 len = sizeof(*mwi_sub); 10338 if (!ast_strlen_zero(p->mailbox)) 10339 len += strlen(p->mailbox); 10340 10341 if (!ast_strlen_zero(p->context)) 10342 len += strlen(p->context) + 1; /* Allow for seperator */ 10343 10344 if (!(mwi_sub = ast_calloc(1, len))) 10345 return -1; 10346 10347 mwi_sub->uniqueid = p->uniqueid; 10348 if (!ast_strlen_zero(p->mailbox)) 10349 strcpy(mwi_sub->mailbox, p->mailbox); 10350 10351 if (!ast_strlen_zero(p->context)) { 10352 strcat(mwi_sub->mailbox, "@"); 10353 strcat(mwi_sub->mailbox, p->context); 10354 } 10355 10356 AST_RWLIST_WRLOCK(&mwi_subs); 10357 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 10358 AST_RWLIST_UNLOCK(&mwi_subs); 10359 ast_free((void *) p->mailbox); 10360 ast_free((void *) p->context); 10361 ast_free(p); 10362 poll_subscribed_mailbox(mwi_sub); 10363 return 0; 10364 }
| static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 10309 of file app_voicemail.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_destroy(), and mwi_sub::uniqueid.
Referenced by mwi_unsub_event_cb().
10310 { 10311 struct mwi_sub *mwi_sub; 10312 uint32_t *uniqueid = datap; 10313 10314 AST_RWLIST_WRLOCK(&mwi_subs); 10315 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 10316 if (mwi_sub->uniqueid == *uniqueid) { 10317 AST_LIST_REMOVE_CURRENT(entry); 10318 break; 10319 } 10320 } 10321 AST_RWLIST_TRAVERSE_SAFE_END 10322 AST_RWLIST_UNLOCK(&mwi_subs); 10323 10324 if (mwi_sub) 10325 mwi_sub_destroy(mwi_sub); 10326 10327 ast_free(uniqueid); 10328 return 0; 10329 }
| 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 10226 of file app_voicemail.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.
10227 { 10228 switch (cmd) { 10229 case CLI_INIT: 10230 e->command = "voicemail reload"; 10231 e->usage = 10232 "Usage: voicemail reload\n" 10233 " Reload voicemail configuration\n"; 10234 return NULL; 10235 case CLI_GENERATE: 10236 return NULL; 10237 } 10238 10239 if (a->argc != 2) 10240 return CLI_SHOWUSAGE; 10241 10242 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 10243 load_config(1); 10244 10245 return CLI_SUCCESS; 10246 }
| 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 10116 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_check_realtime(), ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_voicemail_show_users(), ast_vm_user::context, ast_cli_args::fd, ast_vm_user::fullname, HVSU_OUTPUT_FORMAT, inboxcount(), ast_cli_args::line, ast_vm_user::mailbox, ast_cli_args::n, ast_cli_args::pos, show_users_realtime(), ast_cli_entry::usage, ast_cli_args::word, and ast_vm_user::zonetag.
10117 { 10118 struct ast_vm_user *vmu; 10119 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 10120 const char *context = NULL; 10121 int users_counter = 0; 10122 10123 switch (cmd) { 10124 case CLI_INIT: 10125 e->command = "voicemail show users"; 10126 e->usage = 10127 "Usage: voicemail show users [for <context>]\n" 10128 " Lists all mailboxes currently set up\n"; 10129 return NULL; 10130 case CLI_GENERATE: 10131 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 10132 } 10133 10134 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 10135 return CLI_SHOWUSAGE; 10136 if (a->argc == 5) { 10137 if (strcmp(a->argv[3],"for")) 10138 return CLI_SHOWUSAGE; 10139 context = a->argv[4]; 10140 } 10141 10142 if (ast_check_realtime("voicemail")) { 10143 if (!context) { 10144 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 10145 return CLI_SHOWUSAGE; 10146 } 10147 return show_users_realtime(a->fd, context); 10148 } 10149 10150 AST_LIST_LOCK(&users); 10151 if (AST_LIST_EMPTY(&users)) { 10152 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 10153 AST_LIST_UNLOCK(&users); 10154 return CLI_FAILURE; 10155 } 10156 if (a->argc == 3) 10157 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10158 else { 10159 int count = 0; 10160 AST_LIST_TRAVERSE(&users, vmu, list) { 10161 if (!strcmp(context, vmu->context)) 10162 count++; 10163 } 10164 if (count) { 10165 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 10166 } else { 10167 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 10168 AST_LIST_UNLOCK(&users); 10169 return CLI_FAILURE; 10170 } 10171 } 10172 AST_LIST_TRAVERSE(&users, vmu, list) { 10173 int newmsgs = 0, oldmsgs = 0; 10174 char count[12], tmp[256] = ""; 10175 10176 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(context, vmu->context))) { 10177 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 10178 inboxcount(tmp, &newmsgs, &oldmsgs); 10179 snprintf(count, sizeof(count), "%d", newmsgs); 10180 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 10181 users_counter++; 10182 } 10183 } 10184 AST_LIST_UNLOCK(&users); 10185 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 10186 return CLI_SUCCESS; 10187 }
| 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 10190 of file app_voicemail.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVSZ_OUTPUT_FORMAT, vm_zone::msg_format, vm_zone::name, vm_zone::timezone, and ast_cli_entry::usage.
10191 { 10192 struct vm_zone *zone; 10193 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 10194 char *res = CLI_SUCCESS; 10195 10196 switch (cmd) { 10197 case CLI_INIT: 10198 e->command = "voicemail show zones"; 10199 e->usage = 10200 "Usage: voicemail show zones\n" 10201 " Lists zone message formats\n"; 10202 return NULL; 10203 case CLI_GENERATE: 10204 return NULL; 10205 } 10206 10207 if (a->argc != 3) 10208 return CLI_SHOWUSAGE; 10209 10210 AST_LIST_LOCK(&zones); 10211 if (!AST_LIST_EMPTY(&zones)) { 10212 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 10213 AST_LIST_TRAVERSE(&zones, zone, list) { 10214 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 10215 } 10216 } else { 10217 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 10218 res = CLI_FAILURE; 10219 } 10220 AST_LIST_UNLOCK(&zones); 10221 10222 return res; 10223 }
| 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 5043 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), and strsep().
Referenced by dahdi_handle_event(), do_monitor(), handle_hd_hf(), handle_init_event(), handle_request(), load_module(), mgcp_hangup(), mgcp_request(), mwi_send_init(), my_has_voicemail(), and vm_execmain().
05044 { 05045 char tmp[256], *tmp2 = tmp, *box, *context; 05046 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05047 while ((box = strsep(&tmp2, ","))) { 05048 if ((context = strchr(box, '@'))) 05049 *context++ = '\0'; 05050 else 05051 context = "default"; 05052 if (__has_voicemail(context, box, folder, 1)) 05053 return 1; 05054 } 05055 return 0; 05056 }
| static int inboxcount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5115 of file app_voicemail.c.
References inboxcount2().
Referenced by handle_voicemail_show_users(), leave_voicemail(), load_module(), and manager_list_voicemail_users().
05116 { 05117 return inboxcount2(mailbox, NULL, newmsgs, oldmsgs); 05118 }
| static int inboxcount2 | ( | const char * | mailbox, | |
| int * | urgentmsgs, | |||
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5059 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), and strsep().
Referenced by append_mailbox(), inboxcount(), load_module(), poll_subscribed_mailbox(), and run_externnotify().
05060 { 05061 char tmp[256]; 05062 char *context; 05063 05064 /* If no mailbox, return immediately */ 05065 if (ast_strlen_zero(mailbox)) 05066 return 0; 05067 05068 if (newmsgs) 05069 *newmsgs = 0; 05070 if (oldmsgs) 05071 *oldmsgs = 0; 05072 if (urgentmsgs) 05073 *urgentmsgs = 0; 05074 05075 if (strchr(mailbox, ',')) { 05076 int tmpnew, tmpold, tmpurgent; 05077 char *mb, *cur; 05078 05079 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05080 mb = tmp; 05081 while ((cur = strsep(&mb, ", "))) { 05082 if (!ast_strlen_zero(cur)) { 05083 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05084 return -1; 05085 else { 05086 if (newmsgs) 05087 *newmsgs += tmpnew; 05088 if (oldmsgs) 05089 *oldmsgs += tmpold; 05090 if (urgentmsgs) 05091 *urgentmsgs += tmpurgent; 05092 } 05093 } 05094 } 05095 return 0; 05096 } 05097 05098 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05099 05100 if ((context = strchr(tmp, '@'))) 05101 *context++ = '\0'; 05102 else 05103 context = "default"; 05104 05105 if (newmsgs) 05106 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05107 if (oldmsgs) 05108 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05109 if (urgentmsgs) 05110 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05111 05112 return 0; 05113 }
| static int inbuf | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by inchar(), for base_encode()
Definition at line 3854 of file app_voicemail.c.
References baseio::ateof, BASEMAXINLINE, baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by ast_eivr_getvariable(), ast_eivr_setvariable(), inchar(), sip_addheader(), and sip_removeheader().
03855 { 03856 int l; 03857 03858 if (bio->ateof) 03859 return 0; 03860 03861 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 03862 if (ferror(fi)) 03863 return -1; 03864 03865 bio->ateof = 1; 03866 return 0; 03867 } 03868 03869 bio->iolen = l; 03870 bio->iocp = 0; 03871 03872 return 1; 03873 }
| static int inchar | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by base_encode()
Definition at line 3878 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
03879 { 03880 if (bio->iocp>=bio->iolen) { 03881 if (!inbuf(bio, fi)) 03882 return EOF; 03883 } 03884 03885 return bio->iobuf[bio->iocp++]; 03886 }
| static int invent_message | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| char * | ext, | |||
| int | busy, | |||
| char * | ecodes | |||
| ) | [static] |
Definition at line 4668 of file app_voicemail.c.
References ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, ast_channel::language, and RETRIEVE.
04669 { 04670 int res; 04671 char fn[PATH_MAX]; 04672 char dest[PATH_MAX]; 04673 04674 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 04675 04676 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 04677 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 04678 return -1; 04679 } 04680 04681 RETRIEVE(fn, -1, ext, context); 04682 if (ast_fileexists(fn, NULL, NULL) > 0) { 04683 res = ast_stream_and_wait(chan, fn, ecodes); 04684 if (res) { 04685 DISPOSE(fn, -1); 04686 return res; 04687 } 04688 } else { 04689 /* Dispose just in case */ 04690 DISPOSE(fn, -1); 04691 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 04692 if (res) 04693 return res; 04694 res = ast_say_digit_str(chan, ext, ecodes, chan->language); 04695 if (res) 04696 return res; 04697 } 04698 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 04699 return res; 04700 }
| 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 1197 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by load_config().
01198 { 01199 int i; 01200 char *local_key = ast_strdupa(key); 01201 01202 for (i = 0; i < strlen(key); ++i) { 01203 if (!strchr(VALID_DTMF, *local_key)) { 01204 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01205 return 0; 01206 } 01207 local_key++; 01208 } 01209 return 1; 01210 }
| 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 3680 of file app_voicemail.c.
References map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by copy_message(), leave_voicemail(), open_mailbox(), and save_to_folder().
03681 { 03682 int x; 03683 unsigned char map[MAXMSGLIMIT] = ""; 03684 DIR *msgdir; 03685 struct dirent *msgdirent; 03686 int msgdirint; 03687 03688 /* Reading the entire directory into a file map scales better than 03689 * doing a stat repeatedly on a predicted sequence. I suspect this 03690 * is partially due to stat(2) internally doing a readdir(2) itself to 03691 * find each file. */ 03692 if (!(msgdir = opendir(dir))) { 03693 return -1; 03694 } 03695 03696 while ((msgdirent = readdir(msgdir))) { 03697 if (sscanf(msgdirent->d_name, "msg%30d", &msgdirint) == 1 && msgdirint < MAXMSGLIMIT) 03698 map[msgdirint] = 1; 03699 } 03700 closedir(msgdir); 03701 03702 for (x = 0; x < vmu->maxmsg; x++) { 03703 if (map[x] == 0) 03704 break; 03705 } 03706 03707 return x - 1; 03708 }
| 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 5185 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_lock, ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock(), ast_mutex_unlock(), ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_create(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verbose, ast_waitstream(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_vm_user::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, ast_vm_user::exit, leave_vm_options::exitcontext, exten, ast_channel::exten, find_user(), free_user(), get_date(), inboxcount(), INTRO, invent_message(), ast_channel::language, last_message_index(), ast_channel::macrocontext, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_channel::name, vm_state::newmessages, notify_new_message(), OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, leave_vm_options::record_gain, RENAME, RETRIEVE, S_OR, SENTINEL, STORE, strsep(), transfer, VERBOSE_PREFIX_3, vm_lock_path(), VM_OPERATOR, and VOICEMAIL_FILE_MODE.
05186 { 05187 #ifdef IMAP_STORAGE 05188 int newmsgs, oldmsgs; 05189 #else 05190 char urgdir[PATH_MAX]; 05191 #endif 05192 char txtfile[PATH_MAX]; 05193 char tmptxtfile[PATH_MAX]; 05194 struct vm_state *vms = NULL; 05195 char callerid[256]; 05196 FILE *txt; 05197 char date[256]; 05198 int txtdes; 05199 int res = 0; 05200 int msgnum; 05201 int duration = 0; 05202 int ausemacro = 0; 05203 int ousemacro = 0; 05204 int ouseexten = 0; 05205 char tmpdur[16]; 05206 char priority[16]; 05207 char origtime[16]; 05208 char dir[PATH_MAX]; 05209 char tmpdir[PATH_MAX]; 05210 char fn[PATH_MAX]; 05211 char prefile[PATH_MAX] = ""; 05212 char tempfile[PATH_MAX] = ""; 05213 char ext_context[256] = ""; 05214 char fmt[80]; 05215 char *context; 05216 char ecodes[17] = "#"; 05217 struct ast_str *tmp = ast_str_create(16); 05218 char *tmpptr; 05219 struct ast_vm_user *vmu; 05220 struct ast_vm_user svm; 05221 const char *category = NULL; 05222 const char *code; 05223 const char *alldtmf = "0123456789ABCD*#"; 05224 char flag[80]; 05225 05226 if (!tmp) { 05227 return -1; 05228 } 05229 05230 ext = ast_strdupa(ext); 05231 if ((context = strchr(ext, '@'))) { 05232 *context++ = '\0'; 05233 tmpptr = strchr(context, '&'); 05234 } else { 05235 tmpptr = strchr(ext, '&'); 05236 } 05237 05238 if (tmpptr) 05239 *tmpptr++ = '\0'; 05240 05241 ast_channel_lock(chan); 05242 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 05243 category = ast_strdupa(category); 05244 } 05245 ast_channel_unlock(chan); 05246 05247 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 05248 ast_copy_string(flag, "Urgent", sizeof(flag)); 05249 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 05250 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 05251 } else { 05252 flag[0] = '\0'; 05253 } 05254 05255 ast_debug(3, "Before find_user\n"); 05256 if (!(vmu = find_user(&svm, context, ext))) { 05257 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 05258 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05259 ast_free(tmp); 05260 return res; 05261 } 05262 /* Setup pre-file if appropriate */ 05263 if (strcmp(vmu->context, "default")) 05264 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 05265 else 05266 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 05267 05268 /* Set the path to the prefile. Will be one of 05269 VM_SPOOL_DIRcontext/ext/busy 05270 VM_SPOOL_DIRcontext/ext/unavail 05271 Depending on the flag set in options. 05272 */ 05273 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 05274 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 05275 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 05276 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 05277 } 05278 /* Set the path to the tmpfile as 05279 VM_SPOOL_DIR/context/ext/temp 05280 and attempt to create the folder structure. 05281 */ 05282 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 05283 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 05284 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 05285 ast_free(tmp); 05286 return -1; 05287 } 05288 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 05289 if (ast_fileexists(tempfile, NULL, NULL) > 0) 05290 ast_copy_string(prefile, tempfile, sizeof(prefile)); 05291 05292 DISPOSE(tempfile, -1); 05293 /* It's easier just to try to make it than to check for its existence */ 05294 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 05295 05296 /* Check current or macro-calling context for special extensions */ 05297 if (ast_test_flag(vmu, VM_OPERATOR)) { 05298 if (!ast_strlen_zero(vmu->exit)) { 05299 if (ast_exists_extension(chan, vmu->exit, "o", 1, chan->cid.cid_num)) { 05300 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05301 ouseexten = 1; 05302 } 05303 } else if (ast_exists_extension(chan, chan->context, "o", 1, chan->cid.cid_num)) { 05304 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05305 ouseexten = 1; 05306 } else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "o", 1, chan->cid.cid_num)) { 05307 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 05308 ousemacro = 1; 05309 } 05310 } 05311 05312 if (!ast_strlen_zero(vmu->exit)) { 05313 if (ast_exists_extension(chan, vmu->exit, "a", 1, chan->cid.cid_num)) 05314 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05315 } else if (ast_exists_extension(chan, chan->context, "a", 1, chan->cid.cid_num)) 05316 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05317 else if (!ast_strlen_zero(chan->macrocontext) && ast_exists_extension(chan, chan->macrocontext, "a", 1, chan->cid.cid_num)) { 05318 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 05319 ausemacro = 1; 05320 } 05321 05322 if (ast_test_flag(options, OPT_DTMFEXIT)) { 05323 for (code = alldtmf; *code; code++) { 05324 char e[2] = ""; 05325 e[0] = *code; 05326 if (strchr(ecodes, e[0]) == NULL && ast_canmatch_extension(chan, chan->context, e, 1, chan->cid.cid_num)) 05327 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 05328 } 05329 } 05330 05331 /* Play the beginning intro if desired */ 05332 if (!ast_strlen_zero(prefile)) { 05333 #ifdef ODBC_STORAGE 05334 int success = 05335 #endif 05336 RETRIEVE(prefile, -1, ext, context); 05337 if (ast_fileexists(prefile, NULL, NULL) > 0) { 05338 if (ast_streamfile(chan, prefile, chan->language) > -1) 05339 res = ast_waitstream(chan, ecodes); 05340 #ifdef ODBC_STORAGE 05341 if (success == -1) { 05342 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 05343 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 05344 store_file(prefile, vmu->mailbox, vmu->context, -1); 05345 } 05346 #endif 05347 } else { 05348 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 05349 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 05350 } 05351 DISPOSE(prefile, -1); 05352 if (res < 0) { 05353 ast_debug(1, "Hang up during prefile playback\n"); 05354 free_user(vmu); 05355 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05356 ast_free(tmp); 05357 return -1; 05358 } 05359 } 05360 if (res == '#') { 05361 /* On a '#' we skip the instructions */ 05362 ast_set_flag(options, OPT_SILENT); 05363 res = 0; 05364 } 05365 if (!res && !ast_test_flag(options, OPT_SILENT)) { 05366 res = ast_stream_and_wait(chan, INTRO, ecodes); 05367 if (res == '#') { 05368 ast_set_flag(options, OPT_SILENT); 05369 res = 0; 05370 } 05371 } 05372 if (res > 0) 05373 ast_stopstream(chan); 05374 /* Check for a '*' here in case the caller wants to escape from voicemail to something 05375 other than the operator -- an automated attendant or mailbox login for example */ 05376 if (res == '*') { 05377 chan->exten[0] = 'a'; 05378 chan->exten[1] = '\0'; 05379 if (!ast_strlen_zero(vmu->exit)) { 05380 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05381 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 05382 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05383 } 05384 chan->priority = 0; 05385 free_user(vmu); 05386 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05387 ast_free(tmp); 05388 return 0; 05389 } 05390 05391 /* Check for a '0' here */ 05392 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 05393 transfer: 05394 if (ouseexten || ousemacro) { 05395 chan->exten[0] = 'o'; 05396 chan->exten[1] = '\0'; 05397 if (!ast_strlen_zero(vmu->exit)) { 05398 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 05399 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 05400 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 05401 } 05402 ast_play_and_wait(chan, "transfer"); 05403 chan->priority = 0; 05404 free_user(vmu); 05405 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05406 } 05407 ast_free(tmp); 05408 return 0; 05409 } 05410 05411 /* Allow all other digits to exit Voicemail and return to the dialplan */ 05412 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 05413 if (!ast_strlen_zero(options->exitcontext)) 05414 ast_copy_string(chan->context, options->exitcontext, sizeof(chan->context)); 05415 free_user(vmu); 05416 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 05417 ast_free(tmp); 05418 return res; 05419 } 05420 05421 if (res < 0) { 05422 free_user(vmu); 05423 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05424 ast_free(tmp); 05425 return -1; 05426 } 05427 /* The meat of recording the message... All the announcements and beeps have been played*/ 05428 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 05429 if (!ast_strlen_zero(fmt)) { 05430 msgnum = 0; 05431 05432 #ifdef IMAP_STORAGE 05433 /* Is ext a mailbox? */ 05434 /* must open stream for this user to get info! */ 05435 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 05436 if (res < 0) { 05437 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 05438 ast_free(tmp); 05439 return -1; 05440 } 05441 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 05442 /* It is possible under certain circumstances that inboxcount did not 05443 * create a vm_state when it was needed. This is a catchall which will 05444 * rarely be used. 05445 */ 05446 if (!(vms = create_vm_state_from_user(vmu))) { 05447 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 05448 ast_free(tmp); 05449 return -1; 05450 } 05451 } 05452 vms->newmessages++; 05453 05454 /* here is a big difference! We add one to it later */ 05455 msgnum = newmsgs + oldmsgs; 05456 ast_debug(3, "Messagecount set to %d\n", msgnum); 05457 snprintf(fn, sizeof(fn), "%s/imap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 05458 /* set variable for compatibility */ 05459 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05460 05461 /* Check if mailbox is full */ 05462 check_quota(vms, imapfolder); 05463 if (vms->quota_limit && vms->quota_usage >= vms->quota_limit) { 05464 ast_debug(1, "*** QUOTA EXCEEDED!! %u >= %u\n", vms->quota_usage, vms->quota_limit); 05465 ast_play_and_wait(chan, "vm-mailboxfull"); 05466 ast_free(tmp); 05467 return -1; 05468 } 05469 05470 /* Check if we have exceeded maxmsg */ 05471 if (msgnum >= vmu->maxmsg) { 05472 ast_log(AST_LOG_WARNING, "Unable to leave message since we will exceed the maximum number of messages allowed (%u > %u)\n", msgnum, vmu->maxmsg); 05473 ast_play_and_wait(chan, "vm-mailboxfull"); 05474 ast_free(tmp); 05475 return -1; 05476 } 05477 #else 05478 if (count_messages(vmu, dir) >= vmu->maxmsg) { 05479 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05480 if (!res) 05481 res = ast_waitstream(chan, ""); 05482 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 05483 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05484 goto leave_vm_out; 05485 } 05486 05487 #endif 05488 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 05489 txtdes = mkstemp(tmptxtfile); 05490 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 05491 if (txtdes < 0) { 05492 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 05493 if (!res) 05494 res = ast_waitstream(chan, ""); 05495 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 05496 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05497 goto leave_vm_out; 05498 } 05499 05500 /* Now play the beep once we have the message number for our next message. */ 05501 if (res >= 0) { 05502 /* Unless we're *really* silent, try to send the beep */ 05503 res = ast_stream_and_wait(chan, "beep", ""); 05504 } 05505 05506 /* Store information in real-time storage */ 05507 if (ast_check_realtime("voicemail_data")) { 05508 snprintf(priority, sizeof(priority), "%d", chan->priority); 05509 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 05510 get_date(date, sizeof(date)); 05511 ast_store_realtime("voicemail_data", "origmailbox", ext, "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", S_OR(category, ""), "filename", tmptxtfile, SENTINEL); 05512 } 05513 05514 /* Store information */ 05515 txt = fdopen(txtdes, "w+"); 05516 if (txt) { 05517 get_date(date, sizeof(date)); 05518 fprintf(txt, 05519 ";\n" 05520 "; Message Information file\n" 05521 ";\n" 05522 "[message]\n" 05523 "origmailbox=%s\n" 05524 "context=%s\n" 05525 "macrocontext=%s\n" 05526 "exten=%s\n" 05527 "priority=%d\n" 05528 "callerchan=%s\n" 05529 "callerid=%s\n" 05530 "origdate=%s\n" 05531 "origtime=%ld\n" 05532 "category=%s\n", 05533 ext, 05534 chan->context, 05535 chan->macrocontext, 05536 chan->exten, 05537 chan->priority, 05538 chan->name, 05539 ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"), 05540 date, (long) time(NULL), 05541 category ? category : ""); 05542 } else 05543 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 05544 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, NULL, options->record_gain, vms, flag); 05545 05546 if (txt) { 05547 fprintf(txt, "flag=%s\n", flag); 05548 if (duration < vmminsecs) { 05549 fclose(txt); 05550 if (option_verbose > 2) 05551 ast_verbose( VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs); 05552 ast_filedelete(tmptxtfile, NULL); 05553 unlink(tmptxtfile); 05554 if (ast_check_realtime("voicemail_data")) { 05555 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05556 } 05557 } else { 05558 fprintf(txt, "duration=%d\n", duration); 05559 fclose(txt); 05560 if (vm_lock_path(dir)) { 05561 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 05562 /* Delete files */ 05563 ast_filedelete(tmptxtfile, NULL); 05564 unlink(tmptxtfile); 05565 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 05566 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 05567 unlink(tmptxtfile); 05568 ast_unlock_path(dir); 05569 if (ast_check_realtime("voicemail_data")) { 05570 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 05571 } 05572 } else { 05573 #ifndef IMAP_STORAGE 05574 msgnum = last_message_index(vmu, dir) + 1; 05575 #endif 05576 make_file(fn, sizeof(fn), dir, msgnum); 05577 05578 /* assign a variable with the name of the voicemail file */ 05579 #ifndef IMAP_STORAGE 05580 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 05581 #else 05582 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 05583 #endif 05584 05585 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 05586 ast_filerename(tmptxtfile, fn, NULL); 05587 rename(tmptxtfile, txtfile); 05588 05589 /* Properly set permissions on voicemail text descriptor file. 05590 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 05591 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 05592 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 05593 05594 ast_unlock_path(dir); 05595 if (ast_check_realtime("voicemail_data")) { 05596 snprintf(tmpdur, sizeof(tmpdur), "%d", duration); 05597 ast_update_realtime("voicemail_data", "filename", tmptxtfile, "filename", fn, "duration", tmpdur, SENTINEL); 05598 } 05599 /* We must store the file first, before copying the message, because 05600 * ODBC storage does the entire copy with SQL. 05601 */ 05602 if (ast_fileexists(fn, NULL, NULL) > 0) { 05603 STORE(dir, vmu->mailbox, vmu->context, msgnum, chan, vmu, fmt, duration, vms, flag); 05604 } 05605 05606 /* Are there to be more recipients of this message? */ 05607 while (tmpptr) { 05608 struct ast_vm_user recipu, *recip; 05609 char *exten, *cntx; 05610 05611 exten = strsep(&tmpptr, "&"); 05612 cntx = strchr(exten, '@'); 05613 if (cntx) { 05614 *cntx = '\0'; 05615 cntx++; 05616 } 05617 if ((recip = find_user(&recipu, cntx, exten))) { 05618 copy_message(chan, vmu, 0, msgnum, duration, recip, fmt, dir, flag); 05619 free_user(recip); 05620 } 05621 } 05622 #ifndef IMAP_STORAGE 05623 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If this is an Urgent message */ 05624 /* Move the message from INBOX to Urgent folder if this is urgent! */ 05625 char sfn[PATH_MAX]; 05626 char dfn[PATH_MAX]; 05627 int x; 05628 /* It's easier just to try to make it than to check for its existence */ 05629 create_dirpath(urgdir, sizeof(urgdir), vmu->context, ext, "Urgent"); 05630 ast_debug(5, "Created an Urgent message, moving file from %s to %s.\n", sfn, dfn); 05631 x = last_message_index(vmu, urgdir) + 1; 05632 make_file(sfn, sizeof(sfn), dir, msgnum); 05633 make_file(dfn, sizeof(dfn), urgdir, x); 05634 RENAME(dir, msgnum, vmu->mailbox, vmu->context, urgdir, x, sfn, dfn); 05635 } 05636 #endif 05637 /* Notification needs to happen after the copy, though. */ 05638 if (ast_fileexists(fn, NULL, NULL)) { 05639 #ifdef IMAP_STORAGE 05640 notify_new_message(chan, vmu, vms, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05641 #else 05642 notify_new_message(chan, vmu, NULL, msgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag); 05643 #endif 05644 } 05645 05646 /* Disposal needs to happen after the optional move and copy */ 05647 if (ast_fileexists(fn, NULL, NULL)) { 05648 DISPOSE(dir, msgnum); 05649 } 05650 } 05651 } 05652 } 05653 if (res == '0') { 05654 goto transfer; 05655 } else if (res > 0) 05656 res = 0; 05657 05658 if (duration < vmminsecs) 05659 /* XXX We should really give a prompt too short/option start again, with leave_vm_out called only after a timeout XXX */ 05660 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 05661 else 05662 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 05663 } else 05664 ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n"); 05665 leave_vm_out: 05666 free_user(vmu); 05667 05668 #ifdef IMAP_STORAGE 05669 /* expunge message - use UID Expunge if supported on IMAP server*/ 05670 ast_debug(3, "*** Checking if we can expunge, expungeonhangup set to %d\n", expungeonhangup); 05671 if (expungeonhangup == 1) { 05672 ast_mutex_lock(&vms->lock); 05673 #ifdef HAVE_IMAP_TK2006 05674 if (LEVELUIDPLUS (vms->mailstream)) { 05675 mail_expunge_full(vms->mailstream, NIL, EX_UID); 05676 } else 05677 #endif 05678 mail_expunge(vms->mailstream); 05679 ast_mutex_unlock(&vms->lock); 05680 } 05681 #endif 05682 05683 ast_free(tmp); 05684 return res; 05685 }
| static int load_config | ( | int | reload | ) | [static] |
Definition at line 10613 of file app_voicemail.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_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_DEBUG, AST_LOG_ERROR, AST_LOG_WARNING, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_unload_realtime(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, charset, cidinternalcontexts, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, ast_vm_user::context, DEFAULT_LISTEN_CONTROL_FORWARD_KEY, DEFAULT_LISTEN_CONTROL_PAUSE_KEY, DEFAULT_LISTEN_CONTROL_RESTART_KEY, DEFAULT_LISTEN_CONTROL_REVERSE_KEY, DEFAULT_LISTEN_CONTROL_STOP_KEY, DEFAULT_POLL_FREQ, dialcontext, emailbody, emaildateformat, emailsubject, exitcontext, find_or_create(), free_vm_users(), free_vm_zones(), fromstring, globalflags, is_valid_dtmf(), ast_variable::lineno, listen_control_forward_key, listen_control_pause_key, listen_control_restart_key, listen_control_reverse_key, listen_control_stop_key, LOG_ERROR, ast_vm_user::mailbox, MAX_NUM_CID_CONTEXTS, MAXMSG, MAXMSGLIMIT, MINPASSWORD, vm_zone::msg_format, vm_zone::name, ast_variable::name, ast_variable::next, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_USERSCONF, OPT_PWLOC_VOICEMAILCONF, pagerbody, pagerfromstring, pagersubject, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), PWDCHANGE_EXTERNAL, PWDCHANGE_INTERNAL, read_password_from_file(), saydurationminfo, SENDMAIL, start_poll_thread(), stop_poll_thread(), strsep(), substitute_escapes(), THRESHOLD_SILENCE, vm_zone::timezone, ast_variable::value, 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.
10614 { 10615 struct ast_vm_user *current; 10616 struct ast_config *cfg, *ucfg; 10617 char *cat; 10618 struct ast_variable *var; 10619 const char *val; 10620 char *q, *stringp; 10621 int x; 10622 int tmpadsi[4]; 10623 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 10624 char secretfn[PATH_MAX] = ""; 10625 10626 ast_unload_realtime("voicemail"); 10627 ast_unload_realtime("voicemail_data"); 10628 10629 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 10630 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) { 10631 return 0; 10632 } else if (ucfg == CONFIG_STATUS_FILEINVALID) { 10633 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 10634 ucfg = NULL; 10635 } 10636 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10637 if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) == CONFIG_STATUS_FILEINVALID) { 10638 ast_config_destroy(ucfg); 10639 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 10640 return 0; 10641 } 10642 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 10643 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 10644 return 0; 10645 } else { 10646 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 10647 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 10648 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Avoiding.\n"); 10649 ucfg = NULL; 10650 } 10651 } 10652 #ifdef IMAP_STORAGE 10653 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 10654 #endif 10655 /* set audio control prompts */ 10656 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 10657 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 10658 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 10659 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 10660 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 10661 10662 /* Free all the users structure */ 10663 free_vm_users(); 10664 10665 /* Free all the zones structure */ 10666 free_vm_zones(); 10667 10668 AST_LIST_LOCK(&users); 10669 10670 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 10671 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 10672 10673 if (cfg) { 10674 /* General settings */ 10675 10676 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 10677 val = "default"; 10678 ast_copy_string(userscontext, val, sizeof(userscontext)); 10679 /* Attach voice message to mail message ? */ 10680 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 10681 val = "yes"; 10682 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 10683 10684 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 10685 val = "no"; 10686 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 10687 10688 volgain = 0.0; 10689 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 10690 sscanf(val, "%30lf", &volgain); 10691 10692 #ifdef ODBC_STORAGE 10693 strcpy(odbc_database, "asterisk"); 10694 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 10695 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 10696 } 10697 strcpy(odbc_table, "voicemessages"); 10698 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 10699 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 10700 } 10701 #endif 10702 /* Mail command */ 10703 strcpy(mailcmd, SENDMAIL); 10704 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 10705 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 10706 10707 maxsilence = 0; 10708 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 10709 maxsilence = atoi(val); 10710 if (maxsilence > 0) 10711 maxsilence *= 1000; 10712 } 10713 10714 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 10715 maxmsg = MAXMSG; 10716 } else { 10717 maxmsg = atoi(val); 10718 if (maxmsg <= 0) { 10719 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 10720 maxmsg = MAXMSG; 10721 } else if (maxmsg > MAXMSGLIMIT) { 10722 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10723 maxmsg = MAXMSGLIMIT; 10724 } 10725 } 10726 10727 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 10728 maxdeletedmsg = 0; 10729 } else { 10730 if (sscanf(val, "%30d", &x) == 1) 10731 maxdeletedmsg = x; 10732 else if (ast_true(val)) 10733 maxdeletedmsg = MAXMSG; 10734 else 10735 maxdeletedmsg = 0; 10736 10737 if (maxdeletedmsg < 0) { 10738 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 10739 maxdeletedmsg = MAXMSG; 10740 } else if (maxdeletedmsg > MAXMSGLIMIT) { 10741 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 10742 maxdeletedmsg = MAXMSGLIMIT; 10743 } 10744 } 10745 10746 /* Load date format config for voicemail mail */ 10747 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 10748 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 10749 } 10750 10751 /* External password changing command */ 10752 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 10753 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 10754 pwdchange = PWDCHANGE_EXTERNAL; 10755 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 10756 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 10757 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 10758 } 10759 10760 /* External password validation command */ 10761 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 10762 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 10763 ast_log(AST_LOG_DEBUG, "found externpasscheck: %s\n", ext_pass_check_cmd); 10764 } 10765 10766 #ifdef IMAP_STORAGE 10767 /* IMAP server address */ 10768 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 10769 ast_copy_string(imapserver, val, sizeof(imapserver)); 10770 } else { 10771 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 10772 } 10773 /* IMAP server port */ 10774 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 10775 ast_copy_string(imapport, val, sizeof(imapport)); 10776 } else { 10777 ast_copy_string(imapport, "143", sizeof(imapport)); 10778 } 10779 /* IMAP server flags */ 10780 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 10781 ast_copy_string(imapflags, val, sizeof(imapflags)); 10782 } 10783 /* IMAP server master username */ 10784 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 10785 ast_copy_string(authuser, val, sizeof(authuser)); 10786 } 10787 /* IMAP server master password */ 10788 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 10789 ast_copy_string(authpassword, val, sizeof(authpassword)); 10790 } 10791 /* Expunge on exit */ 10792 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 10793 if (ast_false(val)) 10794 expungeonhangup = 0; 10795 else 10796 expungeonhangup = 1; 10797 } else { 10798 expungeonhangup = 1; 10799 } 10800 /* IMAP voicemail folder */ 10801 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 10802 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 10803 } else { 10804 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 10805 } 10806 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 10807 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 10808 } 10809 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 10810 imapgreetings = ast_true(val); 10811 } else { 10812 imapgreetings = 0; 10813 } 10814 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 10815 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 10816 } else { 10817 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 10818 } 10819 10820 /* There is some very unorthodox casting done here. This is due 10821 * to the way c-client handles the argument passed in. It expects a 10822 * void pointer and casts the pointer directly to a long without 10823 * first dereferencing it. */ 10824 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 10825 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 10826 } else { 10827 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 10828 } 10829 10830 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 10831 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 10832 } else { 10833 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 10834 } 10835 10836 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 10837 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 10838 } else { 10839 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 10840 } 10841 10842 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 10843 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 10844 } else { 10845 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 10846 } 10847 10848 /* Increment configuration version */ 10849 imapversion++; 10850 #endif 10851 /* External voicemail notify application */ 10852 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 10853 ast_copy_string(externnotify, val, sizeof(externnotify)); 10854 ast_debug(1, "found externnotify: %s\n", externnotify); 10855 } else { 10856 externnotify[0] = '\0'; 10857 } 10858 10859 /* SMDI voicemail notification */ 10860 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 10861 ast_debug(1, "Enabled SMDI voicemail notification\n"); 10862 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 10863 smdi_iface = ast_smdi_interface_find(val); 10864 } else { 10865 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 10866 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 10867 } 10868 if (!smdi_iface) { 10869 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 10870 } 10871 } 10872 10873 /* Silence treshold */ 10874 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 10875 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 10876 silencethreshold = atoi(val); 10877 10878 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 10879 val = ASTERISK_USERNAME; 10880 ast_copy_string(serveremail, val, sizeof(serveremail)); 10881 10882 vmmaxsecs = 0; 10883 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 10884 if (sscanf(val, "%30d", &x) == 1) { 10885 vmmaxsecs = x; 10886 } else { 10887 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10888 } 10889 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 10890 static int maxmessage_deprecate = 0; 10891 if (maxmessage_deprecate == 0) { 10892 maxmessage_deprecate = 1; 10893 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 10894 } 10895 if (sscanf(val, "%30d", &x) == 1) { 10896 vmmaxsecs = x; 10897 } else { 10898 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 10899 } 10900 } 10901 10902 vmminsecs = 0; 10903 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 10904 if (sscanf(val, "%30d", &x) == 1) { 10905 vmminsecs = x; 10906 if (maxsilence / 1000 >= vmminsecs) { 10907 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 10908 } 10909 } else { 10910 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10911 } 10912 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 10913 static int maxmessage_deprecate = 0; 10914 if (maxmessage_deprecate == 0) { 10915 maxmessage_deprecate = 1; 10916 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 10917 } 10918 if (sscanf(val, "%30d", &x) == 1) { 10919 vmminsecs = x; 10920 if (maxsilence / 1000 >= vmminsecs) { 10921 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 10922 } 10923 } else { 10924 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 10925 } 10926 } 10927 10928 val = ast_variable_retrieve(cfg, "general", "format"); 10929 if (!val) 10930 val = "wav"; 10931 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 10932 10933 skipms = 3000; 10934 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 10935 if (sscanf(val, "%30d", &x) == 1) { 10936 maxgreet = x; 10937 } else { 10938 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 10939 } 10940 } 10941 10942 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 10943 if (sscanf(val, "%30d", &x) == 1) { 10944 skipms = x; 10945 } else { 10946 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 10947 } 10948 } 10949 10950 maxlogins = 3; 10951 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 10952 if (sscanf(val, "%30d", &x) == 1) { 10953 maxlogins = x; 10954 } else { 10955 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 10956 } 10957 } 10958 10959 minpassword = MINPASSWORD; 10960 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 10961 if (sscanf(val, "%30d", &x) == 1) { 10962 minpassword = x; 10963 } else { 10964 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 10965 } 10966 } 10967 10968 /* Force new user to record name ? */ 10969 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 10970 val = "no"; 10971 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 10972 10973 /* Force new user to record greetings ? */ 10974 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 10975 val = "no"; 10976 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 10977 10978 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 10979 ast_debug(1, "VM_CID Internal context string: %s\n", val); 10980 stringp = ast_strdupa(val); 10981 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 10982 if (!ast_strlen_zero(stringp)) { 10983 q = strsep(&stringp, ","); 10984 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 10985 q++; 10986 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 10987 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 10988 } else { 10989 cidinternalcontexts[x][0] = '\0'; 10990 } 10991 } 10992 } 10993 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 10994 ast_debug(1, "VM Review Option disabled globally\n"); 10995 val = "no"; 10996 } 10997 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 10998 10999 /* Temporary greeting reminder */ 11000 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 11001 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 11002 val = "no"; 11003 } else { 11004 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 11005 } 11006 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 11007 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 11008 ast_debug(1, "VM next message wrap disabled globally\n"); 11009 val = "no"; 11010 } 11011 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 11012 11013 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 11014 ast_debug(1, "VM Operator break disabled globally\n"); 11015 val = "no"; 11016 } 11017 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 11018 11019 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 11020 ast_debug(1, "VM CID Info before msg disabled globally\n"); 11021 val = "no"; 11022 } 11023 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 11024 11025 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 11026 ast_debug(1, "Send Voicemail msg disabled globally\n"); 11027 val = "no"; 11028 } 11029 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 11030 11031 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 11032 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 11033 val = "yes"; 11034 } 11035 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 11036 11037 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 11038 ast_debug(1, "Move Heard enabled globally\n"); 11039 val = "yes"; 11040 } 11041 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 11042 11043 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 11044 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 11045 val = "no"; 11046 } 11047 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 11048 11049 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 11050 ast_debug(1, "Duration info before msg enabled globally\n"); 11051 val = "yes"; 11052 } 11053 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 11054 11055 saydurationminfo = 2; 11056 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 11057 if (sscanf(val, "%30d", &x) == 1) { 11058 saydurationminfo = x; 11059 } else { 11060 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 11061 } 11062 } 11063 11064 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 11065 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 11066 val = "no"; 11067 } 11068 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 11069 11070 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 11071 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 11072 ast_debug(1, "found dialout context: %s\n", dialcontext); 11073 } else { 11074 dialcontext[0] = '\0'; 11075 } 11076 11077 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 11078 ast_copy_string(callcontext, val, sizeof(callcontext)); 11079 ast_debug(1, "found callback context: %s\n", callcontext); 11080 } else { 11081 callcontext[0] = '\0'; 11082 } 11083 11084 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 11085 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 11086 ast_debug(1, "found operator context: %s\n", exitcontext); 11087 } else { 11088 exitcontext[0] = '\0'; 11089 } 11090 11091 /* load password sounds configuration */ 11092 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 11093 ast_copy_string(vm_password, val, sizeof(vm_password)); 11094 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 11095 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 11096 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 11097 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 11098 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 11099 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 11100 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 11101 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 11102 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 11103 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 11104 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 11105 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 11106 } 11107 /* load configurable audio prompts */ 11108 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 11109 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 11110 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 11111 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 11112 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 11113 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 11114 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 11115 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 11116 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 11117 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 11118 11119 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 11120 val = "no"; 11121 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 11122 11123 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 11124 val = "voicemail.conf"; 11125 } 11126 if (!(strcmp(val, "spooldir"))) { 11127 passwordlocation = OPT_PWLOC_SPOOLDIR; 11128 } else { 11129 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 11130 } 11131 11132 poll_freq = DEFAULT_POLL_FREQ; 11133 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 11134 if (sscanf(val, "%30u", &poll_freq) != 1) { 11135 poll_freq = DEFAULT_POLL_FREQ; 11136 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 11137 } 11138 } 11139 11140 poll_mailboxes = 0; 11141 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 11142 poll_mailboxes = ast_true(val); 11143 11144 if (ucfg) { 11145 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 11146 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 11147 continue; 11148 if ((current = find_or_create(userscontext, cat))) { 11149 populate_defaults(current); 11150 apply_options_full(current, ast_variable_browse(ucfg, cat)); 11151 ast_copy_string(current->context, userscontext, sizeof(current->context)); 11152 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 11153 current->passwordlocation = OPT_PWLOC_USERSCONF; 11154 } 11155 11156 switch (current->passwordlocation) { 11157 case OPT_PWLOC_SPOOLDIR: 11158 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 11159 read_password_from_file(secretfn, current->password, sizeof(current->password)); 11160 } 11161 } 11162 } 11163 ast_config_destroy(ucfg); 11164 } 11165 cat = ast_category_browse(cfg, NULL); 11166 while (cat) { 11167 if (strcasecmp(cat, "general")) { 11168 var = ast_variable_browse(cfg, cat); 11169 if (strcasecmp(cat, "zonemessages")) { 11170 /* Process mailboxes in this context */ 11171 while (var) { 11172 append_mailbox(cat, var->name, var->value); 11173 var = var->next; 11174 } 11175 } else { 11176 /* Timezones in this context */ 11177 while (var) { 11178 struct vm_zone *z; 11179 if ((z = ast_malloc(sizeof(*z)))) { 11180 char *msg_format, *tzone; 11181 msg_format = ast_strdupa(var->value); 11182 tzone = strsep(&msg_format, "|"); 11183 if (msg_format) { 11184 ast_copy_string(z->name, var->name, sizeof(z->name)); 11185 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 11186 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 11187 AST_LIST_LOCK(&zones); 11188 AST_LIST_INSERT_HEAD(&zones, z, list); 11189 AST_LIST_UNLOCK(&zones); 11190 } else { 11191 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 11192 ast_free(z); 11193 } 11194 } else { 11195 AST_LIST_UNLOCK(&users); 11196 ast_config_destroy(cfg); 11197 return -1; 11198 } 11199 var = var->next; 11200 } 11201 } 11202 } 11203 cat = ast_category_browse(cfg, cat); 11204 } 11205 memset(fromstring, 0, sizeof(fromstring)); 11206 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 11207 strcpy(charset, "ISO-8859-1"); 11208 if (emailbody) { 11209 ast_free(emailbody); 11210 emailbody = NULL; 11211 } 11212 if (emailsubject) { 11213 ast_free(emailsubject); 11214 emailsubject = NULL; 11215 } 11216 if (pagerbody) { 11217 ast_free(pagerbody); 11218 pagerbody = NULL; 11219 } 11220 if (pagersubject) { 11221 ast_free(pagersubject); 11222 pagersubject = NULL; 11223 } 11224 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 11225 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 11226 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 11227 ast_copy_string(fromstring, val, sizeof(fromstring)); 11228 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 11229 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 11230 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 11231 ast_copy_string(charset, val, sizeof(charset)); 11232 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 11233 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 11234 for (x = 0; x < 4; x++) { 11235 memcpy(&adsifdn[x], &tmpadsi[x], 1); 11236 } 11237 } 11238 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 11239 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 11240 for (x = 0; x < 4; x++) { 11241 memcpy(&adsisec[x], &tmpadsi[x], 1); 11242 } 11243 } 11244 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 11245 if (atoi(val)) { 11246 adsiver = atoi(val); 11247 } 11248 } 11249 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 11250 ast_copy_string(zonetag, val, sizeof(zonetag)); 11251 } 11252 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 11253 emailsubject = ast_strdup(val); 11254 } 11255 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 11256 emailbody = ast_strdup(substitute_escapes(val)); 11257 } 11258 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 11259 pagersubject = ast_strdup(val); 11260 } 11261 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 11262 pagerbody = ast_strdup(substitute_escapes(val)); 11263 } 11264 AST_LIST_UNLOCK(&users); 11265 ast_config_destroy(cfg); 11266 11267 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 11268 start_poll_thread(); 11269 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 11270 stop_poll_thread();; 11271 11272 return 0; 11273 } else { 11274 AST_LIST_UNLOCK(&users); 11275 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 11276 if (ucfg) 11277 ast_config_destroy(ucfg); 11278 return 0; 11279 } 11280 }
| static int load_module | ( | void | ) | [static] |
Definition at line 11367 of file app_voicemail.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_install_vm_functions(), ast_log(), AST_LOG_WARNING, ast_manager_register_xml, ast_realtime_require_field(), ast_register_application_xml, ast_taskprocessor_get(), cli_voicemail, EVENT_FLAG_CALL, EVENT_FLAG_REPORTING, has_voicemail(), inboxcount(), inboxcount2(), load_config(), mailbox_exists_acf, manager_list_voicemail_users(), messagecount(), mwi_subscription_tps, RQ_CHAR, RQ_UINTEGER3, sayname(), SENTINEL, vm_box_exists(), vm_exec(), vm_execmain(), and vmauthenticate().
11368 { 11369 int res; 11370 my_umask = umask(0); 11371 umask(my_umask); 11372 11373 /* compute the location of the voicemail spool directory */ 11374 snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 11375 11376 if (!(mwi_subscription_tps = ast_taskprocessor_get("app_voicemail", 0))) { 11377 ast_log(AST_LOG_WARNING, "failed to reference mwi subscription taskprocessor. MWI will not work\n"); 11378 } 11379 11380 if ((res = load_config(0))) 11381 return res; 11382 11383 res = ast_register_application_xml(app, vm_exec); 11384 res |= ast_register_application_xml(app2, vm_execmain); 11385 res |= ast_register_application_xml(app3, vm_box_exists); 11386 res |= ast_register_application_xml(app4, vmauthenticate); 11387 res |= ast_custom_function_register(&mailbox_exists_acf); 11388 res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users); 11389 if (res) 11390 return res; 11391 11392 ast_cli_register_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail)); 11393 11394 ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname); 11395 ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL); 11396 ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL); 11397 11398 return res; 11399 }
| 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. |
Definition at line 1448 of file app_voicemail.c.
01449 { 01450 return snprintf(dest, len, "%s%s/%s/%s", VM_SPOOL_DIR, context, ext, folder); 01451 }
| 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. | |
| 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. | |
| 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. |
Definition at line 4165 of file app_voicemail.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_LOG_WARNING, ast_random(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_variable_retrieve(), charset, check_mime(), CONFIG_FLAG_NOCACHE, ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, emailbody, emaildateformat, ast_vm_user::emailsubject, emailsubject, ENDL, fromstring, ast_vm_user::fullname, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), MAXHOSTNAMELEN, ast_channel::name, prep_email_sub_vars(), ast_channel::priority, strip_control(), VM_PBXSKIP, and vmu_tm().
Referenced by sendmail().
04166 { 04167 char date[256]; 04168 char host[MAXHOSTNAMELEN] = ""; 04169 char who[256]; 04170 char bound[256]; 04171 char dur[256]; 04172 struct ast_tm tm; 04173 char enc_cidnum[256] = "", enc_cidname[256] = ""; 04174 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 04175 char *greeting_attachment; 04176 char filename[256]; 04177 04178 if (!str1 || !str2) { 04179 ast_free(str1); 04180 ast_free(str2); 04181 return; 04182 } 04183 #ifdef IMAP_STORAGE 04184 #define ENDL "\r\n" 04185 #else 04186 #define ENDL "\n" 04187 #endif 04188 04189 if (cidnum) { 04190 strip_control(cidnum, enc_cidnum, sizeof(enc_cidnum)); 04191 } 04192 if (cidname) { 04193 strip_control(cidname, enc_cidname, sizeof(enc_cidname)); 04194 } 04195 gethostname(host, sizeof(host) - 1); 04196 04197 if (strchr(srcemail, '@')) { 04198 ast_copy_string(who, srcemail, sizeof(who)); 04199 } else { 04200 snprintf(who, sizeof(who), "%s@%s", srcemail, host); 04201 } 04202 04203 greeting_attachment = strrchr(ast_strdupa(attach), '/'); 04204 if (greeting_attachment) { 04205 *greeting_attachment++ = '\0'; 04206 } 04207 04208 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 04209 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", vmu_tm(vmu, &tm)); 04210 fprintf(p, "Date: %s" ENDL, date); 04211 04212 /* Set date format for voicemail mail */ 04213 ast_strftime(date, sizeof(date), emaildateformat, &tm); 04214 04215 if (!ast_strlen_zero(fromstring)) { 04216 struct ast_channel *ast; 04217 if ((ast = ast_dummy_channel_alloc())) { 04218 char *ptr; 04219 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, enc_cidnum, enc_cidname, dur, date, category, flag); 04220 ast_str_substitute_variables(&str1, 0, ast, fromstring); 04221 04222 if (check_mime(ast_str_buffer(str1))) { 04223 int first_line = 1; 04224 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 04225 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04226 *ptr = '\0'; 04227 fprintf(p, "%s %s" ENDL, first_line ? "From:" : "", ast_str_buffer(str2)); 04228 first_line = 0; 04229 /* Substring is smaller, so this will never grow */ 04230 ast_str_set(&str2, 0, "%s", ptr + 1); 04231 } 04232 fprintf(p, "%s %s <%s>" ENDL, first_line ? "From:" : "", ast_str_buffer(str2), who); 04233 } else { 04234 fprintf(p, "From: %s <%s>" ENDL, ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 04235 } 04236 ast = ast_channel_release(ast); 04237 } else { 04238 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04239 } 04240 } else { 04241 fprintf(p, "From: Asterisk PBX <%s>" ENDL, who); 04242 } 04243 04244 if (check_mime(vmu->fullname)) { 04245 int first_line = 1; 04246 char *ptr; 04247 ast_str_encode_mime(&str2, 0, vmu->fullname, strlen("To: "), strlen(vmu->email) + 3); 04248 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04249 *ptr = '\0'; 04250 fprintf(p, "%s %s" ENDL, first_line ? "To:" : "", ast_str_buffer(str2)); 04251 first_line = 0; 04252 /* Substring is smaller, so this will never grow */ 04253 ast_str_set(&str2, 0, "%s", ptr + 1); 04254 } 04255 fprintf(p, "%s %s <%s>" ENDL, first_line ? "To:" : "", ast_str_buffer(str2), vmu->email); 04256 } else { 04257 fprintf(p, "To: %s <%s>" ENDL, ast_str_quote(&str2, 0, vmu->fullname), vmu->email); 04258 } 04259 04260 if (!ast_strlen_zero(emailsubject) || !ast_strlen_zero(vmu->emailsubject)) { 04261 char *e_subj = !ast_strlen_zero(vmu->emailsubject) ? vmu->emailsubject : emailsubject; 04262 struct ast_channel *ast; 04263 if ((ast = ast_dummy_channel_alloc())) { 04264 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04265 ast_str_substitute_variables(&str1, 0, ast, e_subj); 04266 if (check_mime(ast_str_buffer(str1))) { 04267 int first_line = 1; 04268 char *ptr; 04269 ast_str_encode_mime(&str2, 0, ast_str_buffer(str1), strlen("Subject: "), 0); 04270 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 04271 *ptr = '\0'; 04272 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04273 first_line = 0; 04274 /* Substring is smaller, so this will never grow */ 04275 ast_str_set(&str2, 0, "%s", ptr + 1); 04276 } 04277 fprintf(p, "%s %s" ENDL, first_line ? "Subject:" : "", ast_str_buffer(str2)); 04278 } else { 04279 fprintf(p, "Subject: %s" ENDL, ast_str_buffer(str1)); 04280 } 04281 ast = ast_channel_release(ast); 04282 } else { 04283 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04284 } 04285 } else if (ast_test_flag((&globalflags), VM_PBXSKIP)) { 04286 if (ast_strlen_zero(flag)) { 04287 fprintf(p, "Subject: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04288 } else { 04289 fprintf(p, "Subject: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04290 } 04291 } else { 04292 if (ast_strlen_zero(flag)) { 04293 fprintf(p, "Subject: [PBX]: New message %d in mailbox %s" ENDL, msgnum + 1, mailbox); 04294 } else { 04295 fprintf(p, "Subject: [PBX]: New %s message %d in mailbox %s" ENDL, flag, msgnum + 1, mailbox); 04296 } 04297 } 04298 04299 fprintf(p, "Message-ID: <Asterisk-%d-%d-%s-%d@%s>" ENDL, msgnum + 1, 04300 (unsigned int) ast_random(), mailbox, (int) getpid(), host); 04301 if (imap) { 04302 /* additional information needed for IMAP searching */ 04303 fprintf(p, "X-Asterisk-VM-Message-Num: %d" ENDL, msgnum + 1); 04304 /* fprintf(p, "X-Asterisk-VM-Orig-Mailbox: %s" ENDL, ext); */ 04305 fprintf(p, "X-Asterisk-VM-Server-Name: %s" ENDL, fromstring); 04306 fprintf(p, "X-Asterisk-VM-Context: %s" ENDL, context); 04307 #ifdef IMAP_STORAGE 04308 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, (!ast_strlen_zero(vmu->imapvmshareid) ? vmu->imapvmshareid : mailbox)); 04309 #else 04310 fprintf(p, "X-Asterisk-VM-Extension: %s" ENDL, mailbox); 04311 #endif 04312 /* flag added for Urgent */ 04313 fprintf(p, "X-Asterisk-VM-Flag: %s" ENDL, flag); 04314 fprintf(p, "X-Asterisk-VM-Priority: %d" ENDL, chan->priority); 04315 fprintf(p, "X-Asterisk-VM-Caller-channel: %s" ENDL, chan->name); 04316 fprintf(p, "X-Asterisk-VM-Caller-ID-Num: %s" ENDL, enc_cidnum); 04317 fprintf(p, "X-Asterisk-VM-Caller-ID-Name: %s" ENDL, enc_cidname); 04318 fprintf(p, "X-Asterisk-VM-Duration: %d" ENDL, duration); 04319 if (!ast_strlen_zero(category)) { 04320 fprintf(p, "X-Asterisk-VM-Category: %s" ENDL, category); 04321 } else { 04322 fprintf(p, "X-Asterisk-VM-Category: " ENDL); 04323 } 04324 fprintf(p, "X-Asterisk-VM-Message-Type: %s" ENDL, msgnum > -1 ? "Message" : greeting_attachment); 04325 fprintf(p, "X-Asterisk-VM-Orig-date: %s" ENDL, date); 04326 fprintf(p, "X-Asterisk-VM-Orig-time: %ld" ENDL, (long) time(NULL)); 04327 } 04328 if (!ast_strlen_zero(cidnum)) { 04329 fprintf(p, "X-Asterisk-CallerID: %s" ENDL, enc_cidnum); 04330 } 04331 if (!ast_strlen_zero(cidname)) { 04332 fprintf(p, "X-Asterisk-CallerIDName: %s" ENDL, enc_cidname); 04333 } 04334 fprintf(p, "MIME-Version: 1.0" ENDL); 04335 if (attach_user_voicemail) { 04336 /* Something unique. */ 04337 snprintf(bound, sizeof(bound), "----voicemail_%d%s%d%d", msgnum + 1, mailbox, 04338 (int) getpid(), (unsigned int) ast_random()); 04339 04340 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"" ENDL, bound); 04341 fprintf(p, ENDL ENDL "This is a multi-part message in MIME format." ENDL ENDL); 04342 fprintf(p, "--%s" ENDL, bound); 04343 } 04344 fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); 04345 if (emailbody || vmu->emailbody) { 04346 char* e_body = vmu->emailbody ? vmu->emailbody : emailbody; 04347 struct ast_channel *ast; 04348 if ((ast = ast_dummy_channel_alloc())) { 04349 prep_email_sub_vars(ast, vmu, msgnum + 1, context, mailbox, fromfolder, cidnum, cidname, dur, date, category, flag); 04350 ast_str_substitute_variables(&str1, 0, ast, e_body); 04351 fprintf(p, "%s" ENDL, ast_str_buffer(str1)); 04352 ast = ast_channel_release(ast); 04353 } else { 04354 ast_log(AST_LOG_WARNING, "Cannot allocate the channel for variables substitution\n"); 04355 } 04356 } else if (msgnum > -1) { 04357 if (strcmp(vmu->mailbox, mailbox)) { 04358 /* Forwarded type */ 04359 struct ast_config *msg_cfg; 04360 const char *v; 04361 int inttime; 04362 char fromdir[256], fromfile[256], origdate[80] = "", origcallerid[80] = ""; 04363 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 04364 /* Retrieve info from VM attribute file */ 04365 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, fromfolder); 04366 make_file(fromfile, sizeof(fromfile), fromdir, msgnum); 04367 if (strlen(fromfile) < sizeof(fromfile) - 5) { 04368 strcat(fromfile, ".txt"); 04369 } 04370 if ((msg_cfg = ast_config_load(fromfile, config_flags))) { 04371 if ((v = ast_variable_retrieve(msg_cfg, "message", "callerid"))) { 04372 ast_copy_string(origcallerid, v, sizeof(origcallerid)); 04373 } 04374 04375 /* You might be tempted to do origdate, except that a) it's in the wrong 04376 * format, and b) it's missing for IMAP recordings. */ 04377 if ((v = ast_variable_retrieve(msg_cfg, "message", "origtime")) && sscanf(v, "%30d", &inttime) == 1) { 04378 struct timeval tv = { inttime, }; 04379 struct ast_tm tm; 04380 ast_localtime(&tv, &tm, NULL); 04381 ast_strftime(origdate, sizeof(origdate), emaildateformat, &tm); 04382 } 04383 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just forwarded" 04384 " a %s long message (number %d)" ENDL "in mailbox %s from %s, on %s" ENDL 04385 "(originally sent by %s on %s)" ENDL "so you might want to check it when you get a" 04386 " chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" ENDL ENDL, vmu->fullname, dur, 04387 msgnum + 1, mailbox, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), 04388 date, origcallerid, origdate); 04389 ast_config_destroy(msg_cfg); 04390 } else { 04391 goto plain_message; 04392 } 04393 } else { 04394 plain_message: 04395 fprintf(p, "Dear %s:" ENDL ENDL "\tJust wanted to let you know you were just left a " 04396 "%s long message (number %d)" ENDL "in mailbox %s from %s, on %s so you might" ENDL 04397 "want to check it when you get a chance. Thanks!" ENDL ENDL "\t\t\t\t--Asterisk" 04398 ENDL ENDL, vmu->fullname, dur, msgnum + 1, mailbox, 04399 (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 04400 } 04401 } else { 04402 fprintf(p, "This message is to let you know that your greeting was changed on %s." ENDL 04403 "Please do not delete this message, lest your greeting vanish with it." ENDL ENDL, date); 04404 } 04405 04406 if (imap || attach_user_voicemail) { 04407 if (!ast_strlen_zero(attach2)) { 04408 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04409 ast_debug(5, "creating second attachment filename %s\n", filename); 04410 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 0, msgnum); 04411 snprintf(filename, sizeof(filename), "msgintro%04d.%s", msgnum, format); 04412 ast_debug(5, "creating attachment filename %s\n", filename); 04413 add_email_attachment(p, vmu, format, attach2, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04414 } else { 04415 snprintf(filename, sizeof(filename), "msg%04d.%s", msgnum, format); 04416 ast_debug(5, "creating attachment filename %s, no second attachment.\n", filename); 04417 add_email_attachment(p, vmu, format, attach, greeting_attachment, mailbox, bound, filename, 1, msgnum); 04418 } 04419 } 04420 ast_free(str1); 04421 ast_free(str2); 04422 }
| 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. |
Definition at line 1463 of file app_voicemail.c.
Referenced by advanced_options(), close_mailbox(), copy_message(), leave_voicemail(), make_email_file(), notify_new_message(), play_message(), prep_email_sub_vars(), save_to_folder(), vm_execmain(), and vm_forwardoptions().
| static int manager_list_voicemail_users | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager list voicemail users command.
Definition at line 10447 of file app_voicemail.c.
References AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_ack(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::context, count_messages(), ast_vm_user::dialout, ast_vm_user::email, ast_vm_user::exit, ast_vm_user::fullname, inboxcount(), ast_vm_user::language, ast_vm_user::mailbox, 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.
Referenced by load_module().
10448 { 10449 struct ast_vm_user *vmu = NULL; 10450 const char *id = astman_get_header(m, "ActionID"); 10451 char actionid[128] = ""; 10452 10453 if (!ast_strlen_zero(id)) 10454 snprintf(actionid, sizeof(actionid), "ActionID: %s\r\n", id); 10455 10456 AST_LIST_LOCK(&users); 10457 10458 if (AST_LIST_EMPTY(&users)) { 10459 astman_send_ack(s, m, "There are no voicemail users currently defined."); 10460 AST_LIST_UNLOCK(&users); 10461 return RESULT_SUCCESS; 10462 } 10463 10464 astman_send_ack(s, m, "Voicemail user list will follow"); 10465 10466 AST_LIST_TRAVERSE(&users, vmu, list) { 10467 char dirname[256]; 10468 10469 #ifdef IMAP_STORAGE 10470 int new, old; 10471 inboxcount(vmu->mailbox, &new, &old); 10472 #endif 10473 10474 make_dir(dirname, sizeof(dirname), vmu->context, vmu->mailbox, "INBOX"); 10475 astman_append(s, 10476 "%s" 10477 "Event: VoicemailUserEntry\r\n" 10478 "VMContext: %s\r\n" 10479 "VoiceMailbox: %s\r\n" 10480 "Fullname: %s\r\n" 10481 "Email: %s\r\n" 10482 "Pager: %s\r\n" 10483 "ServerEmail: %s\r\n" 10484 "MailCommand: %s\r\n" 10485 "Language: %s\r\n" 10486 "TimeZone: %s\r\n" 10487 "Callback: %s\r\n" 10488 "Dialout: %s\r\n" 10489 "UniqueID: %s\r\n" 10490 "ExitContext: %s\r\n" 10491 "SayDurationMinimum: %d\r\n" 10492 "SayEnvelope: %s\r\n" 10493 "SayCID: %s\r\n" 10494 "AttachMessage: %s\r\n" 10495 "AttachmentFormat: %s\r\n" 10496 "DeleteMessage: %s\r\n" 10497 "VolumeGain: %.2f\r\n" 10498 "CanReview: %s\r\n" 10499 "CallOperator: %s\r\n" 10500 "MaxMessageCount: %d\r\n" 10501 "MaxMessageLength: %d\r\n" 10502 "NewMessageCount: %d\r\n" 10503 #ifdef IMAP_STORAGE 10504 "OldMessageCount: %d\r\n" 10505 "IMAPUser: %s\r\n" 10506 #endif 10507 "\r\n", 10508 actionid, 10509 vmu->context, 10510 vmu->mailbox, 10511 vmu->fullname, 10512 vmu->email, 10513 vmu->pager, 10514 vmu->serveremail, 10515 vmu->mailcmd, 10516 vmu->language, 10517 vmu->zonetag, 10518 vmu->callback, 10519 vmu->dialout, 10520 vmu->uniqueid, 10521 vmu->exit, 10522 vmu->saydurationm, 10523 ast_test_flag(vmu, VM_ENVELOPE) ? "Yes" : "No", 10524 ast_test_flag(vmu, VM_SAYCID) ? "Yes" : "No", 10525 ast_test_flag(vmu, VM_ATTACH) ? "Yes" : "No", 10526 vmu->attachfmt, 10527 ast_test_flag(vmu, VM_DELETE) ? "Yes" : "No", 10528 vmu->volgain, 10529 ast_test_flag(vmu, VM_REVIEW) ? "Yes" : "No", 10530 ast_test_flag(vmu, VM_OPERATOR) ? "Yes" : "No", 10531 vmu->maxmsg, 10532 vmu->maxsecs, 10533 #ifdef IMAP_STORAGE 10534 new, old, vmu->imapuser 10535 #else 10536 count_messages(vmu, dirname) 10537 #endif 10538 ); 10539 } 10540 astman_append(s, "Event: VoicemailUserEntryComplete\r\n%s\r\n", actionid); 10541 10542 AST_LIST_UNLOCK(&users); 10543 10544 return RESULT_SUCCESS; 10545 }
| static void* mb_poll_thread | ( | void * | data | ) | [static] |
Definition at line 10281 of file app_voicemail.c.
References ast_cond_timedwait(), ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), poll_lock, and poll_subscribed_mailboxes().
Referenced by start_poll_thread().
10282 { 10283 while (poll_thread_run) { 10284 struct timespec ts = { 0, }; 10285 struct timeval wait; 10286 10287 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(poll_freq, 1)); 10288 ts.tv_sec = wait.tv_sec; 10289 ts.tv_nsec = wait.tv_usec * 1000; 10290 10291 ast_mutex_lock(&poll_lock); 10292 ast_cond_timedwait(&poll_cond, &poll_lock, &ts); 10293 ast_mutex_unlock(&poll_lock); 10294 10295 if (!poll_thread_run) 10296 break; 10297 10298 poll_subscribed_mailboxes(); 10299 } 10300 10301 return NULL; 10302 }
| static const char* mbox | ( | int | id | ) | [static] |
Definition at line 1524 of file app_voicemail.c.
References ARRAY_LEN, and mailbox_folders.
Referenced by acf_mailbox_exists(), add_peer_mailboxes(), adsi_load_vmail(), build_gateway(), copy_message(), get_folder(), has_voicemail(), notify_new_message(), open_mailbox(), save_to_folder(), vm_box_exists(), and vm_execmain().
01525 { 01526 return (id >= 0 && id < ARRAY_LEN(mailbox_folders)) ? mailbox_folders[id] : "Unknown"; 01527 }
| static int messagecount | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder | |||
| ) | [static] |
Definition at line 4986 of file app_voicemail.c.
References __has_voicemail().
Referenced by load_module().
04987 { 04988 return __has_voicemail(context, mailbox, folder, 0); 04989 }
| static void mwi_sub_destroy | ( | struct mwi_sub * | mwi_sub | ) | [static] |
Definition at line 10304 of file app_voicemail.c.
References ast_free.
Referenced by handle_unsubscribe().
10305 { 10306 ast_free(mwi_sub); 10307 }
| static void mwi_sub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 10382 of file app_voicemail.c.
References ast_calloc, ast_event_get_ie_str(), ast_event_get_ie_uint(), ast_event_get_type(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_EVENTTYPE, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_UNIQUEID, AST_EVENT_MWI, AST_EVENT_SUB, ast_free, ast_log(), ast_strdup, ast_taskprocessor_push(), mwi_sub_task::context, handle_subscribe(), LOG_ERROR, mwi_sub_task::mailbox, mwi_subscription_tps, and mwi_sub_task::uniqueid.
Referenced by start_poll_thread().
10383 { 10384 struct mwi_sub_task *mwist; 10385 10386 if (ast_event_get_type(event) != AST_EVENT_SUB) 10387 return; 10388 10389 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10390 return; 10391 10392 if ((mwist = ast_calloc(1, (sizeof(*mwist)))) == NULL) { 10393 ast_log(LOG_ERROR, "could not allocate a mwi_sub_task\n"); 10394 return; 10395 } 10396 mwist->mailbox = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX)); 10397 mwist->context = ast_strdup(ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT)); 10398 mwist->uniqueid = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10399 10400 if (ast_taskprocessor_push(mwi_subscription_tps, handle_subscribe, mwist) < 0) { 10401 ast_free(mwist); 10402 } 10403 }
| static void mwi_unsub_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 10366 of file app_voicemail.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.
Referenced by start_poll_thread().
10367 { 10368 uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid)); 10369 if (ast_event_get_type(event) != AST_EVENT_UNSUB) 10370 return; 10371 10372 if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) 10373 return; 10374 10375 u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID); 10376 *uniqueid = u; 10377 if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) { 10378 ast_free(uniqueid); 10379 } 10380 }
| 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. |
Definition at line 6501 of file app_voicemail.c.
References ast_app_has_voicemail(), ast_app_inboxcount2(), ast_channel_lock, ast_channel_unlock, ast_log(), AST_LOG_WARNING, 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, globalflags, ast_vm_user::mailbox, make_dir(), make_file(), manager_event, 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.
06502 { 06503 char todir[PATH_MAX], fn[PATH_MAX], ext_context[PATH_MAX], *stringp; 06504 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0; 06505 const char *category; 06506 char *myserveremail = serveremail; 06507 06508 ast_channel_lock(chan); 06509 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06510 category = ast_strdupa(category); 06511 } 06512 ast_channel_unlock(chan); 06513 06514 make_dir(todir, sizeof(todir), vmu->context, vmu->mailbox, "INBOX"); 06515 make_file(fn, sizeof(fn), todir, msgnum); 06516 snprintf(ext_context, sizeof(ext_context), "%s@%s", vmu->mailbox, vmu->context); 06517 06518 if (!ast_strlen_zero(vmu->attachfmt)) { 06519 if (strstr(fmt, vmu->attachfmt)) 06520 fmt = vmu->attachfmt; 06521 else 06522 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); 06523 } 06524 06525 /* Attach only the first format */ 06526 fmt = ast_strdupa(fmt); 06527 stringp = fmt; 06528 strsep(&stringp, "|"); 06529 06530 if (!