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

Go to the source code of this file.
Data Structures | |
| struct | ast_vm_user |
| struct | baseio |
| struct | inprocess |
| struct | leave_vm_options |
| Options for leaving voicemail with the voicemail() application. More... | |
| struct | mwi_sub |
| An MWI subscription. More... | |
| struct | mwi_sub_task |
| struct | mwi_subs |
| struct | users |
| list of users found in the config file More... | |
| struct | vm_state |
| struct | vm_zone |
| struct | zones |
Defines | |
| #define | ASTERISK_USERNAME "asterisk" |
| #define | BASELINELEN 72 |
| #define | BASEMAXINLINE 256 |
| #define | CHUNKSIZE 65536 |
| #define | COMMAND_TIMEOUT 5000 |
| #define | COPY(a, b, c, d, e, f, g, h) (copy_plain_file(g,h)); |
| #define | DATA_EXPORT_VM_USERS(USER) |
| #define | DATA_EXPORT_VM_ZONES(ZONE) |
| #define | DEFAULT_LISTEN_CONTROL_FORWARD_KEY "#" |
| #define | DEFAULT_LISTEN_CONTROL_PAUSE_KEY "0" |
| #define | DEFAULT_LISTEN_CONTROL_RESTART_KEY "2" |
| #define | DEFAULT_LISTEN_CONTROL_REVERSE_KEY "*" |
| #define | DEFAULT_LISTEN_CONTROL_STOP_KEY "13456789" |
| #define | DEFAULT_POLL_FREQ 30 |
| #define | DELETE(a, b, c, d) (vm_delete(c)) |
| #define | DISPOSE(a, b) |
| #define | ENDL "\n" |
| #define | ERROR_LOCK_PATH -100 |
| #define | EXISTS(a, b, c, d) (ast_fileexists(c,NULL,d) > 0) |
| #define | HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" |
| #define | HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
| #define | INTRO "vm-intro" |
| #define | MAX_DATETIME_FORMAT 512 |
| #define | MAX_NUM_CID_CONTEXTS 10 |
| #define | MAXMSG 100 |
| #define | MAXMSGLIMIT 9999 |
| #define | MINPASSWORD 0 |
| #define | OPERATOR_EXIT 300 |
| #define | PWDCHANGE_EXTERNAL (1 << 2) |
| #define | PWDCHANGE_INTERNAL (1 << 1) |
| #define | RENAME(a, b, c, d, e, f, g, h) (rename_file(g,h)); |
| #define | RETRIEVE(a, b, c, d) |
| #define | SENDMAIL "/usr/sbin/sendmail -t" |
| #define | SMDI_MWI_WAIT_TIMEOUT 1000 |
| #define | STORE(a, b, c, d, e, f, g, h, i, j, k) |
| #define | tdesc "Comedian Mail (Voicemail System)" |
| #define | UPDATE_MSG_ID(a, b, c, d, e, f) |
| #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 | acf_vm_info (struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len) |
| static int | actual_load_config (int reload, struct ast_config *cfg, struct ast_config *ucfg) |
| static int | add_email_attachment (FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum) |
| static int | add_message_id (struct ast_config *msg_cfg, char *dir, int msg, char *filename, char *id, size_t id_size, struct ast_vm_user *vmu, int folder) |
| static void | adsi_begin (struct ast_channel *chan, int *useadsi) |
| static void | adsi_delete (struct ast_channel *chan, struct vm_state *vms) |
| static void | adsi_folders (struct ast_channel *chan, int start, char *label) |
| static void | adsi_goodbye (struct ast_channel *chan) |
| static int | adsi_load_vmail (struct ast_channel *chan, int *useadsi) |
| static void | adsi_login (struct ast_channel *chan) |
| static int | adsi_logo (unsigned char *buf) |
| static void | adsi_message (struct ast_channel *chan, struct vm_state *vms) |
| static void | adsi_password (struct ast_channel *chan) |
| static void | adsi_status (struct ast_channel *chan, struct vm_state *vms) |
| static void | adsi_status2 (struct ast_channel *chan, struct vm_state *vms) |
| static int | advanced_options (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain) |
| The advanced options within a message. | |
| static int | append_mailbox (const char *context, const char *box, const char *data) |
| static void | apply_option (struct ast_vm_user *vmu, const char *var, const char *value) |
| Sets a a specific property value. | |
| static void | apply_options (struct ast_vm_user *vmu, const char *options) |
| Destructively Parse options and apply. | |
| static void | apply_options_full (struct ast_vm_user *retval, struct ast_variable *var) |
| Loads the options specific to a voicemail user. | |
| AST_DATA_STRUCTURE (vm_zone, DATA_EXPORT_VM_ZONES) | |
| AST_DATA_STRUCTURE (ast_vm_user, DATA_EXPORT_VM_USERS) | |
| static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *start, size_t preamble, size_t postamble) |
| Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters. | |
| static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
| Wraps a character sequence in double quotes, escaping occurences of quotes within the string. | |
| AST_TEST_DEFINE (test_voicemail_vmuser) | |
| static int | base_encode (char *filename, FILE *so) |
| Performs a base 64 encode algorithm on the contents of a File. | |
| static int | change_password_realtime (struct ast_vm_user *vmu, const char *password) |
| Performs a change of the voicemail passowrd in the realtime engine. | |
| static int | check_mime (const char *str) |
| Check if the string would need encoding within the MIME standard, to avoid confusing certain mail software that expects messages to be 7-bit clean. | |
| static int | check_password (struct ast_vm_user *vmu, char *password) |
| Check that password meets minimum required length. | |
| static int | close_mailbox (struct vm_state *vms, struct ast_vm_user *vmu) |
| static char * | complete_voicemail_show_users (const char *line, const char *word, int pos, int state) |
| static int | copy (char *infile, char *outfile) |
| Utility function to copy a file. | |
| static int | copy_message (struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag, const char *dest_folder) |
| 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 void | generate_random_string (char *buf, size_t size) |
| static int | get_date (char *s, int len) |
| Gets the current date and time, as formatted string. | |
| static int | get_folder (struct ast_channel *chan, int start) |
| get_folder: Folder menu Plays "press 1 for INBOX messages" etc. Should possibly be internationalized | |
| static int | get_folder2 (struct ast_channel *chan, char *fn, int start) |
| plays a prompt and waits for a keypress. | |
| static int | get_folder_by_name (const char *name) |
| static int | handle_subscribe (void *datap) |
| static int | handle_unsubscribe (void *datap) |
| static char * | handle_voicemail_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Reload voicemail configuration from the CLI. | |
| static char * | handle_voicemail_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show a list of voicemail users in the CLI. | |
| static char * | handle_voicemail_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show a list of voicemail zones in the CLI. | |
| static int | has_voicemail (const char *mailbox, const char *folder) |
| Determines if the given folder has messages. | |
| static int | inboxcount (const char *mailbox, int *newmsgs, int *oldmsgs) |
| static int | inboxcount2 (const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs) |
| static int | inbuf (struct baseio *bio, FILE *fi) |
| utility used by inchar(), for base_encode() | |
| static int | inchar (struct baseio *bio, FILE *fi) |
| utility used by base_encode() | |
| static int | inprocess_cmp_fn (void *obj, void *arg, int flags) |
| static int | inprocess_count (const char *context, const char *mailbox, int delta) |
| static int | inprocess_hash_fn (const void *obj, const int flags) |
| static int | invent_message (struct ast_channel *chan, char *context, char *ext, int busy, char *ecodes) |
| static int | is_valid_dtmf (const char *key) |
| Determines if a DTMF key entered is valid. | |
| static int | last_message_index (struct ast_vm_user *vmu, char *dir) |
| Determines the highest message number in use for a given user and mailbox folder. | |
| static int | leave_voicemail (struct ast_channel *chan, char *ext, struct leave_vm_options *options) |
| Prompts the user and records a voicemail to a mailbox. | |
| static int | load_config (int reload) |
| static int | load_module (void) |
| Load the module. | |
| 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, const char *msg_id) |
| 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 int | manager_voicemail_refresh (struct mansession *s, const struct message *m) |
| static void * | mb_poll_thread (void *data) |
| static const char * | mbox (struct ast_vm_user *vmu, int id) |
| static int | message_range_and_existence_check (struct vm_state *vms, const char *msg_ids[], size_t num_msgs, int *msg_nums, struct ast_vm_user *vmu) |
| common bounds checking and existence check for Voicemail API functions. | |
| static int | messagecount (const char *context, const char *mailbox, const char *folder) |
| static int | msg_create_from_file (struct ast_vm_recording_data *recdata) |
| 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 void | notify_new_state (struct ast_vm_user *vmu) |
| 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_by_id (struct ast_channel *chan, const char *mailbox, const char *context, const char *msg_id) |
| Finds a message in a specific mailbox by msg_id and plays it to the channel. | |
| static int | play_message_by_id_helper (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, const char *msg_id) |
| static int | play_message_callerid (struct ast_channel *chan, struct vm_state *vms, char *cid, const char *context, int callback, int saycidnumber) |
| static int | play_message_category (struct ast_channel *chan, const char *category) |
| static int | play_message_datetime (struct ast_channel *chan, struct ast_vm_user *vmu, const char *origtime, const char *filename) |
| static int | play_message_duration (struct ast_channel *chan, struct vm_state *vms, const char *duration, int minduration) |
| static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct ast_vm_user *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain, struct vm_state *vms, char *flag, const char *msg_id) |
| static void | poll_subscribed_mailbox (struct mwi_sub *mwi_sub) |
| static void | poll_subscribed_mailboxes (void) |
| static void | populate_defaults (struct ast_vm_user *vmu) |
| Sets default voicemail system options to a voicemail user. | |
| static void | prep_email_sub_vars (struct ast_channel *ast, struct ast_vm_user *vmu, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, char *dur, char *date, const char *category, const char *flag) |
| static void | queue_mwi_event (const char *box, int urgent, int new, int old) |
| static void | read_password_from_file (const char *secretfn, char *password, int passwordlen) |
| static int | reload (void) |
| static void | rename_file (char *sfn, char *dfn) |
| Renames a message in a mailbox folder. | |
| static int | resequence_mailbox (struct ast_vm_user *vmu, char *dir, int stopcount) |
| static int | reset_user_pw (const char *context, const char *mailbox, const char *newpass) |
| Resets a user password to a specified password. | |
| static void | run_externnotify (char *context, char *extension, const char *flag) |
| static int | save_to_folder (struct ast_vm_user *vmu, struct vm_state *vms, int msg, int box, int *newmsg, int move) |
| 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, const char *msg_id) |
| static int | sendpage (char *srcemail, char *pager, int msgnum, char *context, char *mailbox, const char *fromfolder, char *cidnum, char *cidname, int duration, struct ast_vm_user *vmu, const char *category, const char *flag) |
| static char * | show_users_realtime (int fd, const char *context) |
| static void | start_poll_thread (void) |
| static void | stop_poll_thread (void) |
| static char * | strip_control_and_high (const char *input, char *buf, size_t buflen) |
| Strips control and non 7-bit clean characters from input string. | |
| static const char * | substitute_escapes (const char *value) |
| static int | unload_module (void) |
| static int | vm_allocate_dh (struct vm_state *vms, struct ast_vm_user *vmu, int count_msg) |
| static int | vm_authenticate (struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int max_logins, int silent) |
| static int | vm_box_exists (struct ast_channel *chan, const char *data) |
| static int | vm_browse_messages (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Top level method to invoke the language variant vm_browse_messages_XX function. | |
| static int | vm_browse_messages_en (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Default English syntax for 'You have N messages' greeting. | |
| static int | vm_browse_messages_es (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Spanish syntax for 'You have N messages' greeting. | |
| static int | vm_browse_messages_gr (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Greek syntax for 'You have N messages' greeting. | |
| static int | vm_browse_messages_he (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| static int | vm_browse_messages_it (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Italian syntax for 'You have N messages' greeting. | |
| static int | vm_browse_messages_pt (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Portuguese syntax for 'You have N messages' greeting. | |
| static int | vm_browse_messages_vi (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Vietnamese syntax for 'You have N messages' greeting. | |
| static int | vm_browse_messages_zh (struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu) |
| Chinese (Taiwan)syntax for 'You have N messages' greeting. | |
| static void | vm_change_password (struct ast_vm_user *vmu, const char *newpassword) |
| The handler for the change password option. | |
| static void | vm_change_password_shell (struct ast_vm_user *vmu, char *newpassword) |
| static char * | vm_check_password_shell (char *command, char *buf, size_t len) |
| static int | vm_delete (char *file) |
| Removes the voicemail sound and information file. | |
| static int | vm_exec (struct ast_channel *chan, const char *data) |
| static int | vm_execmain (struct ast_channel *chan, const char *data) |
| static int | vm_forwardoptions (struct ast_channel *chan, struct ast_vm_user *vmu, char *curdir, int curmsg, char *vm_fmts, char *context, signed char record_gain, long *duration, struct vm_state *vms, char *flag) |
| presents the option to prepend to an existing message when forwarding it. | |
| static const char * | vm_index_to_foldername (int id) |
| static int | vm_instructions (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
| static int | vm_instructions_en (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
| static int | vm_instructions_zh (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent) |
| static int | vm_intro (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms) |
| static int | vm_intro_cs (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_de (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_en (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_es (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_fr (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_gr (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_he (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_it (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_multilang (struct ast_channel *chan, struct vm_state *vms, const char message_gender[]) |
| static int | vm_intro_nl (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_no (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_pl (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_pt (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_pt_BR (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_se (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_vi (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_intro_zh (struct ast_channel *chan, struct vm_state *vms) |
| static int | vm_lock_path (const char *path) |
| Lock file path only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason. | |
| static struct ast_vm_mailbox_snapshot * | vm_mailbox_snapshot_create (const char *mailbox, const char *context, const char *folder, int descending, enum ast_vm_snapshot_sort_val sort_val, int combine_INBOX_and_OLD) |
| static struct ast_vm_mailbox_snapshot * | vm_mailbox_snapshot_destroy (struct ast_vm_mailbox_snapshot *mailbox_snapshot) |
| static FILE * | vm_mkftemp (char *template) |
| static int | vm_msg_forward (const char *from_mailbox, const char *from_context, const char *from_folder, const char *to_mailbox, const char *to_context, const char *to_folder, size_t num_msgs, const char *msg_ids[], int delete_old) |
| static int | vm_msg_move (const char *mailbox, const char *context, size_t num_msgs, const char *oldfolder, const char *old_msg_ids[], const char *newfolder) |
| static int | vm_msg_play (struct ast_channel *chan, const char *mailbox, const char *context, const char *folder, const char *msg_num, ast_vm_msg_play_cb cb) |
| static int | vm_msg_remove (const char *mailbox, const char *context, size_t num_msgs, const char *folder, const char *msgs[]) |
| static struct ast_vm_msg_snapshot * | vm_msg_snapshot_alloc (void) |
| static int | vm_msg_snapshot_create (struct ast_vm_user *vmu, struct vm_state *vms, struct ast_vm_mailbox_snapshot *mailbox_snapshot, int snapshot_index, int mailbox_index, int descending, enum ast_vm_snapshot_sort_val sort_val) |
| Create and store off all the msgs in an open mailbox. | |
| static struct ast_vm_msg_snapshot * | vm_msg_snapshot_destroy (struct ast_vm_msg_snapshot *msg_snapshot) |
| 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_playmsgexec (struct ast_channel *chan, const char *data) |
| static int | vm_tempgreeting (struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, char *fmtc, signed char record_gain) |
| The handler for 'record a temporary greeting'. | |
| static int | vm_users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| static int | vm_users_data_provider_get_helper (const struct ast_data_search *search, struct ast_data *data_root, struct ast_vm_user *user) |
| static int | vmauthenticate (struct ast_channel *chan, const char *data) |
| static int | vmsayname_exec (struct ast_channel *chan, const char *data) |
| static struct ast_tm * | vmu_tm (const struct ast_vm_user *vmu, struct ast_tm *tm) |
| fill in *tm for current time according to the proper timezone, if any. | |
| static int | wait_file (struct ast_channel *chan, struct vm_state *vms, char *file) |
| static int | wait_file2 (struct ast_channel *chan, struct vm_state *vms, char *file) |
| static int | write_password_to_file (const char *secretfn, const char *password) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Comedian Mail (Voicemail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .nonoptreq = "res_adsi,res_smdi", } |
| static char * | addesc = "Comedian Mail" |
| static unsigned char | adsifdn [4] = "\x00\x00\x00\x0F" |
| static unsigned char | adsisec [4] = "\x9B\xDB\xF7\xAC" |
| static int | adsiver = 1 |
| static char * | app = "VoiceMail" |
| static char * | app2 = "VoiceMailMain" |
| static char * | app3 = "MailboxExists" |
| static char * | app4 = "VMAuthenticate" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static char | callcontext [AST_MAX_CONTEXT] = "" |
| static char | charset [32] = "ISO-8859-1" |
| static char | cidinternalcontexts [MAX_NUM_CID_CONTEXTS][64] |
| static struct ast_cli_entry | cli_voicemail [] |
| static char | dialcontext [AST_MAX_CONTEXT] = "" |
| static char * | emailbody = NULL |
| static char | emaildateformat [32] = "%A, %B %d, %Y at %r" |
| static char * | emailsubject = NULL |
| static char | exitcontext [AST_MAX_CONTEXT] = "" |
| static char | ext_pass_check_cmd [128] |
| static char | ext_pass_cmd [128] |
| static char | externnotify [160] |
| static char | fromstring [100] |
| static struct ast_flags | globalflags = {0} |
| struct ao2_container * | inprocess_container |
| static char | listen_control_forward_key [12] |
| static char | listen_control_pause_key [12] |
| static char | listen_control_restart_key [12] |
| static char | listen_control_reverse_key [12] |
| static char | listen_control_stop_key [12] |
| static char | locale [20] |
| static struct ast_custom_function | mailbox_exists_acf |
| static const char *const | mailbox_folders [] |
| static char | mailcmd [160] |
| static int | maxdeletedmsg |
| static int | maxgreet |
| static int | maxlogins |
| static int | maxmsg |
| static int | maxsilence |
| static int | minpassword |
| static struct ast_event_sub * | mwi_sub_sub |
| static struct ast_taskprocessor * | mwi_subscription_tps |
| static struct ast_event_sub * | mwi_unsub_sub |
| static int | my_umask |
| static char * | pagerbody = NULL |
| static char | pagerdateformat [32] = "%A, %B %d, %Y at %r" |
| static char | pagerfromstring [100] |
| static char * | pagersubject = NULL |
| static int | passwordlocation |
| static char * | playmsg_app = "VoiceMailPlayMsg" |
| static ast_cond_t | poll_cond = PTHREAD_COND_INITIALIZER |
| static unsigned int | poll_freq |
| static ast_mutex_t | poll_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } |
| static unsigned int | poll_mailboxes |
| static pthread_t | poll_thread = AST_PTHREADT_NULL |
| static unsigned char | poll_thread_run |
| static int | pwdchange = PWDCHANGE_INTERNAL |
| static int | saydurationminfo |
| static char * | sayname_app = "VMSayName" |
| static char | serveremail [80] |
| static int | silencethreshold = 128 |
| static int | skipms |
| static struct ast_smdi_interface * | smdi_iface = NULL |
| static char | userscontext [AST_MAX_EXTENSION] = "default" |
| static struct ast_app_option | vm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 }, [ 'd' ] = { .flag = OPT_DTMFEXIT , .arg_index = OPT_ARG_DTMFEXIT + 1 }, [ 'p' ] = { .flag = OPT_PREPEND_MAILBOX }, [ 'a' ] = { .flag = OPT_AUTOPLAY , .arg_index = OPT_ARG_PLAYFOLDER + 1 }, [ 'U' ] = { .flag = OPT_MESSAGE_Urgent }, [ 'P' ] = { .flag = OPT_MESSAGE_PRIORITY }} |
| static struct ast_data_entry | vm_data_providers [] |
| static struct ast_custom_function | vm_info_acf |
| static char | vm_invalid_password [80] = "vm-invalid-password" |
| static char | vm_mismatch [80] = "vm-mismatch" |
| static char | vm_newpassword [80] = "vm-newpassword" |
| static char | vm_passchanged [80] = "vm-passchanged" |
| static char | vm_password [80] = "vm-password" |
| static char | vm_pls_try_again [80] = "vm-pls-try-again" |
| static char | vm_prepend_timeout [80] = "vm-then-pound" |
| static char | vm_reenterpassword [80] = "vm-reenterpassword" |
| static char | VM_SPOOL_DIR [PATH_MAX] |
| static struct ast_data_handler | vm_users_data_provider |
| static char | vmfmts [80] |
| static int | vmmaxsecs |
| static int | vmminsecs |
| static double | volgain |
| static char | zonetag [80] |
Definition in file app_voicemail.c.
| #define ASTERISK_USERNAME "asterisk" |
Definition at line 562 of file app_voicemail.c.
| #define BASELINELEN 72 |
| #define BASEMAXINLINE 256 |
| #define CHUNKSIZE 65536 |
Definition at line 559 of file app_voicemail.c.
| #define COMMAND_TIMEOUT 5000 |
Definition at line 555 of file app_voicemail.c.
| #define COPY | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (copy_plain_file(g,h)); |
| #define DATA_EXPORT_VM_USERS | ( | USER | ) |
Definition at line 12369 of file app_voicemail.c.
| #define DATA_EXPORT_VM_ZONES | ( | ZONE | ) |
Value:
ZONE(vm_zone, name, AST_DATA_STRING) \ ZONE(vm_zone, timezone, AST_DATA_STRING) \ ZONE(vm_zone, msg_format, AST_DATA_STRING)
Definition at line 12396 of file app_voicemail.c.
| #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 971 of file app_voicemail.c.
Referenced by actual_load_config().
| #define DELETE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (vm_delete(c)) |
Definition at line 899 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 894 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), message_range_and_existence_check(), notify_new_message(), play_message(), play_record_review(), sayname(), vm_intro(), vm_msg_forward(), vm_msg_play(), vm_msg_snapshot_create(), vm_options(), and vm_tempgreeting().
| #define ENDL "\n" |
Definition at line 590 of file app_voicemail.c.
Referenced by add_email_attachment(), base_encode(), make_email_file(), ochar(), and sendpage().
| #define ERROR_LOCK_PATH -100 |
Definition at line 615 of file app_voicemail.c.
| #define EXISTS | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) | (ast_fileexists(c,NULL,d) > 0) |
Definition at line 896 of file app_voicemail.c.
Referenced by close_mailbox(), copy_message(), resequence_mailbox(), 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 578 of file app_voicemail.c.
Referenced by leave_voicemail(), play_record_review(), and vm_forwardoptions().
| #define MAX_DATETIME_FORMAT 512 |
Definition at line 593 of file app_voicemail.c.
| #define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 594 of file app_voicemail.c.
| #define MAXMSG 100 |
Definition at line 580 of file app_voicemail.c.
Referenced by actual_load_config(), and apply_option().
| #define MAXMSGLIMIT 9999 |
Definition at line 581 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), and last_message_index().
| #define MINPASSWORD 0 |
Default minimum mailbox password length
Definition at line 583 of file app_voicemail.c.
Referenced by actual_load_config().
| #define OPERATOR_EXIT 300 |
Definition at line 616 of file app_voicemail.c.
Referenced by leave_voicemail(), vm_exec(), and vm_execmain().
| #define PWDCHANGE_EXTERNAL (1 << 2) |
Definition at line 912 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
| #define PWDCHANGE_INTERNAL (1 << 1) |
Definition at line 911 of file app_voicemail.c.
Referenced by actual_load_config(), vm_newuser(), and vm_options().
| #define RENAME | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h | ) | (rename_file(g,h)); |
Definition at line 897 of file app_voicemail.c.
Referenced by close_mailbox(), leave_voicemail(), resequence_mailbox(), and save_to_folder().
| #define RETRIEVE | ( | a, | |||
| b, | |||||
| c, | |||||
| d | ) |
Definition at line 893 of file app_voicemail.c.
Referenced by advanced_options(), forward_message(), invent_message(), leave_voicemail(), message_range_and_existence_check(), notify_new_message(), play_message(), sayname(), vm_intro(), vm_msg_forward(), vm_msg_play(), vm_msg_snapshot_create(), vm_options(), and vm_tempgreeting().
| #define SENDMAIL "/usr/sbin/sendmail -t" |
Definition at line 576 of file app_voicemail.c.
| #define SMDI_MWI_WAIT_TIMEOUT 1000 |
| #define STORE | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f, | |||||
| g, | |||||
| h, | |||||
| i, | |||||
| j, | |||||
| k | ) |
Definition at line 895 of file app_voicemail.c.
Referenced by copy_message(), forward_message(), leave_voicemail(), msg_create_from_file(), and play_record_review().
| #define tdesc "Comedian Mail (Voicemail System)" |
Definition at line 921 of file app_voicemail.c.
| #define UPDATE_MSG_ID | ( | a, | |||
| b, | |||||
| c, | |||||
| d, | |||||
| e, | |||||
| f | ) |
| #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 609 of file app_voicemail.c.
Referenced by AST_TEST_DEFINE(), find_user(), find_user_realtime(), free_user(), and free_vm_users().
| #define VM_ATTACH (1 << 11) |
Attach message to voicemail notifications?
Definition at line 607 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), forward_message(), manager_list_voicemail_users(), notify_new_message(), and sendmail().
| #define VM_DELETE (1 << 12) |
Delete message after sending notification
Definition at line 608 of file app_voicemail.c.
Referenced by apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and notify_new_message().
| #define VM_DIRECFORWARD (1 << 10) |
Permit caller to use the Directory app for selecting to which mailbox to forward a VM
Definition at line 606 of file app_voicemail.c.
Referenced by actual_load_config(), and forward_message().
| #define VM_ENVELOPE (1 << 4) |
Play the envelope information (who-from, time received, etc.)
Definition at line 600 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().
| #define VM_FORCEGREET (1 << 8) |
Have new users record their greetings
Definition at line 604 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().
| #define VM_FORCENAME (1 << 7) |
Have new users record their name
Definition at line 603 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_newuser().
| #define VM_FWDURGAUTO (1 << 18) |
Autoset of Urgent flag on forwarded Urgent messages set globally
Definition at line 614 of file app_voicemail.c.
Referenced by actual_load_config(), and forward_message().
| #define VM_MESSAGEWRAP (1 << 17) |
Wrap around from the last message to the first, and vice-versa
Definition at line 613 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), vm_execmain(), and vm_instructions_en().
| #define VM_MOVEHEARD (1 << 16) |
Move a "heard" message to Old after listening to it
Definition at line 612 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and close_mailbox().
| #define VM_OPERATOR (1 << 1) |
Allow 0 to be pressed to go to 'o' extension
Definition at line 597 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), leave_voicemail(), manager_list_voicemail_users(), and play_record_review().
| #define VM_PBXSKIP (1 << 9) |
Skip the [PBX] preamble in the Subject line of emails
Definition at line 605 of file app_voicemail.c.
Referenced by actual_load_config(), and make_email_file().
| #define VM_REVIEW (1 << 0) |
After recording, permit the caller to review the recording before saving
Definition at line 596 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_record_review().
| #define VM_SAYCID (1 << 2) |
Repeat the CallerID info during envelope playback
Definition at line 598 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), manager_list_voicemail_users(), and play_message().
| #define VM_SAYDURATION (1 << 5) |
Play the length of the message during envelope playback
Definition at line 601 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and play_message().
| #define VM_SEARCH (1 << 14) |
Search all contexts for a matching mailbox
Definition at line 610 of file app_voicemail.c.
Referenced by actual_load_config(), find_or_create(), find_user(), and find_user_realtime().
| #define VM_SKIPAFTERCMD (1 << 6) |
After deletion, assume caller wants to go to the next message
Definition at line 602 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().
| #define VM_SVMAIL (1 << 3) |
Allow the user to compose a new VM from within VoicemailMain
Definition at line 599 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_execmain().
| #define VM_TEMPGREETWARN (1 << 15) |
Remind user tempgreeting is set
Definition at line 611 of file app_voicemail.c.
Referenced by actual_load_config(), apply_option(), AST_TEST_DEFINE(), and vm_intro().
| #define VMSTATE_MAX_MSG_ARRAY 256 |
Definition at line 830 of file app_voicemail.c.
| #define VOICEMAIL_CONFIG "voicemail.conf" |
Definition at line 561 of file app_voicemail.c.
| #define VOICEMAIL_DIR_MODE 0777 |
Definition at line 557 of file app_voicemail.c.
| #define VOICEMAIL_FILE_MODE 0666 |
Definition at line 558 of file app_voicemail.c.
Referenced by add_email_attachment(), copy(), leave_voicemail(), msg_create_from_file(), and vm_mkftemp().
| enum vm_box |
Definition at line 618 of file app_voicemail.c.
00618 { 00619 NEW_FOLDER, 00620 OLD_FOLDER, 00621 WORK_FOLDER, 00622 FAMILY_FOLDER, 00623 FRIENDS_FOLDER, 00624 GREETINGS_FOLDER 00625 };
| enum vm_option_args |
Definition at line 639 of file app_voicemail.c.
00639 { 00640 OPT_ARG_RECORDGAIN = 0, 00641 OPT_ARG_PLAYFOLDER = 1, 00642 OPT_ARG_DTMFEXIT = 2, 00643 /* This *must* be the last value in this enum! */ 00644 OPT_ARG_ARRAY_SIZE = 3, 00645 };
| 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 627 of file app_voicemail.c.
00627 { 00628 OPT_SILENT = (1 << 0), 00629 OPT_BUSY_GREETING = (1 << 1), 00630 OPT_UNAVAIL_GREETING = (1 << 2), 00631 OPT_RECORDGAIN = (1 << 3), 00632 OPT_PREPEND_MAILBOX = (1 << 4), 00633 OPT_AUTOPLAY = (1 << 6), 00634 OPT_DTMFEXIT = (1 << 7), 00635 OPT_MESSAGE_Urgent = (1 << 8), 00636 OPT_MESSAGE_PRIORITY = (1 << 9) 00637 };
| enum vm_passwordlocation |
Definition at line 647 of file app_voicemail.c.
00647 { 00648 OPT_PWLOC_VOICEMAILCONF = 0, 00649 OPT_PWLOC_SPOOLDIR = 1, 00650 OPT_PWLOC_USERSCONF = 2, 00651 };
| static void __fini_mwi_subs | ( | void | ) | [static] |
Definition at line 1007 of file app_voicemail.c.
01026 : * 1. create a sound along the lines of "Please try again. When done, press the pound key" which could be spliced
| static int __has_voicemail | ( | const char * | context, | |
| const char * | mailbox, | |||
| const char * | folder, | |||
| int | shortcircuit | |||
| ) | [static] |
Definition at line 5752 of file app_voicemail.c.
References ast_strlen_zero().
Referenced by has_voicemail(), inboxcount2(), and messagecount().
05753 { 05754 DIR *dir; 05755 struct dirent *de; 05756 char fn[256]; 05757 int ret = 0; 05758 05759 /* If no mailbox, return immediately */ 05760 if (ast_strlen_zero(mailbox)) 05761 return 0; 05762 05763 if (ast_strlen_zero(folder)) 05764 folder = "INBOX"; 05765 if (ast_strlen_zero(context)) 05766 context = "default"; 05767 05768 snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder); 05769 05770 if (!(dir = opendir(fn))) 05771 return 0; 05772 05773 while ((de = readdir(dir))) { 05774 if (!strncasecmp(de->d_name, "msg", 3)) { 05775 if (shortcircuit) { 05776 ret = 1; 05777 break; 05778 } else if (!strncasecmp(de->d_name + 8, "txt", 3)) { 05779 ret++; 05780 } 05781 } 05782 } 05783 05784 closedir(dir); 05785 05786 return ret; 05787 }
| static void __init_mwi_subs | ( | void | ) | [static] |
Definition at line 1007 of file app_voicemail.c.
01026 : * 1. create a sound along the lines of "Please try again. When done, press the pound key" which could be spliced
| static void __reg_module | ( | void | ) | [static] |
Definition at line 15710 of file app_voicemail.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 15710 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 11987 of file app_voicemail.c.
References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_LOG_WARNING, AST_NONSTANDARD_APP_ARGS, ast_strlen_zero(), find_user(), LOG_ERROR, and mbox().
11988 { 11989 struct ast_vm_user svm; 11990 AST_DECLARE_APP_ARGS(arg, 11991 AST_APP_ARG(mbox); 11992 AST_APP_ARG(context); 11993 ); 11994 static int dep_warning = 0; 11995 11996 AST_NONSTANDARD_APP_ARGS(arg, args, '@'); 11997 11998 if (ast_strlen_zero(arg.mbox)) { 11999 ast_log(LOG_ERROR, "MAILBOX_EXISTS requires an argument (<mailbox>[@<context>])\n"); 12000 return -1; 12001 } 12002 12003 if (!dep_warning) { 12004 dep_warning = 1; 12005 ast_log(AST_LOG_WARNING, "MAILBOX_EXISTS is deprecated. Please use ${VM_INFO(%s,exists)} instead.\n", args); 12006 } 12007 12008 ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len); 12009 return 0; 12010 }
| static int acf_vm_info | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | args, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 12012 of file app_voicemail.c.
References AST_APP_ARG, ast_channel_language(), ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_vm_user::email, find_user(), ast_vm_user::fullname, ast_vm_user::language, ast_vm_user::locale, LOG_ERROR, messagecount(), ast_vm_user::pager, parse(), ast_vm_user::password, S_OR, strsep(), and ast_vm_user::zonetag.
12013 { 12014 struct ast_vm_user *vmu = NULL; 12015 char *tmp, *mailbox, *context, *parse; 12016 int res = 0; 12017 12018 AST_DECLARE_APP_ARGS(arg, 12019 AST_APP_ARG(mailbox_context); 12020 AST_APP_ARG(attribute); 12021 AST_APP_ARG(folder); 12022 ); 12023 12024 buf[0] = '\0'; 12025 12026 if (ast_strlen_zero(args)) { 12027 ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n"); 12028 return -1; 12029 } 12030 12031 parse = ast_strdupa(args); 12032 AST_STANDARD_APP_ARGS(arg, parse); 12033 12034 if (ast_strlen_zero(arg.mailbox_context) || ast_strlen_zero(arg.attribute)) { 12035 ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n"); 12036 return -1; 12037 } 12038 12039 tmp = ast_strdupa(arg.mailbox_context); 12040 mailbox = strsep(&tmp, "@"); 12041 context = strsep(&tmp, ""); 12042 12043 if (ast_strlen_zero(context)) { 12044 context = "default"; 12045 } 12046 12047 vmu = find_user(NULL, context, mailbox); 12048 12049 if (!strncasecmp(arg.attribute, "exists", 5)) { 12050 ast_copy_string(buf, vmu ? "1" : "0", len); 12051 return 0; 12052 } 12053 12054 if (vmu) { 12055 if (!strncasecmp(arg.attribute, "password", 8)) { 12056 ast_copy_string(buf, vmu->password, len); 12057 } else if (!strncasecmp(arg.attribute, "fullname", 8)) { 12058 ast_copy_string(buf, vmu->fullname, len); 12059 } else if (!strncasecmp(arg.attribute, "email", 5)) { 12060 ast_copy_string(buf, vmu->email, len); 12061 } else if (!strncasecmp(arg.attribute, "pager", 5)) { 12062 ast_copy_string(buf, vmu->pager, len); 12063 } else if (!strncasecmp(arg.attribute, "language", 8)) { 12064 ast_copy_string(buf, S_OR(vmu->language, ast_channel_language(chan)), len); 12065 } else if (!strncasecmp(arg.attribute, "locale", 6)) { 12066 ast_copy_string(buf, vmu->locale, len); 12067 } else if (!strncasecmp(arg.attribute, "tz", 2)) { 12068 ast_copy_string(buf, vmu->zonetag, len); 12069 } else if (!strncasecmp(arg.attribute, "count", 5)) { 12070 /* If mbxfolder is empty messagecount will default to INBOX */ 12071 res = messagecount(context, mailbox, arg.folder); 12072 if (res < 0) { 12073 ast_log(LOG_ERROR, "Unable to retrieve message count for mailbox %s\n", arg.mailbox_context); 12074 return -1; 12075 } 12076 snprintf(buf, len, "%d", res); 12077 } else { 12078 ast_log(LOG_ERROR, "Unknown attribute '%s' for VM_INFO\n", arg.attribute); 12079 return -1; 12080 } 12081 } 12082 12083 return 0; 12084 }
| static int actual_load_config | ( | int | reload, | |
| struct ast_config * | cfg, | |||
| struct ast_config * | ucfg | |||
| ) | [static] |
Definition at line 12949 of file app_voicemail.c.
References adsifdn, adsisec, adsiver, append_mailbox(), apply_options_full(), ast_category_browse(), ast_config_option(), ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_false(), ast_format_str_reduce(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, ast_malloc, AST_PTHREADT_NULL, ast_set2_flag, ast_smdi_interface_find(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ASTERISK_USERNAME, callcontext, cidinternalcontexts, 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, pagerdateformat, 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_prepend_timeout, vm_reenterpassword, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SEARCH, VM_SKIPAFTERCMD, VM_SVMAIL, and VM_TEMPGREETWARN.
Referenced by load_config().
12950 { 12951 struct ast_vm_user *current; 12952 char *cat; 12953 struct ast_variable *var; 12954 const char *val; 12955 char *q, *stringp, *tmp; 12956 int x; 12957 int tmpadsi[4]; 12958 char secretfn[PATH_MAX] = ""; 12959 12960 #ifdef IMAP_STORAGE 12961 ast_copy_string(imapparentfolder, "\0", sizeof(imapparentfolder)); 12962 #endif 12963 /* set audio control prompts */ 12964 strcpy(listen_control_forward_key, DEFAULT_LISTEN_CONTROL_FORWARD_KEY); 12965 strcpy(listen_control_reverse_key, DEFAULT_LISTEN_CONTROL_REVERSE_KEY); 12966 strcpy(listen_control_pause_key, DEFAULT_LISTEN_CONTROL_PAUSE_KEY); 12967 strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); 12968 strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); 12969 12970 /* Free all the users structure */ 12971 free_vm_users(); 12972 12973 /* Free all the zones structure */ 12974 free_vm_zones(); 12975 12976 AST_LIST_LOCK(&users); 12977 12978 memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd)); 12979 memset(ext_pass_check_cmd, 0, sizeof(ext_pass_check_cmd)); 12980 12981 if (cfg) { 12982 /* General settings */ 12983 12984 if (!(val = ast_variable_retrieve(cfg, "general", "userscontext"))) 12985 val = "default"; 12986 ast_copy_string(userscontext, val, sizeof(userscontext)); 12987 /* Attach voice message to mail message ? */ 12988 if (!(val = ast_variable_retrieve(cfg, "general", "attach"))) 12989 val = "yes"; 12990 ast_set2_flag((&globalflags), ast_true(val), VM_ATTACH); 12991 12992 if (!(val = ast_variable_retrieve(cfg, "general", "searchcontexts"))) 12993 val = "no"; 12994 ast_set2_flag((&globalflags), ast_true(val), VM_SEARCH); 12995 12996 volgain = 0.0; 12997 if ((val = ast_variable_retrieve(cfg, "general", "volgain"))) 12998 sscanf(val, "%30lf", &volgain); 12999 13000 #ifdef ODBC_STORAGE 13001 strcpy(odbc_database, "asterisk"); 13002 if ((val = ast_variable_retrieve(cfg, "general", "odbcstorage"))) { 13003 ast_copy_string(odbc_database, val, sizeof(odbc_database)); 13004 } 13005 strcpy(odbc_table, "voicemessages"); 13006 if ((val = ast_variable_retrieve(cfg, "general", "odbctable"))) { 13007 ast_copy_string(odbc_table, val, sizeof(odbc_table)); 13008 } 13009 #endif 13010 /* Mail command */ 13011 strcpy(mailcmd, SENDMAIL); 13012 if ((val = ast_variable_retrieve(cfg, "general", "mailcmd"))) 13013 ast_copy_string(mailcmd, val, sizeof(mailcmd)); /* User setting */ 13014 13015 maxsilence = 0; 13016 if ((val = ast_variable_retrieve(cfg, "general", "maxsilence"))) { 13017 maxsilence = atoi(val); 13018 if (maxsilence > 0) 13019 maxsilence *= 1000; 13020 } 13021 13022 if (!(val = ast_variable_retrieve(cfg, "general", "maxmsg"))) { 13023 maxmsg = MAXMSG; 13024 } else { 13025 maxmsg = atoi(val); 13026 if (maxmsg < 0) { 13027 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder '%s'. Using default value %i\n", val, MAXMSG); 13028 maxmsg = MAXMSG; 13029 } else if (maxmsg > MAXMSGLIMIT) { 13030 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 13031 maxmsg = MAXMSGLIMIT; 13032 } 13033 } 13034 13035 if (!(val = ast_variable_retrieve(cfg, "general", "backupdeleted"))) { 13036 maxdeletedmsg = 0; 13037 } else { 13038 if (sscanf(val, "%30d", &x) == 1) 13039 maxdeletedmsg = x; 13040 else if (ast_true(val)) 13041 maxdeletedmsg = MAXMSG; 13042 else 13043 maxdeletedmsg = 0; 13044 13045 if (maxdeletedmsg < 0) { 13046 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox '%s'. Using default value %i\n", val, MAXMSG); 13047 maxdeletedmsg = MAXMSG; 13048 } else if (maxdeletedmsg > MAXMSGLIMIT) { 13049 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %i. Cannot accept value '%s'\n", MAXMSGLIMIT, val); 13050 maxdeletedmsg = MAXMSGLIMIT; 13051 } 13052 } 13053 13054 /* Load date format config for voicemail mail */ 13055 if ((val = ast_variable_retrieve(cfg, "general", "emaildateformat"))) { 13056 ast_copy_string(emaildateformat, val, sizeof(emaildateformat)); 13057 } 13058 13059 /* Load date format config for voicemail pager mail */ 13060 if ((val = ast_variable_retrieve(cfg, "general", "pagerdateformat"))) { 13061 ast_copy_string(pagerdateformat, val, sizeof(pagerdateformat)); 13062 } 13063 13064 /* External password changing command */ 13065 if ((val = ast_variable_retrieve(cfg, "general", "externpass"))) { 13066 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 13067 pwdchange = PWDCHANGE_EXTERNAL; 13068 } else if ((val = ast_variable_retrieve(cfg, "general", "externpassnotify"))) { 13069 ast_copy_string(ext_pass_cmd, val, sizeof(ext_pass_cmd)); 13070 pwdchange = PWDCHANGE_EXTERNAL | PWDCHANGE_INTERNAL; 13071 } 13072 13073 /* External password validation command */ 13074 if ((val = ast_variable_retrieve(cfg, "general", "externpasscheck"))) { 13075 ast_copy_string(ext_pass_check_cmd, val, sizeof(ext_pass_check_cmd)); 13076 ast_debug(1, "found externpasscheck: %s\n", ext_pass_check_cmd); 13077 } 13078 13079 #ifdef IMAP_STORAGE 13080 /* IMAP server address */ 13081 if ((val = ast_variable_retrieve(cfg, "general", "imapserver"))) { 13082 ast_copy_string(imapserver, val, sizeof(imapserver)); 13083 } else { 13084 ast_copy_string(imapserver, "localhost", sizeof(imapserver)); 13085 } 13086 /* IMAP server port */ 13087 if ((val = ast_variable_retrieve(cfg, "general", "imapport"))) { 13088 ast_copy_string(imapport, val, sizeof(imapport)); 13089 } else { 13090 ast_copy_string(imapport, "143", sizeof(imapport)); 13091 } 13092 /* IMAP server flags */ 13093 if ((val = ast_variable_retrieve(cfg, "general", "imapflags"))) { 13094 ast_copy_string(imapflags, val, sizeof(imapflags)); 13095 } 13096 /* IMAP server master username */ 13097 if ((val = ast_variable_retrieve(cfg, "general", "authuser"))) { 13098 ast_copy_string(authuser, val, sizeof(authuser)); 13099 } 13100 /* IMAP server master password */ 13101 if ((val = ast_variable_retrieve(cfg, "general", "authpassword"))) { 13102 ast_copy_string(authpassword, val, sizeof(authpassword)); 13103 } 13104 /* Expunge on exit */ 13105 if ((val = ast_variable_retrieve(cfg, "general", "expungeonhangup"))) { 13106 if (ast_false(val)) 13107 expungeonhangup = 0; 13108 else 13109 expungeonhangup = 1; 13110 } else { 13111 expungeonhangup = 1; 13112 } 13113 /* IMAP voicemail folder */ 13114 if ((val = ast_variable_retrieve(cfg, "general", "imapfolder"))) { 13115 ast_copy_string(imapfolder, val, sizeof(imapfolder)); 13116 } else { 13117 ast_copy_string(imapfolder, "INBOX", sizeof(imapfolder)); 13118 } 13119 if ((val = ast_variable_retrieve(cfg, "general", "imapparentfolder"))) { 13120 ast_copy_string(imapparentfolder, val, sizeof(imapparentfolder)); 13121 } 13122 if ((val = ast_variable_retrieve(cfg, "general", "imapgreetings"))) { 13123 imapgreetings = ast_true(val); 13124 } else { 13125 imapgreetings = 0; 13126 } 13127 if ((val = ast_variable_retrieve(cfg, "general", "greetingfolder"))) { 13128 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 13129 } else if ((val = ast_variable_retrieve(cfg, "general", "greetingsfolder"))) { 13130 /* Also support greetingsfolder as documented in voicemail.conf.sample */ 13131 ast_copy_string(greetingfolder, val, sizeof(greetingfolder)); 13132 } else { 13133 ast_copy_string(greetingfolder, imapfolder, sizeof(greetingfolder)); 13134 } 13135 13136 /* There is some very unorthodox casting done here. This is due 13137 * to the way c-client handles the argument passed in. It expects a 13138 * void pointer and casts the pointer directly to a long without 13139 * first dereferencing it. */ 13140 if ((val = ast_variable_retrieve(cfg, "general", "imapreadtimeout"))) { 13141 mail_parameters(NIL, SET_READTIMEOUT, (void *) (atol(val))); 13142 } else { 13143 mail_parameters(NIL, SET_READTIMEOUT, (void *) 60L); 13144 } 13145 13146 if ((val = ast_variable_retrieve(cfg, "general", "imapwritetimeout"))) { 13147 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) (atol(val))); 13148 } else { 13149 mail_parameters(NIL, SET_WRITETIMEOUT, (void *) 60L); 13150 } 13151 13152 if ((val = ast_variable_retrieve(cfg, "general", "imapopentimeout"))) { 13153 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) (atol(val))); 13154 } else { 13155 mail_parameters(NIL, SET_OPENTIMEOUT, (void *) 60L); 13156 } 13157 13158 if ((val = ast_variable_retrieve(cfg, "general", "imapclosetimeout"))) { 13159 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) (atol(val))); 13160 } else { 13161 mail_parameters(NIL, SET_CLOSETIMEOUT, (void *) 60L); 13162 } 13163 13164 /* Increment configuration version */ 13165 imapversion++; 13166 #endif 13167 /* External voicemail notify application */ 13168 if ((val = ast_variable_retrieve(cfg, "general", "externnotify"))) { 13169 ast_copy_string(externnotify, val, sizeof(externnotify)); 13170 ast_debug(1, "found externnotify: %s\n", externnotify); 13171 } else { 13172 externnotify[0] = '\0'; 13173 } 13174 13175 /* SMDI voicemail notification */ 13176 if ((val = ast_variable_retrieve(cfg, "general", "smdienable")) && ast_true(val)) { 13177 ast_debug(1, "Enabled SMDI voicemail notification\n"); 13178 if ((val = ast_variable_retrieve(cfg, "general", "smdiport"))) { 13179 smdi_iface = ast_smdi_interface_find(val); 13180 } else { 13181 ast_debug(1, "No SMDI interface set, trying default (/dev/ttyS0)\n"); 13182 smdi_iface = ast_smdi_interface_find("/dev/ttyS0"); 13183 } 13184 if (!smdi_iface) { 13185 ast_log(AST_LOG_ERROR, "No valid SMDI interface specfied, disabling SMDI voicemail notification\n"); 13186 } 13187 } 13188 13189 /* Silence treshold */ 13190 silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 13191 if ((val = ast_variable_retrieve(cfg, "general", "silencethreshold"))) 13192 silencethreshold = atoi(val); 13193 13194 if (!(val = ast_variable_retrieve(cfg, "general", "serveremail"))) 13195 val = ASTERISK_USERNAME; 13196 ast_copy_string(serveremail, val, sizeof(serveremail)); 13197 13198 vmmaxsecs = 0; 13199 if ((val = ast_variable_retrieve(cfg, "general", "maxsecs"))) { 13200 if (sscanf(val, "%30d", &x) == 1) { 13201 vmmaxsecs = x; 13202 } else { 13203 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 13204 } 13205 } else if ((val = ast_variable_retrieve(cfg, "general", "maxmessage"))) { 13206 static int maxmessage_deprecate = 0; 13207 if (maxmessage_deprecate == 0) { 13208 maxmessage_deprecate = 1; 13209 ast_log(AST_LOG_WARNING, "Setting 'maxmessage' has been deprecated in favor of 'maxsecs'.\n"); 13210 } 13211 if (sscanf(val, "%30d", &x) == 1) { 13212 vmmaxsecs = x; 13213 } else { 13214 ast_log(AST_LOG_WARNING, "Invalid max message time length\n"); 13215 } 13216 } 13217 13218 vmminsecs = 0; 13219 if ((val = ast_variable_retrieve(cfg, "general", "minsecs"))) { 13220 if (sscanf(val, "%30d", &x) == 1) { 13221 vmminsecs = x; 13222 if (maxsilence / 1000 >= vmminsecs) { 13223 ast_log(AST_LOG_WARNING, "maxsilence should be less than minsecs or you may get empty messages\n"); 13224 } 13225 } else { 13226 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 13227 } 13228 } else if ((val = ast_variable_retrieve(cfg, "general", "minmessage"))) { 13229 static int maxmessage_deprecate = 0; 13230 if (maxmessage_deprecate == 0) { 13231 maxmessage_deprecate = 1; 13232 ast_log(AST_LOG_WARNING, "Setting 'minmessage' has been deprecated in favor of 'minsecs'.\n"); 13233 } 13234 if (sscanf(val, "%30d", &x) == 1) { 13235 vmminsecs = x; 13236 if (maxsilence / 1000 >= vmminsecs) { 13237 ast_log(AST_LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 13238 } 13239 } else { 13240 ast_log(AST_LOG_WARNING, "Invalid min message time length\n"); 13241 } 13242 } 13243 13244 val = ast_variable_retrieve(cfg, "general", "format"); 13245 if (!val) { 13246 val = "wav"; 13247 } else { 13248 tmp = ast_strdupa(val); 13249 val = ast_format_str_reduce(tmp); 13250 if (!val) { 13251 ast_log(LOG_ERROR, "Error processing format string, defaulting to format 'wav'\n"); 13252 val = "wav"; 13253 } 13254 } 13255 ast_copy_string(vmfmts, val, sizeof(vmfmts)); 13256 13257 skipms = 3000; 13258 if ((val = ast_variable_retrieve(cfg, "general", "maxgreet"))) { 13259 if (sscanf(val, "%30d", &x) == 1) { 13260 maxgreet = x; 13261 } else { 13262 ast_log(AST_LOG_WARNING, "Invalid max message greeting length\n"); 13263 } 13264 } 13265 13266 if ((val = ast_variable_retrieve(cfg, "general", "skipms"))) { 13267 if (sscanf(val, "%30d", &x) == 1) { 13268 skipms = x; 13269 } else { 13270 ast_log(AST_LOG_WARNING, "Invalid skipms value\n"); 13271 } 13272 } 13273 13274 maxlogins = 3; 13275 if ((val = ast_variable_retrieve(cfg, "general", "maxlogins"))) { 13276 if (sscanf(val, "%30d", &x) == 1) { 13277 maxlogins = x; 13278 } else { 13279 ast_log(AST_LOG_WARNING, "Invalid max failed login attempts\n"); 13280 } 13281 } 13282 13283 minpassword = MINPASSWORD; 13284 if ((val = ast_variable_retrieve(cfg, "general", "minpassword"))) { 13285 if (sscanf(val, "%30d", &x) == 1) { 13286 minpassword = x; 13287 } else { 13288 ast_log(AST_LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); 13289 } 13290 } 13291 13292 /* Force new user to record name ? */ 13293 if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) 13294 val = "no"; 13295 ast_set2_flag((&globalflags), ast_true(val), VM_FORCENAME); 13296 13297 /* Force new user to record greetings ? */ 13298 if (!(val = ast_variable_retrieve(cfg, "general", "forcegreetings"))) 13299 val = "no"; 13300 ast_set2_flag((&globalflags), ast_true(val), VM_FORCEGREET); 13301 13302 if ((val = ast_variable_retrieve(cfg, "general", "cidinternalcontexts"))) { 13303 ast_debug(1, "VM_CID Internal context string: %s\n", val); 13304 stringp = ast_strdupa(val); 13305 for (x = 0 ; x < MAX_NUM_CID_CONTEXTS ; x++){ 13306 if (!ast_strlen_zero(stringp)) { 13307 q = strsep(&stringp, ","); 13308 while ((*q == ' ')||(*q == '\t')) /* Eat white space between contexts */ 13309 q++; 13310 ast_copy_string(cidinternalcontexts[x], q, sizeof(cidinternalcontexts[x])); 13311 ast_debug(1, "VM_CID Internal context %d: %s\n", x, cidinternalcontexts[x]); 13312 } else { 13313 cidinternalcontexts[x][0] = '\0'; 13314 } 13315 } 13316 } 13317 if (!(val = ast_variable_retrieve(cfg, "general", "review"))){ 13318 ast_debug(1, "VM Review Option disabled globally\n"); 13319 val = "no"; 13320 } 13321 ast_set2_flag((&globalflags), ast_true(val), VM_REVIEW); 13322 13323 /* Temporary greeting reminder */ 13324 if (!(val = ast_variable_retrieve(cfg, "general", "tempgreetwarn"))) { 13325 ast_debug(1, "VM Temporary Greeting Reminder Option disabled globally\n"); 13326 val = "no"; 13327 } else { 13328 ast_debug(1, "VM Temporary Greeting Reminder Option enabled globally\n"); 13329 } 13330 ast_set2_flag((&globalflags), ast_true(val), VM_TEMPGREETWARN); 13331 if (!(val = ast_variable_retrieve(cfg, "general", "messagewrap"))){ 13332 ast_debug(1, "VM next message wrap disabled globally\n"); 13333 val = "no"; 13334 } 13335 ast_set2_flag((&globalflags), ast_true(val), VM_MESSAGEWRAP); 13336 13337 if (!(val = ast_variable_retrieve(cfg, "general", "operator"))){ 13338 ast_debug(1, "VM Operator break disabled globally\n"); 13339 val = "no"; 13340 } 13341 ast_set2_flag((&globalflags), ast_true(val), VM_OPERATOR); 13342 13343 if (!(val = ast_variable_retrieve(cfg, "general", "saycid"))) { 13344 ast_debug(1, "VM CID Info before msg disabled globally\n"); 13345 val = "no"; 13346 } 13347 ast_set2_flag((&globalflags), ast_true(val), VM_SAYCID); 13348 13349 if (!(val = ast_variable_retrieve(cfg, "general", "sendvoicemail"))){ 13350 ast_debug(1, "Send Voicemail msg disabled globally\n"); 13351 val = "no"; 13352 } 13353 ast_set2_flag((&globalflags), ast_true(val), VM_SVMAIL); 13354 13355 if (!(val = ast_variable_retrieve(cfg, "general", "envelope"))) { 13356 ast_debug(1, "ENVELOPE before msg enabled globally\n"); 13357 val = "yes"; 13358 } 13359 ast_set2_flag((&globalflags), ast_true(val), VM_ENVELOPE); 13360 13361 if (!(val = ast_variable_retrieve(cfg, "general", "moveheard"))) { 13362 ast_debug(1, "Move Heard enabled globally\n"); 13363 val = "yes"; 13364 } 13365 ast_set2_flag((&globalflags), ast_true(val), VM_MOVEHEARD); 13366 13367 if (!(val = ast_variable_retrieve(cfg, "general", "forward_urgent_auto"))) { 13368 ast_debug(1, "Autoset of Urgent flag on forwarded Urgent messages disabled globally\n"); 13369 val = "no"; 13370 } 13371 ast_set2_flag((&globalflags), ast_true(val), VM_FWDURGAUTO); 13372 13373 if (!(val = ast_variable_retrieve(cfg, "general", "sayduration"))) { 13374 ast_debug(1, "Duration info before msg enabled globally\n"); 13375 val = "yes"; 13376 } 13377 ast_set2_flag((&globalflags), ast_true(val), VM_SAYDURATION); 13378 13379 saydurationminfo = 2; 13380 if ((val = ast_variable_retrieve(cfg, "general", "saydurationm"))) { 13381 if (sscanf(val, "%30d", &x) == 1) { 13382 saydurationminfo = x; 13383 } else { 13384 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 13385 } 13386 } 13387 13388 if (!(val = ast_variable_retrieve(cfg, "general", "nextaftercmd"))) { 13389 ast_debug(1, "We are not going to skip to the next msg after save/delete\n"); 13390 val = "no"; 13391 } 13392 ast_set2_flag((&globalflags), ast_true(val), VM_SKIPAFTERCMD); 13393 13394 if ((val = ast_variable_retrieve(cfg, "general", "dialout"))) { 13395 ast_copy_string(dialcontext, val, sizeof(dialcontext)); 13396 ast_debug(1, "found dialout context: %s\n", dialcontext); 13397 } else { 13398 dialcontext[0] = '\0'; 13399 } 13400 13401 if ((val = ast_variable_retrieve(cfg, "general", "callback"))) { 13402 ast_copy_string(callcontext, val, sizeof(callcontext)); 13403 ast_debug(1, "found callback context: %s\n", callcontext); 13404 } else { 13405 callcontext[0] = '\0'; 13406 } 13407 13408 if ((val = ast_variable_retrieve(cfg, "general", "exitcontext"))) { 13409 ast_copy_string(exitcontext, val, sizeof(exitcontext)); 13410 ast_debug(1, "found operator context: %s\n", exitcontext); 13411 } else { 13412 exitcontext[0] = '\0'; 13413 } 13414 13415 /* load password sounds configuration */ 13416 if ((val = ast_variable_retrieve(cfg, "general", "vm-password"))) 13417 ast_copy_string(vm_password, val, sizeof(vm_password)); 13418 if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) 13419 ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); 13420 if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) 13421 ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); 13422 if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) 13423 ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); 13424 if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) 13425 ast_copy_string(vm_reenterpassword, val, sizeof(vm_reenterpassword)); 13426 if ((val = ast_variable_retrieve(cfg, "general", "vm-mismatch"))) 13427 ast_copy_string(vm_mismatch, val, sizeof(vm_mismatch)); 13428 if ((val = ast_variable_retrieve(cfg, "general", "vm-pls-try-again"))) { 13429 ast_copy_string(vm_pls_try_again, val, sizeof(vm_pls_try_again)); 13430 } 13431 if ((val = ast_variable_retrieve(cfg, "general", "vm-prepend-timeout"))) { 13432 ast_copy_string(vm_prepend_timeout, val, sizeof(vm_prepend_timeout)); 13433 } 13434 /* load configurable audio prompts */ 13435 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-forward-key")) && is_valid_dtmf(val)) 13436 ast_copy_string(listen_control_forward_key, val, sizeof(listen_control_forward_key)); 13437 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-reverse-key")) && is_valid_dtmf(val)) 13438 ast_copy_string(listen_control_reverse_key, val, sizeof(listen_control_reverse_key)); 13439 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-pause-key")) && is_valid_dtmf(val)) 13440 ast_copy_string(listen_control_pause_key, val, sizeof(listen_control_pause_key)); 13441 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-restart-key")) && is_valid_dtmf(val)) 13442 ast_copy_string(listen_control_restart_key, val, sizeof(listen_control_restart_key)); 13443 if ((val = ast_variable_retrieve(cfg, "general", "listen-control-stop-key")) && is_valid_dtmf(val)) 13444 ast_copy_string(listen_control_stop_key, val, sizeof(listen_control_stop_key)); 13445 13446 if (!(val = ast_variable_retrieve(cfg, "general", "usedirectory"))) 13447 val = "no"; 13448 ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD); 13449 13450 if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) { 13451 val = "voicemail.conf"; 13452 } 13453 if (!(strcmp(val, "spooldir"))) { 13454 passwordlocation = OPT_PWLOC_SPOOLDIR; 13455 } else { 13456 passwordlocation = OPT_PWLOC_VOICEMAILCONF; 13457 } 13458 13459 poll_freq = DEFAULT_POLL_FREQ; 13460 if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) { 13461 if (sscanf(val, "%30u", &poll_freq) != 1) { 13462 poll_freq = DEFAULT_POLL_FREQ; 13463 ast_log(AST_LOG_ERROR, "'%s' is not a valid value for the pollfreq option!\n", val); 13464 } 13465 } 13466 13467 poll_mailboxes = 0; 13468 if ((val = ast_variable_retrieve(cfg, "general", "pollmailboxes"))) 13469 poll_mailboxes = ast_true(val); 13470 13471 memset(fromstring, 0, sizeof(fromstring)); 13472 memset(pagerfromstring, 0, sizeof(pagerfromstring)); 13473 strcpy(charset, "ISO-8859-1"); 13474 if (emailbody) { 13475 ast_free(emailbody); 13476 emailbody = NULL; 13477 } 13478 if (emailsubject) { 13479 ast_free(emailsubject); 13480 emailsubject = NULL; 13481 } 13482 if (pagerbody) { 13483 ast_free(pagerbody); 13484 pagerbody = NULL; 13485 } 13486 if (pagersubject) { 13487 ast_free(pagersubject); 13488 pagersubject = NULL; 13489 } 13490 if ((val = ast_variable_retrieve(cfg, "general", "pbxskip"))) 13491 ast_set2_flag((&globalflags), ast_true(val), VM_PBXSKIP); 13492 if ((val = ast_variable_retrieve(cfg, "general", "fromstring"))) 13493 ast_copy_string(fromstring, val, sizeof(fromstring)); 13494 if ((val = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 13495 ast_copy_string(pagerfromstring, val, sizeof(pagerfromstring)); 13496 if ((val = ast_variable_retrieve(cfg, "general", "charset"))) 13497 ast_copy_string(charset, val, sizeof(charset)); 13498 if ((val = ast_variable_retrieve(cfg, "general", "adsifdn"))) { 13499 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 13500 for (x = 0; x < 4; x++) { 13501 memcpy(&adsifdn[x], &tmpadsi[x], 1); 13502 } 13503 } 13504 if ((val = ast_variable_retrieve(cfg, "general", "adsisec"))) { 13505 sscanf(val, "%2x%2x%2x%2x", &tmpadsi[0], &tmpadsi[1], &tmpadsi[2], &tmpadsi[3]); 13506 for (x = 0; x < 4; x++) { 13507 memcpy(&adsisec[x], &tmpadsi[x], 1); 13508 } 13509 } 13510 if ((val = ast_variable_retrieve(cfg, "general", "adsiver"))) { 13511 if (atoi(val)) { 13512 adsiver = atoi(val); 13513 } 13514 } 13515 if ((val = ast_variable_retrieve(cfg, "general", "tz"))) { 13516 ast_copy_string(zonetag, val, sizeof(zonetag)); 13517 } 13518 if ((val = ast_variable_retrieve(cfg, "general", "locale"))) { 13519 ast_copy_string(locale, val, sizeof(locale)); 13520 } 13521 if ((val = ast_variable_retrieve(cfg, "general", "emailsubject"))) { 13522 emailsubject = ast_strdup(substitute_escapes(val)); 13523 } 13524 if ((val = ast_variable_retrieve(cfg, "general", "emailbody"))) { 13525 emailbody = ast_strdup(substitute_escapes(val)); 13526 } 13527 if ((val = ast_variable_retrieve(cfg, "general", "pagersubject"))) { 13528 pagersubject = ast_strdup(substitute_escapes(val)); 13529 } 13530 if ((val = ast_variable_retrieve(cfg, "general", "pagerbody"))) { 13531 pagerbody = ast_strdup(substitute_escapes(val)); 13532 } 13533 13534 /* load mailboxes from users.conf */ 13535 if (ucfg) { 13536 for (cat = ast_category_browse(ucfg, NULL); cat ; cat = ast_category_browse(ucfg, cat)) { 13537 if (!strcasecmp(cat, "general")) { 13538 continue; 13539 } 13540 if (!ast_true(ast_config_option(ucfg, cat, "hasvoicemail"))) 13541 continue; 13542 if ((current = find_or_create(userscontext, cat))) { 13543 populate_defaults(current); 13544 apply_options_full(current, ast_variable_browse(ucfg, cat)); 13545 ast_copy_string(current->context, userscontext, sizeof(current->context)); 13546 if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) { 13547 current->passwordlocation = OPT_PWLOC_USERSCONF; 13548 } 13549 13550 switch (current->passwordlocation) { 13551 case OPT_PWLOC_SPOOLDIR: 13552 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox); 13553 read_password_from_file(secretfn, current->password, sizeof(current->password)); 13554 } 13555 } 13556 } 13557 } 13558 13559 /* load mailboxes from voicemail.conf */ 13560 cat = ast_category_browse(cfg, NULL); 13561 while (cat) { 13562 if (strcasecmp(cat, "general")) { 13563 var = ast_variable_browse(cfg, cat); 13564 if (strcasecmp(cat, "zonemessages")) { 13565 /* Process mailboxes in this context */ 13566 while (var) { 13567 append_mailbox(cat, var->name, var->value); 13568 var = var->next; 13569 } 13570 } else { 13571 /* Timezones in this context */ 13572 while (var) { 13573 struct vm_zone *z; 13574 if ((z = ast_malloc(sizeof(*z)))) { 13575 char *msg_format, *tzone; 13576 msg_format = ast_strdupa(var->value); 13577 tzone = strsep(&msg_format, "|,"); 13578 if (msg_format) { 13579 ast_copy_string(z->name, var->name, sizeof(z->name)); 13580 ast_copy_string(z->timezone, tzone, sizeof(z->timezone)); 13581 ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format)); 13582 AST_LIST_LOCK(&zones); 13583 AST_LIST_INSERT_HEAD(&zones, z, list); 13584 AST_LIST_UNLOCK(&zones); 13585 } else { 13586 ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno); 13587 ast_free(z); 13588 } 13589 } else { 13590 AST_LIST_UNLOCK(&users); 13591 return -1; 13592 } 13593 var = var->next; 13594 } 13595 } 13596 } 13597 cat = ast_category_browse(cfg, cat); 13598 } 13599 13600 AST_LIST_UNLOCK(&users); 13601 13602 if (poll_mailboxes && poll_thread == AST_PTHREADT_NULL) 13603 start_poll_thread(); 13604 if (!poll_mailboxes && poll_thread != AST_PTHREADT_NULL) 13605 stop_poll_thread();; 13606 13607 return 0; 13608 } else { 13609 AST_LIST_UNLOCK(&users); 13610 ast_log(AST_LOG_WARNING, "Failed to load configuration file.\n"); 13611 return 0; 13612 } 13613 }
| 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 5141 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().
05142 { 05143 char tmpdir[256], newtmp[256]; 05144 char fname[256]; 05145 char tmpcmd[256]; 05146 int tmpfd = -1; 05147 int soxstatus = 0; 05148 05149 /* Eww. We want formats to tell us their own MIME type */ 05150 char *ctype = (!strcasecmp(format, "ogg")) ? "application/" : "audio/x-"; 05151 05152 if (vmu->volgain < -.001 || vmu->volgain > .001) { 05153 create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, vmu->mailbox, "tmp"); 05154 snprintf(newtmp, sizeof(newtmp), "%s/XXXXXX", tmpdir); 05155 tmpfd = mkstemp(newtmp); 05156 chmod(newtmp, VOICEMAIL_FILE_MODE & ~my_umask); 05157 ast_debug(3, "newtmp: %s\n", newtmp); 05158 if (tmpfd > -1) { 05159 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, attach, format, newtmp, format); 05160 if ((soxstatus = ast_safe_system(tmpcmd)) == 0) { 05161 attach = newtmp; 05162 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", attach, format, vmu->volgain, mailbox); 05163 } else { 05164 ast_log(LOG_WARNING, "Sox failed to re-encode %s.%s: %s (have you installed support for all sox file formats?)\n", attach, format, 05165 soxstatus == 1 ? "Problem with command line options" : "An error occurred during file processing"); 05166 ast_log(LOG_WARNING, "Voicemail attachment will have no volume gain.\n"); 05167 } 05168 } 05169 } 05170 fprintf(p, "--%s" ENDL, bound); 05171 if (msgnum > -1) 05172 fprintf(p, "Content-Type: %s%s; name=\"%s\"" ENDL, ctype, format, filename); 05173 else 05174 fprintf(p, "Content-Type: %s%s; name=\"%s.%s\"" ENDL, ctype, format, greeting_attachment, format); 05175 fprintf(p, "Content-Transfer-Encoding: base64" ENDL); 05176 fprintf(p, "Content-Description: Voicemail sound attachment." ENDL); 05177 if (msgnum > -1) 05178 fprintf(p, "Content-Disposition: attachment; filename=\"%s\"" ENDL ENDL, filename); 05179 else 05180 fprintf(p, "Content-Disposition: attachment; filename=\"%s.%s\"" ENDL ENDL, greeting_attachment, format); 05181 snprintf(fname, sizeof(fname), "%s.%s", attach, format); 05182 base_encode(fname, p); 05183 if (last) 05184 fprintf(p, ENDL ENDL "--%s--" ENDL "." ENDL, bound); 05185 if (tmpfd > -1) { 05186 if (soxstatus == 0) { 05187 unlink(fname); 05188 } 05189 close(tmpfd); 05190 unlink(newtmp); 05191 } 05192 return 0; 05193 }
| static int add_message_id | ( | struct ast_config * | msg_cfg, | |
| char * | dir, | |||
| int | msg, | |||
| char * | filename, | |||
| char * | id, | |||
| size_t | id_size, | |||
| struct ast_vm_user * | vmu, | |||
| int | folder | |||
| ) | [static] |
Definition at line 11633 of file app_voicemail.c.
References ast_category_get(), ast_config_text_file_save(), ast_log(), ast_variable_append(), ast_variable_new(), ast_variables_destroy(), generate_random_string(), LOG_ERROR, LOG_WARNING, and UPDATE_MSG_ID.
Referenced by vm_msg_snapshot_create().
11634 { 11635 struct ast_variable *var; 11636 struct ast_category *cat; 11637 generate_random_string(id, id_size); 11638 11639 var = ast_variable_new("msg_id", id, ""); 11640 if (!var) { 11641 return -1; 11642 } 11643 11644 cat = ast_category_get(msg_cfg, "message"); 11645 if (!cat) { 11646 ast_log(LOG_ERROR, "Voicemail data file %s/%d.txt has no [message] category?\n", dir, msg); 11647 ast_variables_destroy(var); 11648 return -1; 11649 } 11650 11651 ast_variable_append(cat, var); 11652 11653 if (ast_config_text_file_save(filename, msg_cfg, "app_voicemail")) { 11654 ast_log(LOG_WARNING, "Unable to update %s to have a message ID\n", filename); 11655 return -1; 11656 } 11657 11658 UPDATE_MSG_ID(dir, msg, id, vmu, msg_cfg, folder); 11659 return 0; 11660 }
| static void adsi_begin | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 7082 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().
07083 { 07084 int x; 07085 if (!ast_adsi_available(chan)) 07086 return; 07087 x = ast_adsi_load_session(chan, adsifdn, adsiver, 1); 07088 if (x < 0) 07089 return; 07090 if (!x) { 07091 if (adsi_load_vmail(chan, useadsi)) { 07092 ast_log(AST_LOG_WARNING, "Unable to upload voicemail scripts\n"); 07093 return; 07094 } 07095 } else 07096 *useadsi = 1; 07097 }
| static void adsi_delete | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7278 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(), ast_mutex_lock, ast_mutex_unlock, vm_state::curmsg, vm_state::deleted, and vm_state::lastmsg.
Referenced by vm_execmain().
07279 { 07280 int bytes = 0; 07281 unsigned char buf[256]; 07282 unsigned char keys[8]; 07283 07284 int x; 07285 07286 if (!ast_adsi_available(chan)) 07287 return; 07288 07289 /* New meaning for keys */ 07290 for (x = 0; x < 5; x++) 07291 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 07292 07293 keys[6] = 0x0; 07294 keys[7] = 0x0; 07295 07296 if (!vms->curmsg) { 07297 /* No prev key, provide "Folder" instead */ 07298 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 07299 } 07300 if (vms->curmsg >= vms->lastmsg) { 07301 /* If last message ... */ 07302 if (vms->curmsg) { 07303 /* but not only message, provide "Folder" instead */ 07304 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 07305 } else { 07306 /* Otherwise if only message, leave blank */ 07307 keys[3] = 1; 07308 } 07309 } 07310 07311 /* If deleted, show "undeleted" */ 07312 #ifdef IMAP_STORAGE 07313 ast_mutex_lock(&vms->lock); 07314 #endif 07315 if (vms->deleted[vms->curmsg]) { 07316 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 07317 } 07318 #ifdef IMAP_STORAGE 07319 ast_mutex_unlock(&vms->lock); 07320 #endif 07321 07322 /* Except "Exit" */ 07323 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 07324 bytes += ast_adsi_set_keys(buf + bytes, keys); 07325 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07326 07327 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07328 }
| static void adsi_folders | ( | struct ast_channel * | chan, | |
| int | start, | |||
| char * | label | |||
| ) | [static] |
Definition at line 7147 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().
07148 { 07149 unsigned char buf[256]; 07150 int bytes = 0; 07151 unsigned char keys[8]; 07152 int x, y; 07153 07154 if (!ast_adsi_available(chan)) 07155 return; 07156 07157 for (x = 0; x < 5; x++) { 07158 y = ADSI_KEY_APPS + 12 + start + x; 07159 if (y > ADSI_KEY_APPS + 12 + 4) 07160 y = 0; 07161 keys[x] = ADSI_KEY_SKT | y; 07162 } 07163 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 17); 07164 keys[6] = 0; 07165 keys[7] = 0; 07166 07167 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, label, ""); 07168 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, " ", ""); 07169 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07170 bytes += ast_adsi_set_keys(buf + bytes, keys); 07171 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07172 07173 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07174 }
| static void adsi_goodbye | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 7433 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().
07434 { 07435 unsigned char buf[256]; 07436 int bytes = 0; 07437 07438 if (!ast_adsi_available(chan)) 07439 return; 07440 bytes += adsi_logo(buf + bytes); 07441 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, " ", ""); 07442 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "Goodbye", ""); 07443 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07444 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07445 07446 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07447 }
| static int adsi_load_vmail | ( | struct ast_channel * | chan, | |
| int * | useadsi | |||
| ) | [static] |
Definition at line 6953 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, and mbox().
Referenced by adsi_begin().
06954 { 06955 unsigned char buf[256]; 06956 int bytes = 0; 06957 int x; 06958 char num[5]; 06959 06960 *useadsi = 0; 06961 bytes += ast_adsi_data_mode(buf + bytes); 06962 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06963 06964 bytes = 0; 06965 bytes += adsi_logo(buf); 06966 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06967 #ifdef DISPLAY 06968 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .", ""); 06969 #endif 06970 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06971 bytes += ast_adsi_data_mode(buf + bytes); 06972 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06973 06974 if (ast_adsi_begin_download(chan, addesc, adsifdn, adsisec, adsiver)) { 06975 bytes = 0; 06976 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Cancelled.", ""); 06977 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 06978 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06979 bytes += ast_adsi_voice_mode(buf + bytes, 0); 06980 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06981 return 0; 06982 } 06983 06984 #ifdef DISPLAY 06985 /* Add a dot */ 06986 bytes = 0; 06987 bytes += ast_adsi_logo(buf); 06988 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Downloading Scripts", ""); 06989 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ..", ""); 06990 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 06991 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 06992 #endif 06993 bytes = 0; 06994 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 0, "Listen", "Listen", "1", 1); 06995 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 1, "Folder", "Folder", "2", 1); 06996 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 2, "Advanced", "Advnced", "3", 1); 06997 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Options", "Options", "0", 1); 06998 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 4, "Help", "Help", "*", 1); 06999 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 5, "Exit", "Exit", "#", 1); 07000 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 07001 07002 #ifdef DISPLAY 07003 /* Add another dot */ 07004 bytes = 0; 07005 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ...", ""); 07006 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07007 07008 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07009 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07010 #endif 07011 07012 bytes = 0; 07013 /* These buttons we load but don't use yet */ 07014 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 6, "Previous", "Prev", "4", 1); 07015 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 8, "Repeat", "Repeat", "5", 1); 07016 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 7, "Delete", "Delete", "7", 1); 07017 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 9, "Next", "Next", "6", 1); 07018 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 10, "Save", "Save", "9", 1); 07019 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 11, "Undelete", "Restore", "7", 1); 07020 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 07021 07022 #ifdef DISPLAY 07023 /* Add another dot */ 07024 bytes = 0; 07025 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " ....", ""); 07026 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07027 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07028 #endif 07029 07030 bytes = 0; 07031 for (x = 0; x < 5; x++) { 07032 snprintf(num, sizeof(num), "%d", x); 07033 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + x, mbox(NULL, x), mbox(NULL, x), num, 1); 07034 } 07035 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 12 + 5, "Cancel", "Cancel", "#", 1); 07036 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 07037 07038 #ifdef DISPLAY 07039 /* Add another dot */ 07040 bytes = 0; 07041 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, " .....", ""); 07042 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07043 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07044 #endif 07045 07046 if (ast_adsi_end_download(chan)) { 07047 bytes = 0; 07048 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Download Unsuccessful.", ""); 07049 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, "ADSI Unavailable", ""); 07050 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07051 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07052 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07053 return 0; 07054 } 07055 bytes = 0; 07056 bytes += ast_adsi_download_disconnect(buf + bytes); 07057 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07058 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD); 07059 07060 ast_debug(1, "Done downloading scripts...\n"); 07061 07062 #ifdef DISPLAY 07063 /* Add last dot */ 07064 bytes = 0; 07065 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ......", ""); 07066 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07067 #endif 07068 ast_debug(1, "Restarting session...\n"); 07069 07070 bytes = 0; 07071 /* Load the session now */ 07072 if (ast_adsi_load_session(chan, adsifdn, adsiver, 1) == 1) { 07073 *useadsi = 1; 07074 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Scripts Loaded!", ""); 07075 } else 07076 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, "Load Failed!", ""); 07077 07078 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07079 return 0; 07080 }
| static void adsi_login | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 7099 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().
07100 { 07101 unsigned char buf[256]; 07102 int bytes = 0; 07103 unsigned char keys[8]; 07104 int x; 07105 if (!ast_adsi_available(chan)) 07106 return; 07107 07108 for (x = 0; x < 8; x++) 07109 keys[x] = 0; 07110 /* Set one key for next */ 07111 keys[3] = ADSI_KEY_APPS + 3; 07112 07113 bytes += adsi_logo(buf + bytes); 07114 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_CENT, 0, " ", ""); 07115 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_CENT, 0, " ", ""); 07116 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07117 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Mailbox: ******", ""); 07118 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 1, 1, ADSI_JUST_LEFT); 07119 bytes += ast_adsi_load_soft_key(buf + bytes, ADSI_KEY_APPS + 3, "Enter", "Enter", "#", 1); 07120 bytes += ast_adsi_set_keys(buf + bytes, keys); 07121 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07122 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07123 }
| static int adsi_logo | ( | unsigned char * | buf | ) | [static] |
Definition at line 6945 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().
06946 { 06947 int bytes = 0; 06948 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_CENT, 0, "Comedian Mail", ""); 06949 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_CENT, 0, "(C)2002-2006 Digium, Inc.", ""); 06950 return bytes; 06951 }
| static void adsi_message | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7176 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_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), buf1, buf2, vm_state::curbox, vm_state::curmsg, vm_state::deleted, vm_state::fn, vm_state::lastmsg, and strsep().
Referenced by play_message(), and vm_execmain().
07177 { 07178 int bytes = 0; 07179 unsigned char buf[256]; 07180 char buf1[256], buf2[256]; 07181 char fn2[PATH_MAX]; 07182 07183 char cid[256] = ""; 07184 char *val; 07185 char *name, *num; 07186 char datetime[21] = ""; 07187 FILE *f; 07188 07189 unsigned char keys[8]; 07190 07191 int x; 07192 07193 if (!ast_adsi_available(chan)) 07194 return; 07195 07196 /* Retrieve important info */ 07197 snprintf(fn2, sizeof(fn2), "%s.txt", vms->fn); 07198 f = fopen(fn2, "r"); 07199 if (f) { 07200 while (!feof(f)) { 07201 if (!fgets((char *) buf, sizeof(buf), f)) { 07202 continue; 07203 } 07204 if (!feof(f)) { 07205 char *stringp = NULL; 07206 stringp = (char *) buf; 07207 strsep(&stringp, "="); 07208 val = strsep(&stringp, "="); 07209 if (!ast_strlen_zero(val)) { 07210 if (!strcmp((char *) buf, "callerid")) 07211 ast_copy_string(cid, val, sizeof(cid)); 07212 if (!strcmp((char *) buf, "origdate")) 07213 ast_copy_string(datetime, val, sizeof(datetime)); 07214 } 07215 } 07216 } 07217 fclose(f); 07218 } 07219 /* New meaning for keys */ 07220 for (x = 0; x < 5; x++) 07221 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 6 + x); 07222 keys[6] = 0x0; 07223 keys[7] = 0x0; 07224 07225 if (!vms->curmsg) { 07226 /* No prev key, provide "Folder" instead */ 07227 keys[0] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 07228 } 07229 if (vms->curmsg >= vms->lastmsg) { 07230 /* If last message ... */ 07231 if (vms->curmsg) { 07232 /* but not only message, provide "Folder" instead */ 07233 keys[3] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 1); 07234 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07235 07236 } else { 07237 /* Otherwise if only message, leave blank */ 07238 keys[3] = 1; 07239 } 07240 } 07241 07242 if (!ast_strlen_zero(cid)) { 07243 ast_callerid_parse(cid, &name, &num); 07244 if (!name) 07245 name = num; 07246 } else { 07247 name = "Unknown Caller"; 07248 } 07249 07250 /* If deleted, show "undeleted" */ 07251 #ifdef IMAP_STORAGE 07252 ast_mutex_lock(&vms->lock); 07253 #endif 07254 if (vms->deleted[vms->curmsg]) { 07255 keys[1] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 11); 07256 } 07257 #ifdef IMAP_STORAGE 07258 ast_mutex_unlock(&vms->lock); 07259 #endif 07260 07261 /* Except "Exit" */ 07262 keys[5] = ADSI_KEY_SKT | (ADSI_KEY_APPS + 5); 07263 snprintf(buf1, sizeof(buf1), "%s%s", vms->curbox, 07264 strcasecmp(vms->curbox, "INBOX") ? " Messages" : ""); 07265 snprintf(buf2, sizeof(buf2), "Message %d of %d", vms->curmsg + 1, vms->lastmsg + 1); 07266 07267 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 07268 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 07269 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, name, ""); 07270 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 4, ADSI_JUST_LEFT, 0, datetime, ""); 07271 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07272 bytes += ast_adsi_set_keys(buf + bytes, keys); 07273 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07274 07275 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07276 }
| static void adsi_password | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 7125 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().
07126 { 07127 unsigned char buf[256]; 07128 int bytes = 0; 07129 unsigned char keys[8]; 07130 int x; 07131 if (!ast_adsi_available(chan)) 07132 return; 07133 07134 for (x = 0; x < 8; x++) 07135 keys[x] = 0; 07136 /* Set one key for next */ 07137 keys[3] = ADSI_KEY_APPS + 3; 07138 07139 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07140 bytes += ast_adsi_input_format(buf + bytes, 1, ADSI_DIR_FROM_LEFT, 0, "Password: ******", ""); 07141 bytes += ast_adsi_input_control(buf + bytes, ADSI_COMM_PAGE, 4, 0, 1, ADSI_JUST_LEFT); 07142 bytes += ast_adsi_set_keys(buf + bytes, keys); 07143 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07144 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07145 }
| static void adsi_status | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7330 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().
07331 { 07332 unsigned char buf[256] = ""; 07333 char buf1[256] = "", buf2[256] = ""; 07334 int bytes = 0; 07335 unsigned char keys[8]; 07336 int x; 07337 07338 char *newm = (vms->newmessages == 1) ? "message" : "messages"; 07339 char *oldm = (vms->oldmessages == 1) ? "message" : "messages"; 07340 if (!ast_adsi_available(chan)) 07341 return; 07342 if (vms->newmessages) { 07343 snprintf(buf1, sizeof(buf1), "You have %d new", vms->newmessages); 07344 if (vms->oldmessages) { 07345 strncat(buf1, " and", sizeof(buf1) - strlen(buf1) - 1); 07346 snprintf(buf2, sizeof(buf2), "%d old %s.", vms->oldmessages, oldm); 07347 } else { 07348 snprintf(buf2, sizeof(buf2), "%s.", newm); 07349 } 07350 } else if (vms->oldmessages) { 07351 snprintf(buf1, sizeof(buf1), "You have %d old", vms->oldmessages); 07352 snprintf(buf2, sizeof(buf2), "%s.", oldm); 07353 } else { 07354 strcpy(buf1, "You have no messages."); 07355 buf2[0] = ' '; 07356 buf2[1] = '\0'; 07357 } 07358 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 07359 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 07360 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07361 07362 for (x = 0; x < 6; x++) 07363 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 07364 keys[6] = 0; 07365 keys[7] = 0; 07366 07367 /* Don't let them listen if there are none */ 07368 if (vms->lastmsg < 0) 07369 keys[0] = 1; 07370 bytes += ast_adsi_set_keys(buf + bytes, keys); 07371 07372 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07373 07374 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07375 }
| static void adsi_status2 | ( | struct ast_channel * | chan, | |
| struct vm_state * | vms | |||
| ) | [static] |
Definition at line 7377 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().
07378 { 07379 unsigned char buf[256] = ""; 07380 char buf1[256] = "", buf2[256] = ""; 07381 int bytes = 0; 07382 unsigned char keys[8]; 07383 int x; 07384 07385 char *mess = (vms->lastmsg == 0) ? "message" : "messages"; 07386 07387 if (!ast_adsi_available(chan)) 07388 return; 07389 07390 /* Original command keys */ 07391 for (x = 0; x < 6; x++) 07392 keys[x] = ADSI_KEY_SKT | (ADSI_KEY_APPS + x); 07393 07394 keys[6] = 0; 07395 keys[7] = 0; 07396 07397 if ((vms->lastmsg + 1) < 1) 07398 keys[0] = 0; 07399 07400 snprintf(buf1, sizeof(buf1), "%s%s has", vms->curbox, 07401 strcasecmp(vms->curbox, "INBOX") ? " folder" : ""); 07402 07403 if (vms->lastmsg + 1) 07404 snprintf(buf2, sizeof(buf2), "%d %s.", vms->lastmsg + 1, mess); 07405 else 07406 strcpy(buf2, "no messages."); 07407 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 1, ADSI_JUST_LEFT, 0, buf1, ""); 07408 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 2, ADSI_JUST_LEFT, 0, buf2, ""); 07409 bytes += ast_adsi_display(buf + bytes, ADSI_COMM_PAGE, 3, ADSI_JUST_LEFT, 0, "", ""); 07410 bytes += ast_adsi_set_line(buf + bytes, ADSI_COMM_PAGE, 1); 07411 bytes += ast_adsi_set_keys(buf + bytes, keys); 07412 07413 bytes += ast_adsi_voice_mode(buf + bytes, 0); 07414 07415 ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY); 07416 07417 }
| 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 14431 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_test_suite_event_notify, ast_variable_retrieve(), ast_verb, ast_waitfordigit(), ast_vm_user::callback, CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, vm_state::curdir, vm_state::curmsg, ast_vm_user::dialout, dialout(), DISPOSE, find_user(), vm_state::fn, vm_state::heard, leave_voicemail(), ast_vm_user::mailbox, make_file(), play_message_callerid(), play_message_datetime(), leave_vm_options::record_gain, RETRIEVE, vm_state::starting, and wait_file().
Referenced by vm_execmain().
14432 { 14433 int res = 0; 14434 char filename[PATH_MAX]; 14435 struct ast_config *msg_cfg = NULL; 14436 const char *origtime, *context; 14437 char *name, *num; 14438 int retries = 0; 14439 char *cid; 14440 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, }; 14441 14442 vms->starting = 0; 14443 14444 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 14445 14446 /* Retrieve info from VM attribute file */ 14447 snprintf(filename, sizeof(filename), "%s.txt", vms->fn); 14448 RETRIEVE(vms->curdir, vms->curmsg, vmu->mailbox, vmu->context); 14449 msg_cfg = ast_config_load(filename, config_flags); 14450 DISPOSE(vms->curdir, vms->curmsg); 14451 if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) { 14452 ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename); 14453 return 0; 14454 } 14455 14456 if (!(origtime = ast_variable_retrieve(msg_cfg, "message", "origtime"))) { 14457 ast_config_destroy(msg_cfg); 14458 return 0; 14459 } 14460 14461 cid = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "callerid")); 14462 14463 context = ast_variable_retrieve(msg_cfg, "message", "context"); 14464 if (!strncasecmp("macro", context, 5)) /* Macro names in contexts are useless for our needs */ 14465 context = ast_variable_retrieve(msg_cfg, "message", "macrocontext"); 14466 switch (option) { 14467 case 3: /* Play message envelope */ 14468 if (!res) { 14469 res = play_message_datetime(chan, vmu, origtime, filename); 14470 } 14471 if (!res) { 14472 res = play_message_callerid(chan, vms, cid, context, 0, 1); 14473 } 14474 14475 res = 't'; 14476 break; 14477 14478 case 2: /* Call back */ 14479 14480 if (ast_strlen_zero(cid)) 14481 break; 14482 14483 ast_callerid_parse(cid, &name, &num); 14484 while ((res > -1) && (res != 't')) { 14485 switch (res) { 14486 case '1': 14487 if (num) { 14488 /* Dial the CID number */ 14489 res = dialout(chan, vmu, num, vmu->callback); 14490 if (res) { 14491 ast_config_destroy(msg_cfg); 14492 return 9; 14493 } 14494 } else { 14495 res = '2'; 14496 } 14497 break; 14498 14499 case '2': 14500 /* Want to enter a different number, can only do this if there's a dialout context for this user */ 14501 if (!ast_strlen_zero(vmu->dialout)) { 14502 res = dialout(chan, vmu, NULL, vmu->dialout); 14503 if (res) { 14504 ast_config_destroy(msg_cfg); 14505 return 9; 14506 } 14507 } else { 14508 ast_verb(3, "Caller can not specify callback number - no dialout context available\n"); 14509 res = ast_play_and_wait(chan, "vm-sorry"); 14510 } 14511 ast_config_destroy(msg_cfg); 14512 return res; 14513 case '*': 14514 res = 't'; 14515 break; 14516 case '3': 14517 case '4': 14518 case '5': 14519 case '6': 14520 case '7': 14521 case '8': 14522 case '9': 14523 case '0': 14524 14525 res = ast_play_and_wait(chan, "vm-sorry"); 14526 retries++; 14527 break; 14528 default: 14529 if (num) { 14530 ast_verb(3, "Confirm CID number '%s' is number to use for callback\n", num); 14531 res = ast_play_and_wait(chan, "vm-num-i-have"); 14532 if (!res) 14533 res = play_message_callerid(chan, vms, num, vmu->context, 1, 1); 14534 if (!res) 14535 res = ast_play_and_wait(chan, "vm-tocallnum"); 14536 /* Only prompt for a caller-specified number if there is a dialout context specified */ 14537 if (!ast_strlen_zero(vmu->dialout)) { 14538 if (!res) 14539 res = ast_play_and_wait(chan, "vm-calldiffnum"); 14540 } 14541 } else { 14542 res = ast_play_and_wait(chan, "vm-nonumber"); 14543 if (!ast_strlen_zero(vmu->dialout)) { 14544 if (!res) 14545 res = ast_play_and_wait(chan, "vm-toenternumber"); 14546 } 14547 } 14548 if (!res) { 14549 res = ast_play_and_wait(chan, "vm-star-cancel"); 14550 } 14551 if (!res) { 14552 res = ast_waitfordigit(chan, 6000); 14553 } 14554 if (!res) { 14555 retries++; 14556 if (retries > 3) { 14557 res = 't'; 14558 } 14559 } 14560 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 14561 break; 14562 14563 } 14564 if (res == 't') 14565 res = 0; 14566 else if (res == '*') 14567 res = -1; 14568 } 14569 break; 14570 14571 case 1: /* Reply */ 14572 /* Send reply directly to sender */ 14573 if (ast_strlen_zero(cid)) 14574 break; 14575 14576 ast_callerid_parse(cid, &name, &num); 14577 if (!num) { 14578 ast_verb(3, "No CID number available, no reply sent\n"); 14579 if (!res) 14580 res = ast_play_and_wait(chan, "vm-nonumber"); 14581 ast_config_destroy(msg_cfg); 14582 return res; 14583 } else { 14584 struct ast_vm_user vmu2; 14585 if (find_user(&vmu2, vmu->context, num)) { 14586 struct leave_vm_options leave_options; 14587 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 14588 snprintf(mailbox, sizeof(mailbox), "%s@%s", num, vmu->context); 14589 14590 ast_verb(3, "Leaving voicemail for '%s' in context '%s'\n", num, vmu->context); 14591 14592 memset(&leave_options, 0, sizeof(leave_options)); 14593 leave_options.record_gain = record_gain; 14594 res = leave_voicemail(chan, mailbox, &leave_options); 14595 if (!res) 14596 res = 't'; 14597 ast_config_destroy(msg_cfg); 14598 return res; 14599 } else { 14600 /* Sender has no mailbox, can't reply */ 14601 ast_verb(3, "No mailbox number '%s' in context '%s', no reply sent\n", num, vmu->context); 14602 ast_play_and_wait(chan, "vm-nobox"); 14603 res = 't'; 14604 ast_config_destroy(msg_cfg); 14605 return res; 14606 } 14607 } 14608 res = 0; 14609 14610 break; 14611 } 14612 14613 #ifndef IMAP_STORAGE 14614 ast_config_destroy(msg_cfg); 14615 14616 if (!res) { 14617 make_file(vms->fn, sizeof(vms->fn), vms->curdir, msg); 14618 vms->heard[msg] = 1; 14619 res = wait_file(chan, vms, vms->fn); 14620 } 14621 #endif 14622 return res; 14623 }
| static int append_mailbox | ( | const char * | context, | |
| const char * | box, | |||
| const char * | data | |||
| ) | [static] |
Definition at line 11702 of file app_voicemail.c.
References apply_options(), ast_alloca, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, find_or_create(), ast_vm_user::fullname, inboxcount2(), LOG_WARNING, ast_vm_user::mailbox, OPT_PWLOC_SPOOLDIR, ast_vm_user::pager, ast_vm_user::password, ast_vm_user::passwordlocation, populate_defaults(), queue_mwi_event(), read_password_from_file(), and strsep().
Referenced by actual_load_config().
11703 { 11704 /* Assumes lock is already held */ 11705 char *tmp; 11706 char *stringp; 11707 char *s; 11708 struct ast_vm_user *vmu; 11709 char *mailbox_full; 11710 int new = 0, old = 0, urgent = 0; 11711 char secretfn[PATH_MAX] = ""; 11712 11713 tmp = ast_strdupa(data); 11714 11715 if (!(vmu = find_or_create(context, box))) 11716 return -1; 11717 11718 populate_defaults(vmu); 11719 11720 stringp = tmp; 11721 if ((s = strsep(&stringp, ","))) { 11722 if (!ast_strlen_zero(s) && s[0] == '*') { 11723 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 11724 "\n\tmust be reset in voicemail.conf.\n", box); 11725 } 11726 /* assign password regardless of validity to prevent NULL password from being assigned */ 11727 ast_copy_string(vmu->password, s, sizeof(vmu->password)); 11728 } 11729 if (stringp && (s = strsep(&stringp, ","))) { 11730 ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname)); 11731 } 11732 if (stringp && (s = strsep(&stringp, ","))) { 11733 ast_copy_string(vmu->email, s, sizeof(vmu->email)); 11734 } 11735 if (stringp && (s = strsep(&stringp, ","))) { 11736 ast_copy_string(vmu->pager, s, sizeof(vmu->pager)); 11737 } 11738 if (stringp && (s = strsep(&stringp, ","))) { 11739 apply_options(vmu, s); 11740 } 11741 11742 switch (vmu->passwordlocation) { 11743 case OPT_PWLOC_SPOOLDIR: 11744 snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox); 11745 read_password_from_file(secretfn, vmu->password, sizeof(vmu->password)); 11746 } 11747 11748 mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1); 11749 strcpy(mailbox_full, box); 11750 strcat(mailbox_full, "@"); 11751 strcat(mailbox_full, context); 11752 11753 inboxcount2(mailbox_full, &urgent, &new, &old); 11754 queue_mwi_event(mailbox_full, urgent, new, old); 11755 11756 return 0; 11757 }
| 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 1248 of file app_voicemail.c.
References apply_options(), ast_copy_string(), ast_free, ast_log(), AST_LOG_WARNING, ast_set2_flag, ast_strdup, ast_true(), ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, ast_vm_user::language, ast_vm_user::locale, LOG_WARNING, ast_vm_user::maxdeletedmsg, MAXMSG, ast_vm_user::maxmsg, MAXMSGLIMIT, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, OPT_PWLOC_VOICEMAILCONF, ast_vm_user::passwordlocation, ast_vm_user::saydurationm, ast_vm_user::serveremail, substitute_escapes(), VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
Referenced by apply_options(), and apply_options_full().
01249 { 01250 int x; 01251 if (!strcasecmp(var, "attach")) { 01252 ast_set2_flag(vmu, ast_true(value), VM_ATTACH); 01253 } else if (!strcasecmp(var, "attachfmt")) { 01254 ast_copy_string(vmu->attachfmt, value, sizeof(vmu->attachfmt)); 01255 } else if (!strcasecmp(var, "serveremail")) { 01256 ast_copy_string(vmu->serveremail, value, sizeof(vmu->serveremail)); 01257 } else if (!strcasecmp(var, "emailbody")) { 01258 ast_free(vmu->emailbody); 01259 vmu->emailbody = ast_strdup(substitute_escapes(value)); 01260 } else if (!strcasecmp(var, "emailsubject")) { 01261 ast_free(vmu->emailsubject); 01262 vmu->emailsubject = ast_strdup(substitute_escapes(value)); 01263 } else if (!strcasecmp(var, "language")) { 01264 ast_copy_string(vmu->language, value, sizeof(vmu->language)); 01265 } else if (!strcasecmp(var, "tz")) { 01266 ast_copy_string(vmu->zonetag, value, sizeof(vmu->zonetag)); 01267 } else if (!strcasecmp(var, "locale")) { 01268 ast_copy_string(vmu->locale, value, sizeof(vmu->locale)); 01269 #ifdef IMAP_STORAGE 01270 } else if (!strcasecmp(var, "imapuser")) { 01271 ast_copy_string(vmu->imapuser, value, sizeof(vmu->imapuser)); 01272 vmu->imapversion = imapversion; 01273 } else if (!strcasecmp(var, "imapserver")) { 01274 ast_copy_string(vmu->imapserver, value, sizeof(vmu->imapserver)); 01275 vmu->imapversion = imapversion; 01276 } else if (!strcasecmp(var, "imapport")) { 01277 ast_copy_string(vmu->imapport, value, sizeof(vmu->imapport)); 01278 vmu->imapversion = imapversion; 01279 } else if (!strcasecmp(var, "imapflags")) { 01280 ast_copy_string(vmu->imapflags, value, sizeof(vmu->imapflags)); 01281 vmu->imapversion = imapversion; 01282 } else if (!strcasecmp(var, "imappassword") || !strcasecmp(var, "imapsecret")) { 01283 ast_copy_string(vmu->imappassword, value, sizeof(vmu->imappassword)); 01284 vmu->imapversion = imapversion; 01285 } else if (!strcasecmp(var, "imapfolder")) { 01286 ast_copy_string(vmu->imapfolder, value, sizeof(vmu->imapfolder)); 01287 vmu->imapversion = imapversion; 01288 } else if (!strcasecmp(var, "imapvmshareid")) { 01289 ast_copy_string(vmu->imapvmshareid, value, sizeof(vmu->imapvmshareid)); 01290 vmu->imapversion = imapversion; 01291 #endif 01292 } else if (!strcasecmp(var, "delete") || !strcasecmp(var, "deletevoicemail")) { 01293 ast_set2_flag(vmu, ast_true(value), VM_DELETE); 01294 } else if (!strcasecmp(var, "saycid")){ 01295 ast_set2_flag(vmu, ast_true(value), VM_SAYCID); 01296 } else if (!strcasecmp(var, "sendvoicemail")){ 01297 ast_set2_flag(vmu, ast_true(value), VM_SVMAIL); 01298 } else if (!strcasecmp(var, "review")){ 01299 ast_set2_flag(vmu, ast_true(value), VM_REVIEW); 01300 } else if (!strcasecmp(var, "tempgreetwarn")){ 01301 ast_set2_flag(vmu, ast_true(value), VM_TEMPGREETWARN); 01302 } else if (!strcasecmp(var, "messagewrap")){ 01303 ast_set2_flag(vmu, ast_true(value), VM_MESSAGEWRAP); 01304 } else if (!strcasecmp(var, "operator")) { 01305 ast_set2_flag(vmu, ast_true(value), VM_OPERATOR); 01306 } else if (!strcasecmp(var, "envelope")){ 01307 ast_set2_flag(vmu, ast_true(value), VM_ENVELOPE); 01308 } else if (!strcasecmp(var, "moveheard")){ 01309 ast_set2_flag(vmu, ast_true(value), VM_MOVEHEARD); 01310 } else if (!strcasecmp(var, "sayduration")){ 01311 ast_set2_flag(vmu, ast_true(value), VM_SAYDURATION); 01312 } else if (!strcasecmp(var, "saydurationm")){ 01313 if (sscanf(value, "%30d", &x) == 1) { 01314 vmu->saydurationm = x; 01315 } else { 01316 ast_log(AST_LOG_WARNING, "Invalid min duration for say duration\n"); 01317 } 01318 } else if (!strcasecmp(var, "forcename")){ 01319 ast_set2_flag(vmu, ast_true(value), VM_FORCENAME); 01320 } else if (!strcasecmp(var, "forcegreetings")){ 01321 ast_set2_flag(vmu, ast_true(value), VM_FORCEGREET); 01322 } else if (!strcasecmp(var, "callback")) { 01323 ast_copy_string(vmu->callback, value, sizeof(vmu->callback)); 01324 } else if (!strcasecmp(var, "dialout")) { 01325 ast_copy_string(vmu->dialout, value, sizeof(vmu->dialout)); 01326 } else if (!strcasecmp(var, "exitcontext")) { 01327 ast_copy_string(vmu->exit, value, sizeof(vmu->exit)); 01328 } else if (!strcasecmp(var, "minsecs")) { 01329 if (sscanf(value, "%30d", &x) == 1 && x >= 0) { 01330 vmu->minsecs = x; 01331 } else { 01332 ast_log(LOG_WARNING, "Invalid min message length of %s. Using global value %d\n", value, vmminsecs); 01333 vmu->minsecs = vmminsecs; 01334 } 01335 } else if (!strcasecmp(var, "maxmessage") || !strcasecmp(var, "maxsecs")) { 01336 vmu->maxsecs = atoi(value); 01337 if (vmu->maxsecs <= 0) { 01338 ast_log(AST_LOG_WARNING, "Invalid max message length of %s. Using global value %d\n", value, vmmaxsecs); 01339 vmu->maxsecs = vmmaxsecs; 01340 } else { 01341 vmu->maxsecs = atoi(value); 01342 } 01343 if (!strcasecmp(var, "maxmessage")) 01344 ast_log(AST_LOG_WARNING, "Option 'maxmessage' has been deprecated in favor of 'maxsecs'. Please make that change in your voicemail config.\n"); 01345 } else if (!strcasecmp(var, "maxmsg")) { 01346 vmu->maxmsg = atoi(value); 01347 /* Accept maxmsg=0 (Greetings only voicemail) */ 01348 if (vmu->maxmsg < 0) { 01349 ast_log(AST_LOG_WARNING, "Invalid number of messages per folder maxmsg=%s. Using default value %d\n", value, MAXMSG); 01350 vmu->maxmsg = MAXMSG; 01351 } else if (vmu->maxmsg > MAXMSGLIMIT) { 01352 ast_log(AST_LOG_WARNING, "Maximum number of messages per folder is %d. Cannot accept value maxmsg=%s\n", MAXMSGLIMIT, value); 01353 vmu->maxmsg = MAXMSGLIMIT; 01354 } 01355 } else if (!strcasecmp(var, "nextaftercmd")) { 01356 ast_set2_flag(vmu, ast_true(value), VM_SKIPAFTERCMD); 01357 } else if (!strcasecmp(var, "backupdeleted")) { 01358 if (sscanf(value, "%30d", &x) == 1) 01359 vmu->maxdeletedmsg = x; 01360 else if (ast_true(value)) 01361 vmu->maxdeletedmsg = MAXMSG; 01362 else 01363 vmu->maxdeletedmsg = 0; 01364 01365 if (vmu->maxdeletedmsg < 0) { 01366 ast_log(AST_LOG_WARNING, "Invalid number of deleted messages saved per mailbox backupdeleted=%s. Using default value %d\n", value, MAXMSG); 01367 vmu->maxdeletedmsg = MAXMSG; 01368 } else if (vmu->maxdeletedmsg > MAXMSGLIMIT) { 01369 ast_log(AST_LOG_WARNING, "Maximum number of deleted messages saved per mailbox is %d. Cannot accept value backupdeleted=%s\n", MAXMSGLIMIT, value); 01370 vmu->maxdeletedmsg = MAXMSGLIMIT; 01371 } 01372 } else if (!strcasecmp(var, "volgain")) { 01373 sscanf(value, "%30lf", &vmu->volgain); 01374 } else if (!strcasecmp(var, "passwordlocation")) { 01375 if (!strcasecmp(value, "spooldir")) { 01376 vmu->passwordlocation = OPT_PWLOC_SPOOLDIR; 01377 } else { 01378 vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF; 01379 } 01380 } else if (!strcasecmp(var, "options")) { 01381 apply_options(vmu, value); 01382 } 01383 }
| static void apply_options | ( | struct ast_vm_user * | vmu, | |
| const char * | options | |||
| ) | [static] |
Destructively Parse options and apply.
Definition at line 1501 of file app_voicemail.c.
References apply_option(), ast_strdupa, strsep(), value, and var.
Referenced by append_mailbox(), apply_option(), and AST_TEST_DEFINE().
01502 { 01503 char *stringp; 01504 char *s; 01505 char *var, *value; 01506 stringp = ast_strdupa(options); 01507 while ((s = strsep(&stringp, "|"))) { 01508 value = s; 01509 if ((var = strsep(&value, "=")) && value) { 01510 apply_option(vmu, var, value); 01511 } 01512 } 01513 }
| 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 1520 of file app_voicemail.c.
References apply_option(), ast_copy_string(), ast_free, ast_log(), ast_strdup, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::email, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::fullname, LOG_WARNING, ast_vm_user::mailbox, ast_variable::name, ast_variable::next, ast_vm_user::pager, ast_vm_user::password, substitute_escapes(), ast_vm_user::uniqueid, and ast_variable::value.
Referenced by actual_load_config(), and find_user_realtime().
01521 { 01522 for (; var; var = var->next) { 01523 if (!strcasecmp(var->name, "vmsecret")) { 01524 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01525 } else if (!strcasecmp(var->name, "secret") || !strcasecmp(var->name, "password")) { /* don't overwrite vmsecret if it exists */ 01526 if (ast_strlen_zero(retval->password)) { 01527 if (!ast_strlen_zero(var->value) && var->value[0] == '*') { 01528 ast_log(LOG_WARNING, "Invalid password detected for mailbox %s. The password" 01529 "\n\tmust be reset in voicemail.conf.\n", retval->mailbox); 01530 } else { 01531 ast_copy_string(retval->password, var->value, sizeof(retval->password)); 01532 } 01533 } 01534 } else if (!strcasecmp(var->name, "uniqueid")) { 01535 ast_copy_string(retval->uniqueid, var->value, sizeof(retval->uniqueid)); 01536 } else if (!strcasecmp(var->name, "pager")) { 01537 ast_copy_string(retval->pager, var->value, sizeof(retval->pager)); 01538 } else if (!strcasecmp(var->name, "email")) { 01539 ast_copy_string(retval->email, var->value, sizeof(retval->email)); 01540 } else if (!strcasecmp(var->name, "fullname")) { 01541 ast_copy_string(retval->fullname, var->value, sizeof(retval->fullname)); 01542 } else if (!strcasecmp(var->name, "context")) { 01543 ast_copy_string(retval->context, var->value, sizeof(retval->context)); 01544 } else if (!strcasecmp(var->name, "emailsubject")) { 01545 ast_free(retval->emailsubject); 01546 retval->emailsubject = ast_strdup(substitute_escapes(var->value)); 01547 } else if (!strcasecmp(var->name, "emailbody")) { 01548 ast_free(retval->emailbody); 01549 retval->emailbody = ast_strdup(substitute_escapes(var->value)); 01550 #ifdef IMAP_STORAGE 01551 } else if (!strcasecmp(var->name, "imapuser")) { 01552 ast_copy_string(retval->imapuser, var->value, sizeof(retval->imapuser)); 01553 retval->imapversion = imapversion; 01554 } else if (!strcasecmp(var->name, "imapserver")) { 01555 ast_copy_string(retval->imapserver, var->value, sizeof(retval->imapserver)); 01556 retval->imapversion = imapversion; 01557 } else if (!strcasecmp(var->name, "imapport")) { 01558 ast_copy_string(retval->imapport, var->value, sizeof(retval->imapport)); 01559 retval->imapversion = imapversion; 01560 } else if (!strcasecmp(var->name, "imapflags")) { 01561 ast_copy_string(retval->imapflags, var->value, sizeof(retval->imapflags)); 01562 retval->imapversion = imapversion; 01563 } else if (!strcasecmp(var->name, "imappassword") || !strcasecmp(var->name, "imapsecret")) { 01564 ast_copy_string(retval->imappassword, var->value, sizeof(retval->imappassword)); 01565 retval->imapversion = imapversion; 01566 } else if (!strcasecmp(var->name, "imapfolder")) { 01567 ast_copy_string(retval->imapfolder, var->value, sizeof(retval->imapfolder)); 01568 retval->imapversion = imapversion; 01569 } else if (!strcasecmp(var->name, "imapvmshareid")) { 01570 ast_copy_string(retval->imapvmshareid, var->value, sizeof(retval->imapvmshareid)); 01571 retval->imapversion = imapversion; 01572 #endif 01573 } else 01574 apply_option(retval, var->name, var->value); 01575 } 01576 }
| AST_DATA_STRUCTURE | ( | vm_zone | , | |
| DATA_EXPORT_VM_ZONES | ||||
| ) |
| AST_DATA_STRUCTURE | ( | ast_vm_user | , | |
| DATA_EXPORT_VM_USERS | ||||
| ) |
| static const char* ast_str_encode_mime | ( | struct ast_str ** | end, | |
| ssize_t | maxlen, | |||
| const char * | start, | |||
| size_t | preamble, | |||
| size_t | postamble | |||
| ) | [static] |
Encode a string according to the MIME rules for encoding strings that are not 7-bit clean or contain control characters.
Additionally, if the encoded string would exceed the MIME limit of 76 characters per line, then the encoding will be broken up into multiple sections, separated by a space character, in order to facilitate breaking up the associated header across multiple lines.
| end | An expandable buffer for holding the result | |
| maxlen | Always zero, but see |
| start | A string to be encoded | |
| preamble | The length of the first line already used for this string, to ensure that each line maintains a maximum length of 76 chars. | |
| postamble | the length of any additional characters appended to the line, used to ensure proper field wrapping. |
| The | encoded string. |
Definition at line 4797 of file app_voicemail.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), and ast_str_strlen().
04798 { 04799 struct ast_str *tmp = ast_str_alloca(80); 04800 int first_section = 1; 04801 04802 ast_str_reset(*end); 04803 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04804 for (; *start; start++) { 04805 int need_encoding = 0; 04806 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 04807 need_encoding = 1; 04808 } 04809 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 04810 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 04811 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 04812 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 04813 /* Start new line */ 04814 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 04815 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 04816 first_section = 0; 04817 } 04818 if (need_encoding && *start == ' ') { 04819 ast_str_append(&tmp, -1, "_"); 04820 } else if (need_encoding) { 04821 ast_str_append(&tmp, -1, "=%hhX", *start); 04822 } else { 04823 ast_str_append(&tmp, -1, "%c", *start); 04824 } 04825 } 04826 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 04827 return ast_str_buffer(*end); 04828 }
| 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 4725 of file app_voicemail.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
04726 { 04727 const char *ptr; 04728 04729 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 04730 ast_str_set(buf, maxlen, "\""); 04731 for (ptr = from; *ptr; ptr++) { 04732 if (*ptr == '"' || *ptr == '\\') { 04733 ast_str_append(buf, maxlen, "\\%c", *ptr); 04734 } else { 04735 ast_str_append(buf, maxlen, "%c", *ptr); 04736 } 04737 } 04738 ast_str_append(buf, maxlen, "\""); 04739 04740 return ast_str_buffer(*buf); 04741 }
| AST_TEST_DEFINE | ( | test_voicemail_vmuser | ) |
Definition at line 11759 of file app_voicemail.c.
References apply_options(), ast_calloc, ast_set_flag, AST_TEST_FAIL, ast_test_flag, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_vm_user::attachfmt, ast_vm_user::callback, ast_vm_user::dialout, ast_vm_user::emailbody, ast_vm_user::emailsubject, ast_vm_user::exit, free_user(), ast_vm_user::maxdeletedmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, OPT_PWLOC_SPOOLDIR, ast_vm_user::passwordlocation, populate_defaults(), ast_vm_user::saydurationm, ast_vm_user::serveremail, TEST_EXECUTE, TEST_INIT, VM_ALLOCED, VM_ATTACH, VM_DELETE, VM_ENVELOPE, VM_FORCEGREET, VM_FORCENAME, VM_MESSAGEWRAP, VM_MOVEHEARD, VM_OPERATOR, VM_REVIEW, VM_SAYCID, VM_SAYDURATION, VM_SKIPAFTERCMD, VM_SVMAIL, VM_TEMPGREETWARN, ast_vm_user::volgain, and ast_vm_user::zonetag.
11760 { 11761 int res = 0; 11762 struct ast_vm_user *vmu; 11763 /* language parameter seems to only be used for display in manager action */ 11764 static const char options_string[] = "attach=yes|attachfmt=wav49|" 11765 "serveremail=someguy@digium.com|tz=central|delete=yes|saycid=yes|" 11766 "sendvoicemail=yes|review=yes|tempgreetwarn=yes|messagewrap=yes|operator=yes|" 11767 "envelope=yes|moveheard=yes|sayduration=yes|saydurationm=5|forcename=yes|" 11768 "forcegreetings=yes|callback=somecontext|dialout=somecontext2|" 11769 "exitcontext=somecontext3|minsecs=10|maxsecs=100|nextaftercmd=yes|" 11770 "backupdeleted=50|volgain=1.3|passwordlocation=spooldir|emailbody=" 11771 "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message|emailsubject=" 11772 "[PBX]: New message \\\\${VM_MSGNUM}\\\\ in mailbox ${VM_MAILBOX}"; 11773 #ifdef IMAP_STORAGE 11774 static const char option_string2[] = "imapuser=imapuser|imappassword=imappasswd|" 11775 "imapfolder=INBOX|imapvmshareid=6000|imapserver=imapserver|imapport=1234|imapflags=flagged"; 11776 #endif 11777 11778 switch (cmd) { 11779 case TEST_INIT: 11780 info->name = "vmuser"; 11781 info->category = "/apps/app_voicemail/"; 11782 info->summary = "Vmuser unit test"; 11783 info->description = 11784 "This tests passing all supported parameters to apply_options, the voicemail user config parser"; 11785 return AST_TEST_NOT_RUN; 11786 case TEST_EXECUTE: 11787 break; 11788 } 11789 11790 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) { 11791 return AST_TEST_NOT_RUN; 11792 } 11793 populate_defaults(vmu); 11794 ast_set_flag(vmu, VM_ALLOCED); 11795 11796 apply_options(vmu, options_string); 11797 11798 if (!ast_test_flag(vmu, VM_ATTACH)) { 11799 ast_test_status_update(test, "Parse failure for attach option\n"); 11800 res = 1; 11801 } 11802 if (strcasecmp(vmu->attachfmt, "wav49")) { 11803 ast_test_status_update(test, "Parse failure for attachftm option\n"); 11804 res = 1; 11805 } 11806 if (strcasecmp(vmu->serveremail, "someguy@digium.com")) { 11807 ast_test_status_update(test, "Parse failure for serveremail option\n"); 11808 res = 1; 11809 } 11810 if (!vmu->emailsubject || strcasecmp(vmu->emailsubject, "[PBX]: New message \\${VM_MSGNUM}\\ in mailbox ${VM_MAILBOX}")) { 11811 ast_test_status_update(test, "Parse failure for emailsubject option\n"); 11812 res = 1; 11813 } 11814 if (!vmu->emailbody || strcasecmp(vmu->emailbody, "Dear ${VM_NAME}:\n\n\tYou were just left a ${VM_DUR} long message")) { 11815 ast_test_status_update(test, "Parse failure for emailbody option\n"); 11816 res = 1; 11817 } 11818 if (strcasecmp(vmu->zonetag, "central")) { 11819 ast_test_status_update(test, "Parse failure for tz option\n"); 11820 res = 1; 11821 } 11822 if (!ast_test_flag(vmu, VM_DELETE)) { 11823 ast_test_status_update(test, "Parse failure for delete option\n"); 11824 res = 1; 11825 } 11826 if (!ast_test_flag(vmu, VM_SAYCID)) { 11827 ast_test_status_update(test, "Parse failure for saycid option\n"); 11828 res = 1; 11829 } 11830 if (!ast_test_flag(vmu, VM_SVMAIL)) { 11831 ast_test_status_update(test, "Parse failure for sendvoicemail option\n"); 11832 res = 1; 11833 } 11834 if (!ast_test_flag(vmu, VM_REVIEW)) { 11835 ast_test_status_update(test, "Parse failure for review option\n"); 11836 res = 1; 11837 } 11838 if (!ast_test_flag(vmu, VM_TEMPGREETWARN)) { 11839 ast_test_status_update(test, "Parse failure for tempgreetwarm option\n"); 11840 res = 1; 11841 } 11842 if (!ast_test_flag(vmu, VM_MESSAGEWRAP)) { 11843 ast_test_status_update(test, "Parse failure for messagewrap option\n"); 11844 res = 1; 11845 } 11846 if (!ast_test_flag(vmu, VM_OPERATOR)) { 11847 ast_test_status_update(test, "Parse failure for operator option\n"); 11848 res = 1; 11849 } 11850 if (!ast_test_flag(vmu, VM_ENVELOPE)) { 11851 ast_test_status_update(test, "Parse failure for envelope option\n"); 11852 res = 1; 11853 } 11854 if (!ast_test_flag(vmu, VM_MOVEHEARD)) { 11855 ast_test_status_update(test, "Parse failure for moveheard option\n"); 11856 res = 1; 11857 } 11858 if (!ast_test_flag(vmu, VM_SAYDURATION)) { 11859 ast_test_status_update(test, "Parse failure for sayduration option\n"); 11860 res = 1; 11861 } 11862 if (vmu->saydurationm != 5) { 11863 ast_test_status_update(test, "Parse failure for saydurationm option\n"); 11864 res = 1; 11865 } 11866 if (!ast_test_flag(vmu, VM_FORCENAME)) { 11867 ast_test_status_update(test, "Parse failure for forcename option\n"); 11868 res = 1; 11869 } 11870 if (!ast_test_flag(vmu, VM_FORCEGREET)) { 11871 ast_test_status_update(test, "Parse failure for forcegreetings option\n"); 11872 res = 1; 11873 } 11874 if (strcasecmp(vmu->callback, "somecontext")) { 11875 ast_test_status_update(test, "Parse failure for callbacks option\n"); 11876 res = 1; 11877 } 11878 if (strcasecmp(vmu->dialout, "somecontext2")) { 11879 ast_test_status_update(test, "Parse failure for dialout option\n"); 11880 res = 1; 11881 } 11882 if (strcasecmp(vmu->exit, "somecontext3")) { 11883 ast_test_status_update(test, "Parse failure for exitcontext option\n"); 11884 res = 1; 11885 } 11886 if (vmu->minsecs != 10) { 11887 ast_test_status_update(test, "Parse failure for minsecs option\n"); 11888 res = 1; 11889 } 11890 if (vmu->maxsecs != 100) { 11891 ast_test_status_update(test, "Parse failure for maxsecs option\n"); 11892 res = 1; 11893 } 11894 if (!ast_test_flag(vmu, VM_SKIPAFTERCMD)) { 11895 ast_test_status_update(test, "Parse failure for nextaftercmd option\n"); 11896 res = 1; 11897 } 11898 if (vmu->maxdeletedmsg != 50) { 11899 ast_test_status_update(test, "Parse failure for backupdeleted option\n"); 11900 res = 1; 11901 } 11902 if (vmu->volgain != 1.3) { 11903 ast_test_status_update(test, "Parse failure for volgain option\n"); 11904 res = 1; 11905 } 11906 if (vmu->passwordlocation != OPT_PWLOC_SPOOLDIR) { 11907 ast_test_status_update(test, "Parse failure for passwordlocation option\n"); 11908 res = 1; 11909 } 11910 #ifdef IMAP_STORAGE 11911 apply_options(vmu, option_string2); 11912 11913 if (strcasecmp(vmu->imapuser, "imapuser")) { 11914 ast_test_status_update(test, "Parse failure for imapuser option\n"); 11915 res = 1; 11916 } 11917 if (strcasecmp(vmu->imappassword, "imappasswd")) { 11918 ast_test_status_update(test, "Parse failure for imappasswd option\n"); 11919 res = 1; 11920 } 11921 if (strcasecmp(vmu->imapfolder, "INBOX")) { 11922 ast_test_status_update(test, "Parse failure for imapfolder option\n"); 11923 res = 1; 11924 } 11925 if (strcasecmp(vmu->imapvmshareid, "6000")) { 11926 ast_test_status_update(test, "Parse failure for imapvmshareid option\n"); 11927 res = 1; 11928 } 11929 if (strcasecmp(vmu->imapserver, "imapserver")) { 11930 ast_test_status_update(test, "Parse failure for imapserver option\n"); 11931 res = 1; 11932 } 11933 if (strcasecmp(vmu->imapport, "1234")) { 11934 ast_test_status_update(test, "Parse failure for imapport option\n"); 11935 res = 1; 11936 } 11937 if (strcasecmp(vmu->imapflags, "flagged")) { 11938 ast_test_status_update(test, "Parse failure for imapflags option\n"); 11939 res = 1; 11940 } 11941 #endif 11942 11943 free_user(vmu); 11944 return res ? AST_TEST_FAIL : AST_TEST_PASS; 11945 }
| 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 4603 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, BASEMAXINLINE, ENDL, errno, inchar(), baseio::iocp, and ochar().
04604 { 04605 static const unsigned char dtable[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 04606 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 04607 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 04608 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; 04609 int i, hiteof = 0; 04610 FILE *fi; 04611 struct baseio bio; 04612 04613 memset(&bio, 0, sizeof(bio)); 04614 bio.iocp = BASEMAXINLINE; 04615 04616 if (!(fi = fopen(filename, "rb"))) { 04617 ast_log(AST_LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 04618 return -1; 04619 } 04620 04621 while (!hiteof){ 04622 unsigned char igroup[3], ogroup[4]; 04623 int c, n; 04624 04625 memset(igroup, 0, sizeof(igroup)); 04626 04627 for (n = 0; n < 3; n++) { 04628 if ((c = inchar(&bio, fi)) == EOF) { 04629 hiteof = 1; 04630 break; 04631 } 04632 04633 igroup[n] = (unsigned char) c; 04634 } 04635 04636 if (n > 0) { 04637 ogroup[0]= dtable[igroup[0] >> 2]; 04638 ogroup[1]= dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 04639 ogroup[2]= dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 04640 ogroup[3]= dtable[igroup[2] & 0x3F]; 04641 04642 if (n < 3) { 04643 ogroup[3] = '='; 04644 04645 if (n < 2) 04646 ogroup[2] = '='; 04647 } 04648 04649 for (i = 0; i < 4; i++) 04650 ochar(&bio, ogroup[i], so); 04651 } 04652 } 04653 04654 fclose(fi); 04655 04656 if (fputs(ENDL, so) == EOF) { 04657 return 0; 04658 } 04659 04660 return 1; 04661 }
| 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 1479 of file app_voicemail.c.
References ast_copy_string(), ast_realtime_require_field(), ast_test_suite_event_notify, ast_update2_realtime(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, RQ_CHAR, and SENTINEL.
Referenced by vm_change_password().
01480 { 01481 int res = -1; 01482 if (!strcmp(vmu->password, password)) { 01483 /* No change (but an update would return 0 rows updated, so we opt out here) */ 01484 return 0; 01485 } 01486 01487 if (strlen(password) > 10) { 01488 ast_realtime_require_field("voicemail", "password", RQ_CHAR, strlen(password), SENTINEL); 01489 } 01490 if (ast_update2_realtime("voicemail", "context", vmu->context, "mailbox", vmu->mailbox, SENTINEL, "password", password, SENTINEL) > 0) { 01491 ast_test_suite_event_notify("PASSWORDCHANGED", "Message: realtime engine updated with new password\r\nPasswordSource: realtime"); 01492 ast_copy_string(vmu->password, password, sizeof(vmu->password)); 01493 res = 0; 01494 } 01495 return res; 01496 }
| 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 4770 of file app_voicemail.c.
04771 { 04772 for (; *str; str++) { 04773 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 04774 return 1; 04775 } 04776 } 04777 return 0; 04778 }
| 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 1438 of file app_voicemail.c.
References ast_debug, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, ast_strlen_zero(), ast_vm_user::context, ast_vm_user::mailbox, ast_vm_user::password, and vm_check_password_shell().
Referenced by network_thread(), vm_newuser(), and vm_options().
01439 { 01440 /* check minimum length */ 01441 if (strlen(password) < minpassword) 01442 return 1; 01443 /* check that password does not contain '*' character */ 01444 if (!ast_strlen_zero(password) && password[0] == '*') 01445 return 1; 01446 if (!ast_strlen_zero(ext_pass_check_cmd)) { 01447 char cmd[255], buf[255]; 01448 01449 ast_debug(1, "Verify password policies for %s\n", password); 01450 01451 snprintf(cmd, sizeof(cmd), "%s %s %s %s %s", ext_pass_check_cmd, vmu->mailbox, vmu->context, vmu->password, password); 01452 if (vm_check_password_shell(cmd, buf, sizeof(buf))) { 01453 ast_debug(5, "Result: %s\n", buf); 01454 if (!strncasecmp(buf, "VALID", 5)) { 01455 ast_debug(3, "Passed password check: '%s'\n", buf); 01456 return 0; 01457 } else if (!strncasecmp(buf, "FAILURE", 7)) { 01458 ast_log(AST_LOG_WARNING, "Unable to execute password validation script: '%s'.\n", buf); 01459 return 0; 01460 } else { 01461 ast_log(AST_LOG_NOTICE, "Password doesn't match policies for user %s %s\n", vmu->mailbox, password); 01462 return 1; 01463 } 01464 } 01465 } 01466 return 0; 01467 }
| static int close_mailbox | ( | struct vm_state * | vms, | |
| struct ast_vm_user * | vmu | |||
| ) | [static] |
Definition at line 8712 of file app_voicemail.c.
References ast_check_realtime(), ast_debug, ast_free, ast_log(), AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_unlock_path(), ast_vm_user::context, vm_state::curbox, vm_state::curdir, vm_state::curmsg, DELETE, vm_state::deleted, vm_state::dh_arraysize, ERROR_LOCK_PATH, EXISTS, vm_state::fn, vm_state::heard, last_message_index(), vm_state::lastmsg, ast_vm_user::mailbox, make_file(), ast_vm_user::maxdeletedmsg, RENAME, save_to_folder(), vm_lock_path(), and VM_MOVEHEARD.
Referenced by play_message_by_id(), vm_execmain(), vm_mailbox_snapshot_create(), vm_msg_forward(), vm_msg_move(), vm_msg_play(), and vm_msg_remove().
08713 { 08714 int x = 0; 08715 int last_msg_idx = 0; 08716 08717 #ifndef IMAP_STORAGE 08718 int res = 0, nummsg; 08719 char fn2[PATH_MAX]; 08720 #endif 08721 08722 if (vms->lastmsg <= -1) { 08723 goto done; 08724 } 08725 08726 vms->curmsg = -1; 08727 #ifndef IMAP_STORAGE 08728 /* Get the deleted messages fixed */ 08729 if (vm_lock_path(vms->curdir)) { 08730 return ERROR_LOCK_PATH; 08731 } 08732 08733 /* update count as message may have arrived while we've got mailbox open */ 08734 last_msg_idx = last_message_index(vmu, vms->curdir); 08735 if (last_msg_idx != vms->lastmsg) { 08736 ast_log(AST_LOG_NOTICE, "%d messages received after mailbox opened.\n", last_msg_idx - vms->lastmsg); 08737 } 08738 08739 /* must check up to last detected message, just in case it is erroneously greater than maxmsg */ 08740 for (x = 0; x < last_msg_idx + 1; x++) { 08741 if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 08742 /* Save this message. It's not in INBOX or hasn't been heard */ 08743 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08744 if (!EXISTS(vms->curdir, x, vms->fn, NULL)) { 08745 break; 08746 } 08747 vms->curmsg++; 08748 make_file(fn2, sizeof(fn2), vms->curdir, vms->curmsg); 08749 if (strcmp(vms->fn, fn2)) { 08750 RENAME(vms->curdir, x, vmu->mailbox, vmu->context, vms->curdir, vms->curmsg, vms->fn, fn2); 08751 } 08752 } else if ((!strcasecmp(vms->curbox, "INBOX") || !strcasecmp(vms->curbox, "Urgent")) && vms->heard[x] && ast_test_flag(vmu, VM_MOVEHEARD) && !vms->deleted[x]) { 08753 /* Move to old folder before deleting */ 08754 res = save_to_folder(vmu, vms, x, 1, NULL, 0); 08755 if (res == ERROR_LOCK_PATH) { 08756 /* If save failed do not delete the message */ 08757 ast_log(AST_LOG_WARNING, "Save failed. Not moving message: %s.\n", res == ERROR_LOCK_PATH ? "unable to lock path" : "destination folder full"); 08758 vms->deleted[x] = 0; 08759 vms->heard[x] = 0; 08760 --x; 08761 } 08762 } else if (vms->deleted[x] && vmu->maxdeletedmsg) { 08763 /* Move to deleted folder */ 08764 res = save_to_folder(vmu, vms, x, 10, NULL, 0); 08765 if (res == ERROR_LOCK_PATH) { 08766 /* If save failed do not delete the message */ 08767 vms->deleted[x] = 0; 08768 vms->heard[x] = 0; 08769 --x; 08770 } 08771 } else if (vms->deleted[x] && ast_check_realtime("voicemail_data")) { 08772 /* If realtime storage enabled - we should explicitly delete this message, 08773 cause RENAME() will overwrite files, but will keep duplicate records in RT-storage */ 08774 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08775 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08776 DELETE(vms->curdir, x, vms->fn, vmu); 08777 } 08778 } 08779 } 08780 08781 /* Delete ALL remaining messages */ 08782 nummsg = x - 1; 08783 for (x = vms->curmsg + 1; x <= nummsg; x++) { 08784 make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 08785 if (EXISTS(vms->curdir, x, vms->fn, NULL)) { 08786 DELETE(vms->curdir, x, vms->fn, vmu); 08787 } 08788 } 08789 ast_unlock_path(vms->curdir); 08790 #else /* defined(IMAP_STORAGE) */ 08791 ast_mutex_lock(&vms->lock); 08792 if (vms->deleted) { 08793 /* Since we now expunge after each delete, deleting in reverse order 08794 * ensures that no reordering occurs between each step. */ 08795 last_msg_idx = vms->dh_arraysize; 08796 for (x = last_msg_idx - 1; x >= 0; x--) { 08797 if (vms->deleted[x]) { 08798 ast_debug(3, "IMAP delete of %d\n", x); 08799 DELETE(vms->curdir, x, vms->fn, vmu); 08800 } 08801 } 08802 } 08803 #endif 08804 08805 done: 08806 if (vms->deleted) { 08807 ast_free(vms->deleted); 08808 vms->deleted = NULL; 08809 } 08810 if (vms->heard) { 08811 ast_free(vms->heard); 08812 vms->heard = NULL; 08813 } 08814 vms->dh_arraysize = 0; 08815 #ifdef IMAP_STORAGE 08816 ast_mutex_unlock(&vms->lock); 08817 #endif 08818 08819 return 0; 08820 }
| static char* complete_voicemail_show_users | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 12176 of file app_voicemail.c.
References AST_LIST_TRAVERSE, ast_strdup, and ast_vm_user::context.
Referenced by handle_voicemail_show_users().
12177 { 12178 int which = 0; 12179 int wordlen; 12180 struct ast_vm_user *vmu; 12181 const char *context = ""; 12182 12183 /* 0 - show; 1 - voicemail; 2 - users; 3 - for; 4 - <context> */ 12184 if (pos > 4) 12185 return NULL; 12186 if (pos == 3) 12187 return (state == 0) ? ast_strdup("for") : NULL; 12188 wordlen = strlen(word); 12189 AST_LIST_TRAVERSE(&users, vmu, list) { 12190 if (!strncasecmp(word, vmu->context, wordlen)) { 12191 if (context && strcmp(context, vmu->context) && ++which > state) 12192 return ast_strdup(vmu->context); 12193 /* ignore repeated contexts ? */ 12194 context = vmu->context; 12195 } 12196 } 12197 return NULL; 12198 }
| 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 4408 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, errno, and VOICEMAIL_FILE_MODE.
Referenced by ast_func_read(), ast_func_read2(), ast_func_write(), config_hook_exec(), copy_plain_file(), filehelper(), iax2_register(), parse_hint_device(), parse_hint_presence(), and vm_forwardoptions().
04409 { 04410 int ifd; 04411 int ofd; 04412 int res; 04413 int len; 04414 char buf[4096]; 04415 04416 #ifdef HARDLINK_WHEN_POSSIBLE 04417 /* Hard link if possible; saves disk space & is faster */ 04418 if (link(infile, outfile)) { 04419 #endif 04420 if ((ifd = open(infile, O_RDONLY)) < 0) { 04421 ast_log(AST_LOG_WARNING, "Unable to open %s in read-only mode: %s\n", infile, strerror(errno)); 04422 return -1; 04423 } 04424 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, VOICEMAIL_FILE_MODE)) < 0) { 04425 ast_log(AST_LOG_WARNING, "Unable to open %s in write-only mode: %s\n", outfile, strerror(errno)); 04426 close(ifd); 04427 return -1; 04428 } 04429 do { 04430 len = read(ifd, buf, sizeof(buf)); 04431 if (len < 0) { 04432 ast_log(AST_LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 04433 close(ifd); 04434 close(ofd); 04435 unlink(outfile); 04436 } else if (len) { 04437 res = write(ofd, buf, len); 04438 if (errno == ENOMEM || errno == ENOSPC || res != len) { 04439 ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 04440 close(ifd); 04441 close(ofd); 04442 unlink(outfile); 04443 } 04444 } 04445 } while (len); 04446 close(ifd); 04447 close(ofd); 04448 return 0; 04449 #ifdef HARDLINK_WHEN_POSSIBLE 04450 } else { 04451 /* Hard link succeeded */ 04452 return 0; 04453 } 04454 #endif 04455 }
| 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, | |||
| const char * | dest_folder | |||
| ) | [static] |
Copies a message from one mailbox to another.
| chan | ||
| vmu | ||
| imbox | ||
| msgnum | ||
| duration | ||
| recip | ||
| fmt | ||
| dir | ||
| flag,dest_folder | This is only used by file storage based mailboxes. |
Definition at line 5681 of file app_voicemail.c.
References ast_channel_caller(), ast_channel_language(), ast_copy_string(), ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, ast_strlen_zero(), ast_unlock_path(), ast_vm_user::context, COPY, copy_plain_file(), create_dirpath(), ERROR_LOCK_PATH, EXISTS, ast_party_caller::id, inprocess_count(), last_message_index(), ast_vm_user::mailbox, make_dir(), make_file(), mbox(), ast_party_id::name, notify_new_message(), ast_party_id::number, S_COR, STORE, ast_party_name::str, ast_party_number::str, ast_party_name::valid, ast_party_number::valid, vm_delete(), and vm_lock_path().
Referenced by forward_message(), leave_voicemail(), and vm_msg_forward().
05682 { 05683 char fromdir[PATH_MAX], todir[PATH_MAX], frompath[PATH_MAX], topath[PATH_MAX]; 05684 const char *frombox = mbox(vmu, imbox); 05685 const char *userfolder; 05686 int recipmsgnum; 05687 int res = 0; 05688 05689 ast_log(AST_LOG_NOTICE, "Copying message from %s@%s to %s@%s\n", vmu->mailbox, vmu->context, recip->mailbox, recip->context); 05690 05691 if (!ast_strlen_zero(flag) && !strcmp(flag, "Urgent")) { /* If urgent, copy to Urgent folder */ 05692 userfolder = "Urgent"; 05693 } else if (!ast_strlen_zero(dest_folder)) { 05694 userfolder = dest_folder; 05695 } else { 05696 userfolder = "INBOX"; 05697 } 05698 05699 create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05700 05701 if (!dir) 05702 make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox); 05703 else 05704 ast_copy_string(fromdir, dir, sizeof(fromdir)); 05705 05706 make_file(frompath, sizeof(frompath), fromdir, msgnum); 05707 make_dir(todir, sizeof(todir), recip->context, recip->mailbox, userfolder); 05708 05709 if (vm_lock_path(todir)) 05710 return ERROR_LOCK_PATH; 05711 05712 recipmsgnum = last_message_index(recip, todir) + 1; 05713 if (recipmsgnum < recip->maxmsg - (imbox ? 0 : inprocess_count(vmu->mailbox, vmu->context, 0))) { 05714 make_file(topath, sizeof(topath), todir, recipmsgnum); 05715 #ifndef ODBC_STORAGE 05716 if (EXISTS(fromdir, msgnum, frompath, chan ? ast_channel_language(chan) : "")) { 05717 COPY(fromdir, msgnum, todir, recipmsgnum, recip->mailbox, recip->context, frompath, topath); 05718 } else { 05719 #endif 05720 /* If we are prepending a message for ODBC, then the message already 05721 * exists in the database, but we want to force copying from the 05722 * filesystem (since only the FS contains the prepend). */ 05723 copy_plain_file(frompath, topath); 05724 STORE(todir, recip->mailbox, recip->context, recipmsgnum, chan, recip, fmt, duration, NULL, NULL, NULL); 05725 vm_delete(topath); 05726 #ifndef ODBC_STORAGE 05727 } 05728 #endif 05729 } else { 05730 ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context); 05731 res = -1; 05732 } 05733 ast_unlock_path(todir); 05734 if (chan) { 05735 struct ast_party_caller *caller = ast_channel_caller(chan); 05736 notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, 05737 S_COR(caller->id.number.valid, caller->id.number.str, NULL), 05738 S_COR(caller->id.name.valid, caller->id.name.str, NULL), 05739 flag); 05740 } 05741 05742 return res; 05743 }
| static void copy_plain_file | ( | char * | frompath, | |
| char * | topath | |||
| ) | [static] |
Copies a voicemail information (envelope) file.
| frompath | ||
| topath |
Definition at line 4466 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().
04467 { 04468 char frompath2[PATH_MAX], topath2[PATH_MAX]; 04469 struct ast_variable *tmp,*var = NULL; 04470 const char *origmailbox = NULL, *context = NULL, *macrocontext = NULL, *exten = NULL, *priority = NULL, *callerchan = NULL, *callerid = NULL, *origdate = NULL, *origtime = NULL, *category = NULL, *duration = NULL; 04471 ast_filecopy(frompath, topath, NULL); 04472 snprintf(frompath2, sizeof(frompath2), "%s.txt", frompath); 04473 snprintf(topath2, sizeof(topath2), "%s.txt", topath); 04474 if (ast_check_realtime("voicemail_data")) { 04475 var = ast_load_realtime("voicemail_data", "filename", frompath, SENTINEL); 04476 /* This cycle converts ast_variable linked list, to va_list list of arguments, may be there is a better way to do it? */ 04477 for (tmp = var; tmp; tmp = tmp->next) { 04478 if (!strcasecmp(tmp->name, "origmailbox")) { 04479 origmailbox = tmp->value; 04480 } else if (!strcasecmp(tmp->name, "context")) { 04481 context = tmp->value; 04482 } else if (!strcasecmp(tmp->name, "macrocontext")) { 04483 macrocontext = tmp->value; 04484 } else if (!strcasecmp(tmp->name, "exten")) { 04485 exten = tmp->value; 04486 } else if (!strcasecmp(tmp->name, "priority")) { 04487 priority = tmp->value; 04488 } else if (!strcasecmp(tmp->name, "callerchan")) { 04489 callerchan = tmp->value; 04490 } else if (!strcasecmp(tmp->name, "callerid")) { 04491 callerid = tmp->value; 04492 } else if (!strcasecmp(tmp->name, "origdate")) { 04493 origdate = tmp->value; 04494 } else if (!strcasecmp(tmp->name, "origtime")) { 04495 origtime = tmp->value; 04496 } else if (!strcasecmp(tmp->name, "category")) { 04497 category = tmp->value; 04498 } else if (!strcasecmp(tmp->name, "duration")) { 04499 duration = tmp->value; 04500 } 04501 } 04502 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); 04503 } 04504 copy(frompath2, topath2); 04505 ast_variables_destroy(var); 04506 }
| 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 4303 of file app_voicemail.c.
References ast_unlock_path(), ERROR_LOCK_PATH, and vm_lock_path().
Referenced by leave_voicemail(), manager_list_voicemail_users(), msg_create_from_file(), and open_mailbox().
04304 { 04305 04306 int vmcount = 0; 04307 DIR *vmdir = NULL; 04308 struct dirent *vment = NULL; 04309 04310 if (vm_lock_path(dir)) 04311 return ERROR_LOCK_PATH; 04312 04313 if ((vmdir = opendir(dir))) { 04314 while ((vment = readdir(vmdir))) { 04315 if (strlen(vment->d_name) > 7 && !strncmp(vment->d_name + 7, ".txt", 4)) { 04316 vmcount++; 04317 } 04318 } 04319 closedir(vmdir); 04320 } 04321 ast_unlock_path(dir); 04322 04323 return vmcount; 04324 }
| 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 1899 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_mkdir(), make_dir(), and VOICEMAIL_DIR_MODE.
01900 { 01901 mode_t mode = VOICEMAIL_DIR_MODE; 01902 int res; 01903 01904 make_dir(dest, len, context, ext, folder); 01905 if ((res = ast_mkdir(dest, mode))) { 01906 ast_log(AST_LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01907 return -1; 01908 } 01909 return 0; 01910 }
| static int dialout | ( | struct ast_channel * | chan, | |
| struct ast_vm_user * | vmu, | |||
| char * | num, | |||
| char * | outgoing_context | |||
| ) | [static] |
Definition at line 14360 of file app_voicemail.c.
References ast_channel_context(), ast_channel_context_set(), ast_channel_exten_set(), ast_channel_priority_set(), ast_copy_string(), ast_play_and_wait(), ast_readstring(), ast_strlen_zero(), ast_test_suite_event_notify, ast_verb, and ast_waitfordigit().
Referenced by advanced_options(), and vm_execmain().
14361 { 14362 int cmd = 0; 14363 char destination[80] = ""; 14364 int retries = 0; 14365 14366 if (!num) { 14367 ast_verb(3, "Destination number will be entered manually\n"); 14368 while (retries < 3 && cmd != 't') { 14369 destination[1] = '\0'; 14370 destination[0] = cmd = ast_play_and_wait(chan, "vm-enter-num-to-call"); 14371 if (!cmd) 14372 destination[0] = cmd = ast_play_and_wait(chan, "vm-then-pound"); 14373 if (!cmd) 14374 destination[0] = cmd = ast_play_and_wait(chan, "vm-star-cancel"); 14375 if (!cmd) { 14376 cmd = ast_waitfordigit(chan, 6000); 14377 if (cmd) 14378 destination[0] = cmd; 14379 } 14380 if (!cmd) { 14381 retries++; 14382 } else { 14383 14384 if (cmd < 0) 14385 return 0; 14386 if (cmd == '*') { 14387 ast_verb(3, "User hit '*' to cancel outgoing call\n"); 14388 return 0; 14389 } 14390 if ((cmd = ast_readstring(chan, destination + strlen(destination), sizeof(destination) - 1, 6000, 10000, "#")) < 0) 14391 retries++; 14392 else 14393 cmd = 't'; 14394 } 14395 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 14396 } 14397 if (retries >= 3) { 14398 return 0; 14399 } 14400 14401 } else { 14402 ast_verb(3, "Destination number is CID number '%s'\n", num); 14403 ast_copy_string(destination, num, sizeof(destination)); 14404 } 14405 14406 if (!ast_strlen_zero(destination)) { 14407 if (destination[strlen(destination) -1 ] == '*') 14408 return 0; 14409 ast_verb(3, "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", destination, outgoing_context, ast_channel_context(chan)); 14410 ast_channel_exten_set(chan, destination); 14411 ast_channel_context_set(chan, outgoing_context); 14412 ast_channel_priority_set(chan, 0); 14413 return 9; 14414 } 14415 return 0; 14416 }
| static struct ast_vm_user* find_or_create | ( | const char * | context, | |
| const char * | box | |||
| ) | [static, read] |
Definition at line 11662 of file app_voicemail.c.
References ast_calloc, ast_copy_string(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_strlen_zero(), ast_test_flag, ast_vm_user::context, globalflags, LOG_WARNING, ast_vm_user::mailbox, and VM_SEARCH.
Referenced by actual_load_config(), and append_mailbox().
11663 { 11664 struct ast_vm_user *vmu; 11665 11666 if (!ast_strlen_zero(box) && box[0] == '*') { 11667 ast_log(LOG_WARNING, "Mailbox %s in context %s begins with '*' character. The '*' character," 11668 "\n\twhen it is the first character in a mailbox or password, is used to jump to a" 11669 "\n\tpredefined extension 'a'. A mailbox or password beginning with '*' is not valid" 11670 "\n\tand will be ignored.\n", box, context); 11671 return NULL; 11672 } 11673 11674 AST_LIST_TRAVERSE(&users, vmu, list) { 11675 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(box, vmu->mailbox)) { 11676 if (strcasecmp(vmu->context, context)) { 11677 ast_log(LOG_WARNING, "\nIt has been detected that you have defined mailbox '%s' in separate\ 11678 \n\tcontexts and that you have the 'searchcontexts' option on. This type of\ 11679 \n\tconfiguration creates an ambiguity that you likely do not want. Please\ 11680 \n\tamend your voicemail.conf file to avoid this situation.\n", box); 11681 } 11682 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s\n", box); 11683 return NULL; 11684 } 11685 if (!strcasecmp(context, vmu->context) && !strcasecmp(box, vmu->mailbox)) { 11686 ast_log(LOG_WARNING, "Ignoring duplicated mailbox %s in context %s\n", box, context); 11687 return NULL; 11688 } 11689 } 11690 11691 if (!(vmu = ast_calloc(1, sizeof(*vmu)))) 11692 return NULL; 11693 11694 ast_copy_string(vmu->context, context, sizeof(vmu->context)); 11695 ast_copy_string(vmu->mailbox, box, sizeof(vmu->mailbox)); 11696 11697 AST_LIST_INSERT_TAIL(&users, vmu, list); 11698 11699 return vmu; 11700 }
| 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 1651 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_malloc, ast_set2_flag, ast_strdup, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, find_user_realtime(), globalflags, VM_ALLOCED, and VM_SEARCH.
01652 { 01653 /* This function could be made to generate one from a database, too */ 01654 struct ast_vm_user *vmu = NULL, *cur; 01655 AST_LIST_LOCK(&users); 01656 01657 if (!context && !ast_test_flag((&globalflags), VM_SEARCH)) 01658 context = "default"; 01659 01660 AST_LIST_TRAVERSE(&users, cur, list) { 01661 #ifdef IMAP_STORAGE 01662 if (cur->imapversion != imapversion) { 01663 continue; 01664 } 01665 #endif 01666 if (ast_test_flag((&globalflags), VM_SEARCH) && !strcasecmp(mailbox, cur->mailbox)) 01667 break; 01668 if (context && (!strcasecmp(context, cur->context)) && (!strcasecmp(mailbox, cur->mailbox))) 01669 break; 01670 } 01671 if (cur) { 01672 /* Make a copy, so that on a reload, we have no race */ 01673 if ((vmu = (ivm ? ivm : ast_malloc(sizeof(*vmu))))) { 01674 *vmu = *cur; 01675 if (!ivm) { 01676 vmu->emailbody = ast_strdup(cur->emailbody); 01677 vmu->emailsubject = ast_strdup(cur->emailsubject); 01678 } 01679 ast_set2_flag(vmu, !ivm, VM_ALLOCED); 01680 AST_LIST_NEXT(vmu, list) = NULL; 01681 } 01682 } else 01683 vmu = find_user_realtime(ivm, context, mailbox); 01684 AST_LIST_UNLOCK(&users); 01685 return vmu; 01686 }
| 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 1610 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.
01611 { 01612 struct ast_variable *var; 01613 struct ast_vm_user *retval; 01614 01615 if ((retval = (ivm ? ivm : ast_calloc(1, sizeof(*retval))))) { 01616 if (ivm) { 01617 memset(retval, 0, sizeof(*retval)); 01618 } 01619 populate_defaults(retval); 01620 if (!ivm) { 01621 ast_set_flag(retval, VM_ALLOCED); 01622 } 01623 if (mailbox) { 01624 ast_copy_string(retval->mailbox, mailbox, sizeof(retval->mailbox)); 01625 } 01626 if (!context && ast_test_flag((&globalflags), VM_SEARCH)) { 01627 var = ast_load_realtime("voicemail", "mailbox", mailbox, SENTINEL); 01628 } else { 01629 var = ast_load_realtime("voicemail", "mailbox", mailbox, "context", context, SENTINEL); 01630 } 01631 if (var) { 01632 apply_options_full(retval, var); 01633 ast_variables_destroy(var); 01634 } else { 01635 if (!ivm) 01636 ast_free(retval); 01637 retval = NULL; 01638 } 01639 } 01640 return retval; 01641 }
| static int forward_message | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| struct vm_state * | vms, | |||
| struct ast_vm_user * | sender, | |||
| char * | fmt, | |||
| int | is_new_message, | |||
| signed char | record_gain, | |||
| int | urgent | |||
| ) | [static] |
Sends a voicemail message to a mailbox recipient.
| chan | ||
| context | ||
| vms | ||
| sender | ||
| fmt | ||
| is_new_message | Used to indicate the mode for which this method was invoked. Will be 0 when called to forward an existing message (option 8) Will be 1 when called to leave a message (option 3->5) | |
| record_gain | ||
| urgent | Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory. |
When in the forward message mode (is_new_message == 0):
Definition at line 7885 of file app_voicemail.c.
References ast_channel_caller(), ast_channel_context(), ast_channel_context_set(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_language(), ast_channel_priority(), ast_channel_priority_set(), ast_clear_flag, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_fileexists(), ast_filerename(), AST_LIST_EMPTY, AST_LIST_HEAD_NOLOCK_STATIC, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_LOG_ERROR, AST_LOG_WARNING, AST_MAX_EXTENSION, ast_play_and_wait(), ast_readstring(), ast_say_digit_str(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_test_suite_event_notify, ast_variable_retrieve(), ast_waitfordigit(), CONFIG_FLAG_NOCACHE, CONFIG_STATUS_FILEINVALID, ast_vm_user::context, copy_message(), vm_state::curbox, vm_state::curdir, vm_state::curmsg, DISPOSE, find_user(), vm_state::fn, free_user(), globalflags, inboxcount(), inprocess_count(), leave_voicemail(), LOG_ERROR, LOG_NOTICE, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, pbx_exec(), pbx_findapp(), leave_vm_options::record_gain, RETRIEVE, run_externnotify(), S_COR, S_OR, sendmail(), STORE, strsep(), vm_state::username, VM_ATTACH, VM_DIRECFORWARD, vm_forwardoptions(), and VM_FWDURGAUTO.
Referenced by vm_execmain().
07886 { 07887 #ifdef IMAP_STORAGE 07888 int todircount = 0; 07889 struct vm_state *dstvms; 07890 #endif 07891 char username[70]=""; 07892 char fn[PATH_MAX]; /* for playback of name greeting */ 07893 char ecodes[16] = "#"; 07894 int res = 0, cmd = 0; 07895 struct ast_vm_user *receiver = NULL, *vmtmp; 07896 AST_LIST_HEAD_NOLOCK_STATIC(extensions, ast_vm_user); 07897 char *stringp; 07898 const char *s; 07899 int saved_messages = 0; 07900 int valid_extensions = 0; 07901 char *dir; 07902 int curmsg; 07903 char urgent_str[7] = ""; 07904 int prompt_played = 0; 07905 #ifndef IMAP_STORAGE 07906 char msgfile[PATH_MAX], textfile[PATH_MAX], backup[PATH_MAX], backup_textfile[PATH_MAX]; 07907 #endif 07908 if (ast_test_flag((&globalflags), VM_FWDURGAUTO)) { 07909 ast_copy_string(urgent_str, urgent ? "Urgent" : "", sizeof(urgent_str)); 07910 } 07911 07912 if (vms == NULL) return -1; 07913 dir = vms->curdir; 07914 curmsg = vms->curmsg; 07915 07916 ast_test_suite_event_notify("FORWARD", "Message: entering forward message menu"); 07917 while (!res && !valid_extensions) { 07918 int use_directory = 0; 07919 if (ast_test_flag((&globalflags), VM_DIRECFORWARD)) { 07920 int done = 0; 07921 int retries = 0; 07922 cmd = 0; 07923 while ((cmd >= 0) && !done ){ 07924 if (cmd) 07925 retries = 0; 07926 switch (cmd) { 07927 case '1': 07928 use_directory = 0; 07929 done = 1; 07930 break; 07931 case '2': 07932 use_directory = 1; 07933 done = 1; 07934 break; 07935 case '*': 07936 cmd = 't'; 07937 done = 1; 07938 break; 07939 default: 07940 /* Press 1 to enter an extension press 2 to use the directory */ 07941 cmd = ast_play_and_wait(chan, "vm-forward"); 07942 if (!cmd) { 07943 cmd = ast_waitfordigit(chan, 3000); 07944 } 07945 if (!cmd) { 07946 retries++; 07947 } 07948 if (retries > 3) { 07949 cmd = 't'; 07950 done = 1; 07951 } 07952 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", cmd, cmd); 07953 } 07954 } 07955 if (cmd < 0 || cmd == 't') 07956 break; 07957 } 07958 07959 if (use_directory) { 07960 /* use app_directory */ 07961 07962 struct ast_app* directory_app; 07963 07964 directory_app = pbx_findapp("Directory"); 07965 if (directory_app) { 07966 char vmcontext[256]; 07967 char *old_context; 07968 char *old_exten; 07969 int old_priority; 07970 /* make backup copies */ 07971 old_context = ast_strdupa(ast_channel_context(chan)); 07972 old_exten = ast_strdupa(ast_channel_exten(chan)); 07973 old_priority = ast_channel_priority(chan); 07974 07975 /* call the the Directory, changes the channel */ 07976 snprintf(vmcontext, sizeof(vmcontext), "%s,,v", context ? context : "default"); 07977 res = pbx_exec(chan, directory_app, vmcontext); 07978 07979 ast_copy_string(username, ast_channel_exten(chan), sizeof(username)); 07980 07981 /* restore the old context, exten, and priority */ 07982 ast_channel_context_set(chan, old_context); 07983 ast_channel_exten_set(chan, old_exten); 07984 ast_channel_priority_set(chan, old_priority); 07985 } else { 07986 ast_log(AST_LOG_WARNING, "Could not find the Directory application, disabling directory_forward\n"); 07987 ast_clear_flag((&globalflags), VM_DIRECFORWARD); 07988 } 07989 } else { 07990 /* Ask for an extension */ 07991 ast_test_suite_event_notify("PLAYBACK", "Message: vm-extension"); 07992 res = ast_streamfile(chan, "vm-extension", ast_channel_language(chan)); /* "extension" */ 07993 prompt_played++; 07994 if (res || prompt_played > 4) 07995 break; 07996 if ((res = ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#")) < 0) 07997 break; 07998 } 07999 08000 /* start all over if no username */ 08001 if (ast_strlen_zero(username)) 08002 continue; 08003 stringp = username; 08004 s = strsep(&stringp, "*"); 08005 /* start optimistic */ 08006 valid_extensions = 1; 08007 while (s) { 08008 if ((is_new_message == 1 || strcmp(s, sender->mailbox)) && (receiver = find_user(NULL, context, s))) { 08009 int oldmsgs; 08010 int newmsgs; 08011 int capacity; 08012 if (inboxcount(s, &newmsgs, &oldmsgs)) { 08013 ast_log(LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", s); 08014 /* Shouldn't happen, but allow trying another extension if it does */ 08015 res = ast_play_and_wait(chan, "pbx-invalid"); 08016 valid_extensions = 0; 08017 break; 08018 } 08019 capacity = receiver->maxmsg - inprocess_count(receiver->mailbox, receiver->context, +1); 08020 if ((newmsgs + oldmsgs) >= capacity) { 08021 ast_log(LOG_NOTICE, "Mailbox '%s' is full with capacity of %d, prompting for another extension.\n", s, capacity); 08022 res = ast_play_and_wait(chan, "vm-mailboxfull"); 08023 valid_extensions = 0; 08024 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 08025 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 08026 free_user(vmtmp); 08027 } 08028 inprocess_count(receiver->mailbox, receiver->context, -1); 08029 break; 08030 } 08031 AST_LIST_INSERT_HEAD(&extensions, receiver, list); 08032 } else { 08033 /* XXX Optimization for the future. When we encounter a single bad extension, 08034 * bailing out on all of the extensions may not be the way to go. We should 08035 * probably just bail on that single extension, then allow the user to enter 08036 * several more. XXX 08037 */ 08038 while ((receiver = AST_LIST_REMOVE_HEAD(&extensions, list))) { 08039 free_user(receiver); 08040 } 08041 ast_log(LOG_NOTICE, "'%s' is not a valid mailbox\n", s); 08042 /* "I am sorry, that's not a valid extension. Please try again." */ 08043 res = ast_play_and_wait(chan, "pbx-invalid"); 08044 valid_extensions = 0; 08045 break; 08046 } 08047 08048 /* play name if available, else play extension number */ 08049 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, receiver->context, s); 08050 RETRIEVE(fn, -1, s, receiver->context); 08051 if (ast_fileexists(fn, NULL, NULL) > 0) { 08052 res = ast_stream_and_wait(chan, fn, ecodes); 08053 if (res) { 08054 DISPOSE(fn, -1); 08055 return res; 08056 } 08057 } else { 08058 res = ast_say_digit_str(chan, s, ecodes, ast_channel_language(chan)); 08059 } 08060 DISPOSE(fn, -1); 08061 08062 s = strsep(&stringp, "*"); 08063 } 08064 /* break from the loop of reading the extensions */ 08065 if (valid_extensions) 08066 break; 08067 } 08068 /* check if we're clear to proceed */ 08069 if (AST_LIST_EMPTY(&extensions) || !valid_extensions) 08070 return res; 08071 if (is_new_message == 1) { 08072 struct leave_vm_options leave_options; 08073 char mailbox[AST_MAX_EXTENSION * 2 + 2]; 08074 snprintf(mailbox, sizeof(mailbox), "%s@%s", username, context); 08075 08076 /* Send VoiceMail */ 08077 memset(&leave_options, 0, sizeof(leave_options)); 08078 leave_options.record_gain = record_gain; 08079 cmd = leave_voicemail(chan, mailbox, &leave_options); 08080 } else { 08081 /* Forward VoiceMail */ 08082 long duration = 0; 08083 struct vm_state vmstmp; 08084 int copy_msg_result = 0; 08085 #ifdef IMAP_STORAGE 08086 char filename[PATH_MAX]; 08087 struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE }; 08088 const char *msg_id = NULL; 08089 struct ast_config *msg_cfg; 08090 #endif 08091 memcpy(&vmstmp, vms, sizeof(vmstmp)); 08092 08093 RETRIEVE(dir, curmsg, sender->mailbox, sender->context); 08094 #ifdef IMAP_STORAGE 08095 make_file(filename, sizeof(filename), dir, curmsg); 08096 strncat(filename, ".txt", sizeof(filename) - strlen(filename) - 1); 08097 msg_cfg = ast_config_load(filename, config_flags); 08098 if (msg_cfg && msg_cfg == CONFIG_STATUS_FILEINVALID) { 08099 msg_id = ast_strdupa(ast_variable_retrieve(msg_cfg, "message", "msg_id")); 08100 ast_config_destroy(msg_cfg); 08101 } 08102 #endif 08103 08104 cmd = vm_forwardoptions(chan, sender, vmstmp.curdir, curmsg, vmfmts, S_OR(context, "default"), record_gain, &duration, &vmstmp, urgent_str); 08105 if (!cmd) { 08106 AST_LIST_TRAVERSE_SAFE_BEGIN(&extensions, vmtmp, list) { 08107 #ifdef IMAP_STORAGE 08108 int attach_user_voicemail; 08109 char *myserveremail = serveremail; 08110 08111 /* get destination mailbox */ 08112 dstvms = get_vm_state_by_mailbox(vmtmp->mailbox, vmtmp->context, 0); 08113 if (!dstvms) { 08114 dstvms = create_vm_state_from_user(vmtmp); 08115 } 08116 if (dstvms) { 08117 init_mailstream(dstvms, 0); 08118 if (!dstvms->mailstream) { 08119 ast_log(AST_LOG_ERROR, "IMAP mailstream for %s is NULL\n", vmtmp->mailbox); 08120 } else { 08121 copy_msg_result = STORE(vmstmp.curdir, vmtmp->mailbox, vmtmp->context, dstvms->curmsg, chan, vmtmp, fmt, duration, dstvms, urgent_str, msg_id); 08122 run_externnotify(vmtmp->context, vmtmp->mailbox, urgent_str); 08123 } 08124 } else { 08125 ast_log(AST_LOG_ERROR, "Could not find state information for mailbox %s\n", vmtmp->mailbox); 08126 } 08127 if (!ast_strlen_zero(vmtmp->serveremail)) 08128 myserveremail = vmtmp->serveremail; 08129 attach_user_voicemail = ast_test_flag(vmtmp, VM_ATTACH); 08130 /* NULL category for IMAP storage */ 08131 sendmail(myserveremail, vmtmp, todircount, vmtmp->context, vmtmp->mailbox, 08132 dstvms->curbox, 08133 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL), 08134 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL), 08135 vmstmp.fn, vmstmp.introfn, fmt, duration, attach_user_voicemail, chan, 08136 NULL, urgent_str, msg_id); 08137 #else 08138 copy_msg_result = copy_message(chan, sender, 0, curmsg, duration, vmtmp, fmt, dir, urgent_str, NULL); 08139 #endif 08140 saved_messages++; 08141 AST_LIST_REMOVE_CURRENT(list); 08142 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 08143 free_user(vmtmp); 08144 if (res) 08145 break; 08146 } 08147 AST_LIST_TRAVERSE_SAFE_END; 08148 if (saved_messages > 0 && !copy_msg_result) { 08149 /* give confirmation that the message was saved */ 08150 /* commented out since we can't forward batches yet 08151 if (saved_messages == 1) 08152 res = ast_play_and_wait(chan, "vm-message"); 08153 else 08154 res = ast_play_and_wait(chan, "vm-messages"); 08155 if (!res) 08156 res = ast_play_and_wait(chan, "vm-saved"); */ 08157 #ifdef IMAP_STORAGE 08158 /* If forwarded with intro, DON'T PLAY THIS MESSAGE AGAIN! */ 08159 if (ast_strlen_zero(vmstmp.introfn)) 08160 #endif 08161 res = ast_play_and_wait(chan, "vm-msgsaved"); 08162 } 08163 #ifndef IMAP_STORAGE 08164 else { 08165 /* with IMAP, mailbox full warning played by imap_check_limits */ 08166 res = ast_play_and_wait(chan, "vm-mailboxfull"); 08167 } 08168 /* Restore original message without prepended message if backup exists */ 08169 make_file(msgfile, sizeof(msgfile), dir, curmsg); 08170 strcpy(textfile, msgfile); 08171 strcpy(backup, msgfile); 08172 strcpy(backup_textfile, msgfile); 08173 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 08174 strncat(backup, "-bak", sizeof(backup) - strlen(backup) - 1); 08175 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 08176 if (ast_fileexists(backup, NULL, NULL) > 0) { 08177 ast_filerename(backup, msgfile, NULL); 08178 rename(backup_textfile, textfile); 08179 } 08180 #endif 08181 } 08182 DISPOSE(dir, curmsg); 08183 #ifndef IMAP_STORAGE 08184 if (cmd) { /* assuming hangup, cleanup backup file */ 08185 make_file(msgfile, sizeof(msgfile), dir, curmsg); 08186 strcpy(textfile, msgfile); 08187 strcpy(backup_textfile, msgfile); 08188 strncat(textfile, ".txt", sizeof(textfile) - strlen(textfile) - 1); 08189 strncat(backup_textfile, "-bak.txt", sizeof(backup_textfile) - strlen(backup_textfile) - 1); 08190 rename(backup_textfile, textfile); 08191 } 08192 #endif 08193 } 08194 08195 /* If anything failed above, we still have this list to free */ 08196 while ((vmtmp = AST_LIST_REMOVE_HEAD(&extensions, list))) { 08197 inprocess_count(vmtmp->mailbox, vmtmp->context, -1); 08198 free_user(vmtmp); 08199 } 08200 return res ? res : cmd; 08201 }
| static void free_user | ( | struct ast_vm_user * | vmu | ) | [static] |
Definition at line 1941 of file app_voicemail.c.
References ast_free, ast_test_flag, ast_vm_user::emailbody, ast_vm_user::emailsubject, and VM_ALLOCED.
01942 { 01943 if (ast_test_flag(vmu, VM_ALLOCED)) { 01944 01945 ast_free(vmu->emailbody); 01946 vmu->emailbody = NULL; 01947 01948 ast_free(vmu->emailsubject); 01949 vmu->emailsubject = NULL; 01950 01951 ast_free(vmu); 01952 } 01953 }
| static void free_vm_users | ( | void | ) | [static] |
Free the users structure.
Definition at line 12831 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 actual_load_config(), and unload_module().
12832 { 12833 struct ast_vm_user *current; 12834 AST_LIST_LOCK(&users); 12835 while ((current = AST_LIST_REMOVE_HEAD(&users, list))) { 12836 ast_set_flag(current, VM_ALLOCED); 12837 free_user(current); 12838 } 12839 AST_LIST_UNLOCK(&users); 12840 }
| static void free_vm_zones | ( | void | ) | [static] |
Free the zones structure.
Definition at line 12843 of file app_voicemail.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and free_zone().
Referenced by actual_load_config(), and unload_module().
12844 { 12845 struct vm_zone *zcur; 12846 AST_LIST_LOCK(&zones); 12847 while ((zcur = AST_LIST_REMOVE_HEAD(&zones, list))) 12848 free_zone(zcur); 12849 AST_LIST_UNLOCK(&zones); 12850 }
| static void free_zone | ( | struct vm_zone * | z | ) | [static] |
Definition at line 5445 of file app_voicemail.c.
References ast_free.
05446 { 05447 ast_free(z); 05448 }
| static void generate_random_string | ( | char * | buf, | |
| size_t | size | |||
| ) | [static] |
Definition at line 11623 of file app_voicemail.c.
References ast_random().
Referenced by add_message_id(), ast_rtp_new(), build_callid_pvt(), build_callid_registry(), calendar_query_exec(), construct_pidf_body(), do_notify(), and generate_uri().
11624 { 11625 long val[4]; 11626 int x; 11627 11628 for (x=0; x<4; x++) 11629 val[x] = ast_random(); 11630 snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]); 11631 }
| 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 5401 of file app_voicemail.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
05402 { 05403 struct ast_tm tm; 05404 struct timeval t = ast_tvnow(); 05405 05406 ast_localtime(&t, &tm, "UTC"); 05407 05408 return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm); 05409 }
| 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 7453 of file app_voicemail.c.
References ast_channel_language(), AST_DIGIT_ANY, ast_fileexists(), ast_play_and_wait(), ast_say_number(), ast_test_suite_event_notify, ast_verb, ast_waitfordigit(), mbox(), and vm_play_folder_name().
Referenced by get_folder2().
07454 { 07455 int x; 07456 int d; 07457 char fn[PATH_MAX]; 07458 d = ast_play_and_wait(chan, "vm-press"); /* "Press" */ 07459 if (d) 07460 return d; 07461 for (x = start; x < 5; x++) { /* For all folders */ 07462 if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, ast_channel_language(chan), NULL))) 07463 return d; 07464 d = ast_play_and_wait(chan, "vm-for"); /* "for" */ 07465 if (d) 07466 return d; 07467 snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */ 07468 07469 /* The inbox folder can have its name changed under certain conditions 07470 * so this checks if the sound file exists for the inbox folder name and 07471 * if it doesn't, plays the default name instead. */ 07472 if (x == 0) { 07473 if (ast_fileexists(fn, NULL, NULL)) { 07474 d = vm_play_folder_name(chan, fn); 07475 } else { 07476 ast_verb(1, "failed to find %s\n", fn); 07477 d = vm_play_folder_name(chan, "vm-INBOX"); 07478 } 07479 } else { 07480 ast_test_suite_event_notify("PLAYBACK", "Message: folder name %s", fn); 07481 d = vm_play_folder_name(chan, fn); 07482 } 07483 07484 if (d) 07485 return d; 07486 d = ast_waitfordigit(chan, 500); 07487 if (d) 07488 return d; 07489 } 07490 07491 d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */ 07492 if (d) 07493 return d; 07494 d = ast_waitfordigit(chan, 4000); 07495 return d; 07496 }
| 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 7510 of file app_voicemail.c.
References ast_play_and_wait(), ast_test_suite_event_notify, and get_folder().
Referenced by vm_execmain().
07511 { 07512 int res = 0; 07513 int loops = 0; 07514 07515 res = ast_play_and_wait(chan, fn); /* Folder name */ 07516 while (((res < '0') || (res > '9')) && 07517 (res != '#') && (res >= 0) && 07518 loops < 4) { 07519 res = get_folder(chan, 0); 07520 loops++; 07521 } 07522 if (loops == 4) { /* give up */ 07523 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", '#', '#'); 07524 return '#'; 07525 } 07526 ast_test_suite_event_notify("USERPRESS", "Message: User pressed %c\r\nDTMF: %c", res, res); 07527 return res; 07528 }
| static int get_folder_by_name | ( | const char * | name | ) | [static] |
Definition at line 1928 of file app_voicemail.c.
References ARRAY_LEN.
Referenced by vm_execmain(), vm_msg_forward(), vm_msg_move(), vm_msg_play(), and vm_msg_remove().
01929 { 01930 size_t i; 01931 01932 for (i = 0; i < ARRAY_LEN(mailbox_folders); i++) { 01933 if (strcasecmp(name, mailbox_folders[i]) == 0) { 01934 return i; 01935 } 01936 } 01937 01938 return -1; 01939 }
| static int handle_subscribe | ( | void * | datap | ) | [static] |
Definition at line 12558 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().
12559 { 12560 unsigned int len; 12561 struct mwi_sub *mwi_sub; 12562 struct mwi_sub_task *p = datap; 12563 12564 len = sizeof(*mwi_sub); 12565 if (!ast_strlen_zero(p->mailbox)) 12566 len += strlen(p->mailbox); 12567 12568 if (!ast_strlen_zero(p->context)) 12569 len += strlen(p->context) + 1; /* Allow for seperator */ 12570 12571 if (!(mwi_sub = ast_calloc(1, len))) 12572 return -1; 12573 12574 mwi_sub->uniqueid = p->uniqueid; 12575 if (!ast_strlen_zero(p->mailbox)) 12576 strcpy(mwi_sub->mailbox, p->mailbox); 12577 12578 if (!ast_strlen_zero(p->context)) { 12579 strcat(mwi_sub->mailbox, "@"); 12580 strcat(mwi_sub->mailbox, p->context); 12581 } 12582 12583 AST_RWLIST_WRLOCK(&mwi_subs); 12584 AST_RWLIST_INSERT_TAIL(&mwi_subs, mwi_sub, entry); 12585 AST_RWLIST_UNLOCK(&mwi_subs); 12586 ast_free((void *) p->mailbox); 12587 ast_free((void *) p->context); 12588 ast_free(p); 12589 poll_subscribed_mailbox(mwi_sub); 12590 return 0; 12591 }
| static int handle_unsubscribe | ( | void * | datap | ) | [static] |
Definition at line 12536 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().
12537 { 12538 struct mwi_sub *mwi_sub; 12539 uint32_t *uniqueid = datap; 12540 12541 AST_RWLIST_WRLOCK(&mwi_subs); 12542 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&mwi_subs, mwi_sub, entry) { 12543 if (mwi_sub->uniqueid == *uniqueid) { 12544 AST_LIST_REMOVE_CURRENT(entry); 12545 break; 12546 } 12547 } 12548 AST_RWLIST_TRAVERSE_SAFE_END 12549 AST_RWLIST_UNLOCK(&mwi_subs); 12550 12551 if (mwi_sub) 12552 mwi_sub_destroy(mwi_sub); 12553 12554 ast_free(uniqueid); 12555 return 0; 12556 }
| 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 12313 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.
12314 { 12315 switch (cmd) { 12316 case CLI_INIT: 12317 e->command = "voicemail reload"; 12318 e->usage = 12319 "Usage: voicemail reload\n" 12320 " Reload voicemail configuration\n"; 12321 return NULL; 12322 case CLI_GENERATE: 12323 return NULL; 12324 } 12325 12326 if (a->argc != 2) 12327 return CLI_SHOWUSAGE; 12328 12329 ast_cli(a->fd, "Reloading voicemail configuration...\n"); 12330 load_config(1); 12331 12332 return CLI_SUCCESS; 12333 }
| 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 12201 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.
12202 { 12203 struct ast_vm_user *vmu; 12204 #define HVSU_OUTPUT_FORMAT "%-10s %-5s %-25s %-10s %6s\n" 12205 const char *context = NULL; 12206 int users_counter = 0; 12207 12208 switch (cmd) { 12209 case CLI_INIT: 12210 e->command = "voicemail show users"; 12211 e->usage = 12212 "Usage: voicemail show users [for <context>]\n" 12213 " Lists all mailboxes currently set up\n"; 12214 return NULL; 12215 case CLI_GENERATE: 12216 return complete_voicemail_show_users(a->line, a->word, a->pos, a->n); 12217 } 12218 12219 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 12220 return CLI_SHOWUSAGE; 12221 if (a->argc == 5) { 12222 if (strcmp(a->argv[3],"for")) 12223 return CLI_SHOWUSAGE; 12224 context = a->argv[4]; 12225 } 12226 12227 if (ast_check_realtime("voicemail")) { 12228 if (!context) { 12229 ast_cli(a->fd, "You must specify a specific context to show users from realtime!\n"); 12230 return CLI_SHOWUSAGE; 12231 } 12232 return show_users_realtime(a->fd, context); 12233 } 12234 12235 AST_LIST_LOCK(&users); 12236 if (AST_LIST_EMPTY(&users)) { 12237 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 12238 AST_LIST_UNLOCK(&users); 12239 return CLI_FAILURE; 12240 } 12241 if (!context) { 12242 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 12243 } else { 12244 int count = 0; 12245 AST_LIST_TRAVERSE(&users, vmu, list) { 12246 if (!strcmp(context, vmu->context)) { 12247 count++; 12248 break; 12249 } 12250 } 12251 if (count) { 12252 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, "Context", "Mbox", "User", "Zone", "NewMsg"); 12253 } else { 12254 ast_cli(a->fd, "No such voicemail context \"%s\"\n", context); 12255 AST_LIST_UNLOCK(&users); 12256 return CLI_FAILURE; 12257 } 12258 } 12259 AST_LIST_TRAVERSE(&users, vmu, list) { 12260 int newmsgs = 0, oldmsgs = 0; 12261 char count[12], tmp[256] = ""; 12262 12263 if (!context || !strcmp(context, vmu->context)) { 12264 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->mailbox, ast_strlen_zero(vmu->context) ? "default" : vmu->context); 12265 inboxcount(tmp, &newmsgs, &oldmsgs); 12266 snprintf(count, sizeof(count), "%d", newmsgs); 12267 ast_cli(a->fd, HVSU_OUTPUT_FORMAT, vmu->context, vmu->mailbox, vmu->fullname, vmu->zonetag, count); 12268 users_counter++; 12269 } 12270 } 12271 AST_LIST_UNLOCK(&users); 12272 ast_cli(a->fd, "%d voicemail users configured.\n", users_counter); 12273 return CLI_SUCCESS; 12274 }
| 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 12277 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.
12278 { 12279 struct vm_zone *zone; 12280 #define HVSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 12281 char *res = CLI_SUCCESS; 12282 12283 switch (cmd) { 12284 case CLI_INIT: 12285 e->command = "voicemail show zones"; 12286 e->usage = 12287 "Usage: voicemail show zones\n" 12288 " Lists zone message formats\n"; 12289 return NULL; 12290 case CLI_GENERATE: 12291 return NULL; 12292 } 12293 12294 if (a->argc != 3) 12295 return CLI_SHOWUSAGE; 12296 12297 AST_LIST_LOCK(&zones); 12298 if (!AST_LIST_EMPTY(&zones)) { 12299 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 12300 AST_LIST_TRAVERSE(&zones, zone, list) { 12301 ast_cli(a->fd, HVSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 12302 } 12303 } else { 12304 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 12305 res = CLI_FAILURE; 12306 } 12307 AST_LIST_UNLOCK(&zones); 12308 12309 return res; 12310 }
| static int has_voicemail | ( | const char * | mailbox, | |
| const char * | folder | |||
| ) | [static] |
Determines if the given folder has messages.
| mailbox | The @ delimited string for user@context. If no context is found, uses 'default' for the context. | |
| folder | the folder to look in |
Definition at line 5798 of file app_voicemail.c.
References __has_voicemail(), ast_copy_string(), ast_strlen_zero(), 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().
05799 { 05800 char tmp[256], *tmp2 = tmp, *box, *context; 05801 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05802 if (ast_strlen_zero(folder)) { 05803 folder = "INBOX"; 05804 } 05805 while ((box = strsep(&tmp2, ",&"))) { 05806 if ((context = strchr(box, '@'))) 05807 *context++ = '\0'; 05808 else 05809 context = "default"; 05810 if (__has_voicemail(context, box, folder, 1)) 05811 return 1; 05812 /* If we are checking INBOX, we should check Urgent as well */ 05813 if (!strcmp(folder, "INBOX") && __has_voicemail(context, box, "Urgent", 1)) { 05814 return 1; 05815 } 05816 } 05817 return 0; 05818 }
| static int inboxcount | ( | const char * | mailbox, | |
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5880 of file app_voicemail.c.
References inboxcount2().
Referenced by forward_message(), handle_voicemail_show_users(), leave_voicemail(), load_module(), manager_list_voicemail_users(), and msg_create_from_file().
05881 { 05882 int urgentmsgs = 0; 05883 int res = inboxcount2(mailbox, &urgentmsgs, newmsgs, oldmsgs); 05884 if (newmsgs) { 05885 *newmsgs += urgentmsgs; 05886 } 05887 return res; 05888 }
| static int inboxcount2 | ( | const char * | mailbox, | |
| int * | urgentmsgs, | |||
| int * | newmsgs, | |||
| int * | oldmsgs | |||
| ) | [static] |
Definition at line 5821 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(), run_externnotify(), and vm_users_data_provider_get_helper().
05822 { 05823 char tmp[256]; 05824 char *context; 05825 05826 /* If no mailbox, return immediately */ 05827 if (ast_strlen_zero(mailbox)) 05828 return 0; 05829 05830 if (newmsgs) 05831 *newmsgs = 0; 05832 if (oldmsgs) 05833 *oldmsgs = 0; 05834 if (urgentmsgs) 05835 *urgentmsgs = 0; 05836 05837 if (strchr(mailbox, ',')) { 05838 int tmpnew, tmpold, tmpurgent; 05839 char *mb, *cur; 05840 05841 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05842 mb = tmp; 05843 while ((cur = strsep(&mb, ", "))) { 05844 if (!ast_strlen_zero(cur)) { 05845 if (inboxcount2(cur, urgentmsgs ? &tmpurgent : NULL, newmsgs ? &tmpnew : NULL, oldmsgs ? &tmpold : NULL)) 05846 return -1; 05847 else { 05848 if (newmsgs) 05849 *newmsgs += tmpnew; 05850 if (oldmsgs) 05851 *oldmsgs += tmpold; 05852 if (urgentmsgs) 05853 *urgentmsgs += tmpurgent; 05854 } 05855 } 05856 } 05857 return 0; 05858 } 05859 05860 ast_copy_string(tmp, mailbox, sizeof(tmp)); 05861 05862 if ((context = strchr(tmp, '@'))) 05863 *context++ = '\0'; 05864 else 05865 context = "default"; 05866 05867 if (newmsgs) 05868 *newmsgs = __has_voicemail(context, tmp, "INBOX", 0); 05869 if (oldmsgs) 05870 *oldmsgs = __has_voicemail(context, tmp, "Old", 0); 05871 if (urgentmsgs) 05872 *urgentmsgs = __has_voicemail(context, tmp, "Urgent", 0); 05873 05874 return 0; 05875 }
| static int inbuf | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by inchar(), for base_encode()
Definition at line 4538 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(), netconsole(), sip_addheader(), and sip_removeheader().
04539 { 04540 int l; 04541 04542 if (bio->ateof) 04543 return 0; 04544 04545 if ((l = fread(bio->iobuf, 1, BASEMAXINLINE, fi)) <= 0) { 04546 if (ferror(fi)) 04547 return -1; 04548 04549 bio->ateof = 1; 04550 return 0; 04551 } 04552 04553 bio->iolen = l; 04554 bio->iocp = 0; 04555 04556 return 1; 04557 }
| static int inchar | ( | struct baseio * | bio, | |
| FILE * | fi | |||
| ) | [static] |
utility used by base_encode()
Definition at line 4562 of file app_voicemail.c.
References inbuf(), baseio::iobuf, baseio::iocp, and baseio::iolen.
Referenced by base_encode().
04563 { 04564 if (bio->iocp>=bio->iolen) { 04565 if (!inbuf(bio, fi)) 04566 return EOF; 04567 } 04568 04569 return bio->iobuf[bio->iocp++]; 04570 }
| static int inprocess_cmp_fn | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1124 of file app_voicemail.c.
References CMP_MATCH, inprocess::context, and inprocess::mailbox.
Referenced by load_module().
01125 { 01126 struct inprocess *i = obj, *j = arg; 01127 if (strcmp(i->mailbox, j->mailbox)) { 01128 return 0; 01129 } 01130 return !strcmp(i->context, j->context) ? CMP_MATCH : 0; 01131 }
| static int inprocess_count | ( | const char * | context, | |
| const char * | mailbox, | |||
| int | delta | |||
| ) | [static] |
Definition at line 1133 of file app_voicemail.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_alloca, ast_atomic_fetchadd_int(), ast_log(), inprocess::context, inprocess::count, inprocess_container, LOG_WARNING, and inprocess::mailbox.
Referenced by copy_message(), forward_message(), leave_voicemail(), and msg_create_from_file().
01134 { 01135 struct inprocess *i, *arg = ast_alloca(sizeof(*arg) + strlen(context) + strlen(mailbox) + 2); 01136 arg->context = arg->mailbox + strlen(mailbox) + 1; 01137 strcpy(arg->mailbox, mailbox); /* SAFE */ 01138 strcpy(arg->context, context); /* SAFE */ 01139 ao2_lock(inprocess_container); 01140 if ((i = ao2_find(inprocess_container, arg, 0))) { 01141 int ret = ast_atomic_fetchadd_int(&i->count, delta); 01142 ao2_unlock(inprocess_container); 01143 ao2_ref(i, -1); 01144 return ret; 01145 } 01146 if (delta < 0) { 01147 ast_log(LOG_WARNING, "BUG: ref count decrement on non-existing object???\n"); 01148 } 01149 if (!(i = ao2_alloc(sizeof(*i) + strlen(context) + strlen(mailbox) + 2, NULL))) { 01150 ao2_unlock(inprocess_container); 01151 return 0; 01152 } 01153 i->context = i->mailbox + strlen(mailbox) + 1; 01154 strcpy(i->mailbox, mailbox); /* SAFE */ 01155 strcpy(i->context, context); /* SAFE */ 01156 i->count = delta; 01157 ao2_link(inprocess_container, i); 01158 ao2_unlock(inprocess_container); 01159 ao2_ref(i, -1); 01160 return 0; 01161 }
| static int inprocess_hash_fn | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1118 of file app_voicemail.c.
References inprocess::mailbox.
Referenced by load_module().
| static int invent_message | ( | struct ast_channel * | chan, | |
| char * | context, | |||
| char * | ext, | |||
| int | busy, | |||
| char * | ecodes | |||
| ) | [static] |
Definition at line 5411 of file app_voicemail.c.
References ast_channel_language(), ast_fileexists(), ast_log(), AST_LOG_WARNING, ast_say_digit_str(), ast_stream_and_wait(), create_dirpath(), DISPOSE, and RETRIEVE.
05412 { 05413 int res; 05414 char fn[PATH_MAX]; 05415 char dest[PATH_MAX]; 05416 05417 snprintf(fn, sizeof(fn), "%s%s/%s/greet", VM_SPOOL_DIR, context, ext); 05418 05419 if ((res = create_dirpath(dest, sizeof(dest), context, ext, ""))) { 05420 ast_log(AST_LOG_WARNING, "Failed to make directory(%s)\n", fn); 05421 return -1; 05422 } 05423 05424 RETRIEVE(fn, -1, ext, context); 05425 if (ast_fileexists(fn, NULL, NULL) > 0) { 05426 res = ast_stream_and_wait(chan, fn, ecodes); 05427 if (res) { 05428 DISPOSE(fn, -1); 05429 return res; 05430 } 05431 } else { 05432 /* Dispose just in case */ 05433 DISPOSE(fn, -1); 05434 res = ast_stream_and_wait(chan, "vm-theperson", ecodes); 05435 if (res) 05436 return res; 05437 res = ast_say_digit_str(chan, ext, ecodes, ast_channel_language(chan)); 05438 if (res) 05439 return res; 05440 } 05441 res = ast_stream_and_wait(chan, busy ? "vm-isonphone" : "vm-isunavail", ecodes); 05442 return res; 05443 }
| 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 1585 of file app_voicemail.c.
References ast_log(), AST_LOG_WARNING, ast_strdupa, and VALID_DTMF.
Referenced by actual_load_config().
01586 { 01587 int i; 01588 char *local_key = ast_strdupa(key); 01589 01590 for (i = 0; i < strlen(key); ++i) { 01591 if (!strchr(VALID_DTMF, *local_key)) { 01592 ast_log(AST_LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key); 01593 return 0; 01594 } 01595 local_key++; 01596 } 01597 return 1; 01598 }
| 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 4357 of file app_voicemail.c.
References ast_debug, map, ast_vm_user::maxmsg, and MAXMSGLIMIT.
Referenced by close_mailbox(), copy_message(), leave_voicemail(), msg_create_from_file(), open_mailbox(), and save_to_folder().
04358 { 04359 int x; 04360 unsigned char map[MAXMSGLIMIT] = ""; 04361 DIR *msgdir; 04362 struct dirent *msgdirent; 04363 int msgdirint; 04364 char extension[4]; 04365 int stopcount = 0; 04366 04367 /* Reading the entire directory into a file map scales better than 04368 * doing a stat repeatedly on a predicted sequence. I suspect this 04369 * is partially due to stat(2) internally doing a readdir(2) itself to 04370 * find each file. */ 04371 if (!(msgdir = opendir(dir))) { 04372 return -1; 04373 } 04374 04375 while ((msgdirent = readdir(msgdir))) { 04376 if (sscanf(msgdirent->d_name, "msg%30d.%3s", &msgdirint, extension) == 2 && !strcmp(extension, "txt") && msgdirint < MAXMSGLIMIT) { 04377 map[msgdirint] = 1; 04378 stopcount++; 04379 ast_debug(4, "%s map[%d] = %d, count = %d\n", dir, msgdirint, map[msgdirint], stopcount); 04380 } 04381 } 04382 closedir(msgdir); 04383 04384 for (x = 0; x < vmu->maxmsg; x++) { 04385 if (map[x] == 1) { 04386 stopcount--; 04387 } else if (map[x] == 0 && !stopcount) { 04388 break; 04389 } 04390 } 04391 04392 return x - 1; 04393 }
| 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 6248 of file app_voicemail.c.
References ast_callerid_merge(), ast_canmatch_extension(), ast_channel_caller(), ast_channel_context(), ast_channel_context_set(), ast_channel_exten(), ast_channel_exten_set(), ast_channel_language(), ast_channel_lock, ast_channel_macrocontext(), ast_channel_name(), ast_channel_priority(), ast_channel_priority_set(), ast_channel_redirecting(), ast_channel_unlock, ast_check_realtime(), ast_copy_string(), ast_debug, ast_destroy_realtime(), ast_exists_extension(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), AST_LOG_ERROR, AST_LOG_NOTICE, AST_LOG_WARNING, ast_mutex_lock, ast_mutex_unlock, ast_play_and_wait(), ast_set_flag, ast_stopstream(), ast_store_realtime(), ast_str_buffer(), ast_str_create(), ast_str_hash(), ast_str_set(), ast_strdupa, ast_stream_and_wait(), ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_unlock_path(), ast_update_realtime(), ast_verb, ast_waitstream(), ast_vm_user::context, copy_message(), count_messages(), create_dirpath(), DISPOSE, errno, ast_vm_user::exit, leave_vm_options::exitcontext, exten, find_user(), free_user(), get_date(), inboxcount(), inprocess_count(), INTRO, invent_message(), last_message_index(), LOG_WARNING, ast_vm_user::mailbox, make_file(), ast_vm_user::maxmsg, ast_vm_user::maxsecs, ast_vm_user::minsecs, vm_state::newmessages, notify_new_message(), OPERATOR_EXIT, OPT_BUSY_GREETING, OPT_DTMFEXIT, OPT_MESSAGE_PRIORITY, OPT_MESSAGE_Urgent, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), play_record_review(), leave_vm_options::record_gain, RENAME, RETRIEVE, S_COR, S_OR, SENTINEL, STORE, strsep(), transfer, vm_lock_path(), VM_OPERATOR, VOICEMAIL_DIR_MODE, and VOICEMAIL_FILE_MODE.
06249 { 06250 #ifdef IMAP_STORAGE 06251 int newmsgs, oldmsgs; 06252 #else 06253 char urgdir[PATH_MAX]; 06254 #endif 06255 char txtfile[PATH_MAX]; 06256 char tmptxtfile[PATH_MAX]; 06257 struct vm_state *vms = NULL; 06258 char callerid[256]; 06259 FILE *txt; 06260 char date[256]; 06261 int txtdes; 06262 int res = 0; 06263 int msgnum; 06264 int duration = 0; 06265 int sound_duration = 0; 06266 int ausemacro = 0; 06267 int ousemacro = 0; 06268 int ouseexten = 0; 06269 char tmpdur[16]; 06270 char priority[16]; 06271 char origtime[16]; 06272 char dir[PATH_MAX]; 06273 char tmpdir[PATH_MAX]; 06274 char fn[PATH_MAX]; 06275 char prefile[PATH_MAX] = ""; 06276 char tempfile[PATH_MAX] = ""; 06277 char ext_context[256] = ""; 06278 char fmt[80]; 06279 char *context; 06280 char ecodes[17] = "#"; 06281 struct ast_str *tmp = ast_str_create(16); 06282 char *tmpptr; 06283 struct ast_vm_user *vmu; 06284 struct ast_vm_user svm; 06285 const char *category = NULL; 06286 const char *code; 06287 const char *alldtmf = "0123456789ABCD*#"; 06288 char flag[80]; 06289 06290 if (!tmp) { 06291 return -1; 06292 } 06293 06294 ast_str_set(&tmp, 0, "%s", ext); 06295 ext = ast_str_buffer(tmp); 06296 if ((context = strchr(ext, '@'))) { 06297 *context++ = '\0'; 06298 tmpptr = strchr(context, '&'); 06299 } else { 06300 tmpptr = strchr(ext, '&'); 06301 } 06302 06303 if (tmpptr) 06304 *tmpptr++ = '\0'; 06305 06306 ast_channel_lock(chan); 06307 if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) { 06308 category = ast_strdupa(category); 06309 } 06310 ast_channel_unlock(chan); 06311 06312 if (ast_test_flag(options, OPT_MESSAGE_Urgent)) { 06313 ast_copy_string(flag, "Urgent", sizeof(flag)); 06314 } else if (ast_test_flag(options, OPT_MESSAGE_PRIORITY)) { 06315 ast_copy_string(flag, "PRIORITY", sizeof(flag)); 06316 } else { 06317 flag[0] = '\0'; 06318 } 06319 06320 ast_debug(3, "Before find_user\n"); 06321 if (!(vmu = find_user(&svm, context, ext))) { 06322 ast_log(AST_LOG_WARNING, "No entry in voicemail config file for '%s'\n", ext); 06323 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06324 ast_free(tmp); 06325 return res; 06326 } 06327 /* Setup pre-file if appropriate */ 06328 if (strcmp(vmu->context, "default")) 06329 snprintf(ext_context, sizeof(ext_context), "%s@%s", ext, vmu->context); 06330 else 06331 ast_copy_string(ext_context, vmu->mailbox, sizeof(ext_context)); 06332 06333 /* Set the path to the prefile. Will be one of 06334 VM_SPOOL_DIRcontext/ext/busy 06335 VM_SPOOL_DIRcontext/ext/unavail 06336 Depending on the flag set in options. 06337 */ 06338 if (ast_test_flag(options, OPT_BUSY_GREETING)) { 06339 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", VM_SPOOL_DIR, vmu->context, ext); 06340 } else if (ast_test_flag(options, OPT_UNAVAIL_GREETING)) { 06341 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", VM_SPOOL_DIR, vmu->context, ext); 06342 } 06343 /* Set the path to the tmpfile as 06344 VM_SPOOL_DIR/context/ext/temp 06345 and attempt to create the folder structure. 06346 */ 06347 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", VM_SPOOL_DIR, vmu->context, ext); 06348 if ((res = create_dirpath(tmpdir, sizeof(tmpdir), vmu->context, ext, "tmp"))) { 06349 ast_log(AST_LOG_WARNING, "Failed to make directory (%s)\n", tempfile); 06350 ast_free(tmp); 06351 return -1; 06352 } 06353 RETRIEVE(tempfile, -1, vmu->mailbox, vmu->context); 06354 if (ast_fileexists(tempfile, NULL, NULL) > 0) 06355 ast_copy_string(prefile, tempfile, sizeof(prefile)); 06356 06357 DISPOSE(tempfile, -1); 06358 /* It's easier just to try to make it than to check for its existence */ 06359 #ifndef IMAP_STORAGE 06360 create_dirpath(dir, sizeof(dir), vmu->context, ext, "INBOX"); 06361 #else 06362 snprintf(dir, sizeof(dir), "%simap", VM_SPOOL_DIR); 06363 if (mkdir(dir, VOICEMAIL_DIR_MODE) && errno != EEXIST) { 06364 ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); 06365 } 06366 #endif 06367 06368 /* Check current or macro-calling context for special extensions */ 06369 if (ast_test_flag(vmu, VM_OPERATOR)) { 06370 if (!ast_strlen_zero(vmu->exit)) { 06371 if (ast_exists_extension(chan, vmu->exit, "o", 1, 06372 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06373 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 06374 ouseexten = 1; 06375 } 06376 } else if (ast_exists_extension(chan, ast_channel_context(chan), "o", 1, 06377 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06378 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 06379 ouseexten = 1; 06380 } else if (!ast_strlen_zero(ast_channel_macrocontext(chan)) 06381 && ast_exists_extension(chan, ast_channel_macrocontext(chan), "o", 1, 06382 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06383 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 06384 ousemacro = 1; 06385 } 06386 } 06387 06388 if (!ast_strlen_zero(vmu->exit)) { 06389 if (ast_exists_extension(chan, vmu->exit, "a", 1, 06390 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06391 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 06392 } 06393 } else if (ast_exists_extension(chan, ast_channel_context(chan), "a", 1, 06394 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06395 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 06396 } else if (!ast_strlen_zero(ast_channel_macrocontext(chan)) 06397 && ast_exists_extension(chan, ast_channel_macrocontext(chan), "a", 1, 06398 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06399 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 06400 ausemacro = 1; 06401 } 06402 06403 if (ast_test_flag(options, OPT_DTMFEXIT)) { 06404 for (code = alldtmf; *code; code++) { 06405 char e[2] = ""; 06406 e[0] = *code; 06407 if (strchr(ecodes, e[0]) == NULL 06408 && ast_canmatch_extension(chan, 06409 (!ast_strlen_zero(options->exitcontext) ? options->exitcontext : ast_channel_context(chan)), 06410 e, 1, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))) { 06411 strncat(ecodes, e, sizeof(ecodes) - strlen(ecodes) - 1); 06412 } 06413 } 06414 } 06415 06416 /* Play the beginning intro if desired */ 06417 if (!ast_strlen_zero(prefile)) { 06418 #ifdef ODBC_STORAGE 06419 int success = 06420 #endif 06421 RETRIEVE(prefile, -1, ext, context); 06422 if (ast_fileexists(prefile, NULL, NULL) > 0) { 06423 if (ast_streamfile(chan, prefile, ast_channel_language(chan)) > -1) 06424 res = ast_waitstream(chan, ecodes); 06425 #ifdef ODBC_STORAGE 06426 if (success == -1) { 06427 /* We couldn't retrieve the file from the database, but we found it on the file system. Let's put it in the database. */ 06428 ast_debug(1, "Greeting not retrieved from database, but found in file storage. Inserting into database\n"); 06429 store_file(prefile, vmu->mailbox, vmu->context, -1); 06430 } 06431 #endif 06432 } else { 06433 ast_debug(1, "%s doesn't exist, doing what we can\n", prefile); 06434 res = invent_message(chan, vmu->context, ext, ast_test_flag(options, OPT_BUSY_GREETING), ecodes); 06435 } 06436 DISPOSE(prefile, -1); 06437 if (res < 0) { 06438 ast_debug(1, "Hang up during prefile playback\n"); 06439 free_user(vmu); 06440 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06441 ast_free(tmp); 06442 return -1; 06443 } 06444 } 06445 if (res == '#') { 06446 /* On a '#' we skip the instructions */ 06447 ast_set_flag(options, OPT_SILENT); 06448 res = 0; 06449 } 06450 /* If maxmsg is zero, act as a "greetings only" voicemail: Exit successfully without recording */ 06451 if (vmu->maxmsg == 0) { 06452 ast_debug(3, "Greetings only VM (maxmsg=0), Skipping voicemail recording\n"); 06453 pbx_builtin_setvar_helper(chan, "VMSTATUS", "SUCCESS"); 06454 goto leave_vm_out; 06455 } 06456 if (!res && !ast_test_flag(options, OPT_SILENT)) { 06457 res = ast_stream_and_wait(chan, INTRO, ecodes); 06458 if (res == '#') { 06459 ast_set_flag(options, OPT_SILENT); 06460 res = 0; 06461 } 06462 } 06463 if (res > 0) 06464 ast_stopstream(chan); 06465 /* Check for a '*' here in case the caller wants to escape from voicemail to something 06466 other than the operator -- an automated attendant or mailbox login for example */ 06467 if (res == '*') { 06468 ast_channel_exten_set(chan, "a"); 06469 if (!ast_strlen_zero(vmu->exit)) { 06470 ast_channel_context_set(chan, vmu->exit); 06471 } else if (ausemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) { 06472 ast_channel_context_set(chan, ast_channel_macrocontext(chan)); 06473 } 06474 ast_channel_priority_set(chan, 0); 06475 free_user(vmu); 06476 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 06477 ast_free(tmp); 06478 return 0; 06479 } 06480 06481 /* Check for a '0' here */ 06482 if (ast_test_flag(vmu, VM_OPERATOR) && res == '0') { 06483 transfer: 06484 if (ouseexten || ousemacro) { 06485 ast_channel_exten_set(chan, "o"); 06486 if (!ast_strlen_zero(vmu->exit)) { 06487 ast_channel_context_set(chan, vmu->exit); 06488 } else if (ousemacro && !ast_strlen_zero(ast_channel_macrocontext(chan))) { 06489 ast_channel_context_set(chan, ast_channel_macrocontext(chan)); 06490 } 06491 ast_play_and_wait(chan, "transfer"); 06492 ast_channel_priority_set(chan, 0); 06493 free_user(vmu); 06494 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 06495 } 06496 ast_free(tmp); 06497 return OPERATOR_EXIT; 06498 } 06499 06500 /* Allow all other digits to exit Voicemail and return to the dialplan */ 06501 if (ast_test_flag(options, OPT_DTMFEXIT) && res > 0) { 06502 if (!ast_strlen_zero(options->exitcontext)) { 06503 ast_channel_context_set(chan, options->exitcontext); 06504 } 06505 free_user(vmu); 06506 ast_free(tmp); 06507 pbx_builtin_setvar_helper(chan, "VMSTATUS", "USEREXIT"); 06508 return res; 06509 } 06510 06511 if (res < 0) { 06512 free_user(vmu); 06513 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06514 ast_free(tmp); 06515 return -1; 06516 } 06517 /* The meat of recording the message... All the announcements and beeps have been played*/ 06518 ast_copy_string(fmt, vmfmts, sizeof(fmt)); 06519 if (!ast_strlen_zero(fmt)) { 06520 char msg_id[256] = ""; 06521 msgnum = 0; 06522 06523 #ifdef IMAP_STORAGE 06524 /* Is ext a mailbox? */ 06525 /* must open stream for this user to get info! */ 06526 res = inboxcount(ext_context, &newmsgs, &oldmsgs); 06527 if (res < 0) { 06528 ast_log(AST_LOG_NOTICE, "Can not leave voicemail, unable to count messages\n"); 06529 ast_free(tmp); 06530 return -1; 06531 } 06532 if (!(vms = get_vm_state_by_mailbox(ext, context, 0))) { 06533 /* It is possible under certain circumstances that inboxcount did not 06534 * create a vm_state when it was needed. This is a catchall which will 06535 * rarely be used. 06536 */ 06537 if (!(vms = create_vm_state_from_user(vmu))) { 06538 ast_log(AST_LOG_ERROR, "Couldn't allocate necessary space\n"); 06539 ast_free(tmp); 06540 return -1; 06541 } 06542 } 06543 vms->newmessages++; 06544 06545 /* here is a big difference! We add one to it later */ 06546 msgnum = newmsgs + oldmsgs; 06547 ast_debug(3, "Messagecount set to %d\n", msgnum); 06548 snprintf(fn, sizeof(fn), "%simap/msg%s%04d", VM_SPOOL_DIR, vmu->mailbox, msgnum); 06549 /* set variable for compatibility */ 06550 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06551 06552 if ((res = imap_check_limits(chan, vms, vmu, msgnum))) { 06553 goto leave_vm_out; 06554 } 06555 #else 06556 if (count_messages(vmu, dir) >= vmu->maxmsg - inprocess_count(vmu->mailbox, vmu->context, +1)) { 06557 res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan)); 06558 if (!res) 06559 res = ast_waitstream(chan, ""); 06560 ast_log(AST_LOG_WARNING, "No more messages possible\n"); 06561 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06562 inprocess_count(vmu->mailbox, vmu->context, -1); 06563 goto leave_vm_out; 06564 } 06565 06566 #endif 06567 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 06568 txtdes = mkstemp(tmptxtfile); 06569 chmod(tmptxtfile, VOICEMAIL_FILE_MODE & ~my_umask); 06570 if (txtdes < 0) { 06571 res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan)); 06572 if (!res) 06573 res = ast_waitstream(chan, ""); 06574 ast_log(AST_LOG_ERROR, "Unable to create message file: %s\n", strerror(errno)); 06575 pbx_builtin_setvar_helper(chan, "VMSTATUS", "FAILED"); 06576 inprocess_count(vmu->mailbox, vmu->context, -1); 06577 goto leave_vm_out; 06578 } 06579 06580 /* Now play the beep once we have the message number for our next message. */ 06581 if (res >= 0) { 06582 /* Unless we're *really* silent, try to send the beep */ 06583 res = ast_stream_and_wait(chan, "beep", ""); 06584 } 06585 06586 /* Store information in real-time storage */ 06587 if (ast_check_realtime("voicemail_data")) { 06588 snprintf(priority, sizeof(priority), "%d", ast_channel_priority(chan)); 06589 snprintf(origtime, sizeof(origtime), "%ld", (long) time(NULL)); 06590 get_date(date, sizeof(date)); 06591 ast_callerid_merge(callerid, sizeof(callerid), 06592 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL), 06593 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL), 06594 "Unknown"); 06595 ast_store_realtime("voicemail_data", 06596 "origmailbox", ext, 06597 "context", ast_channel_context(chan), 06598 "macrocontext", ast_channel_macrocontext(chan), 06599 "exten", ast_channel_exten(chan), 06600 "priority", priority, 06601 "callerchan", ast_channel_name(chan), 06602 "callerid", callerid, 06603 "origdate", date, 06604 "origtime", origtime, 06605 "category", S_OR(category, ""), 06606 "filename", tmptxtfile, 06607 SENTINEL); 06608 } 06609 06610 /* Store information */ 06611 txt = fdopen(txtdes, "w+"); 06612 if (txt) { 06613 char msg_id_hash[256] = ""; 06614 06615 /* Every voicemail msg gets its own unique msg id. The msg id is the originate time 06616 * plus a hash of the extension, context, and callerid of the channel leaving the msg */ 06617 snprintf(msg_id_hash, sizeof(msg_id_hash), "%s%s%s", ast_channel_exten(chan), ast_channel_context(chan), callerid); 06618 snprintf(msg_id, sizeof(msg_id), "%ld-%d", (long) time(NULL), ast_str_hash(msg_id_hash)); 06619 06620 get_date(date, sizeof(date)); 06621 ast_callerid_merge(callerid, sizeof(callerid), 06622 S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL), 06623 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL), 06624 "Unknown"); 06625 fprintf(txt, 06626 ";\n" 06627 "; Message Information file\n" 06628 ";\n" 06629 "[message]\n" 06630 "origmailbox=%s\n" 06631 "context=%s\n" 06632 "macrocontext=%s\n" 06633 "exten=%s\n" 06634 "rdnis=%s\n" 06635 "priority=%d\n" 06636 "callerchan=%s\n" 06637 "callerid=%s\n" 06638 "origdate=%s\n" 06639 "origtime=%ld\n" 06640 "category=%s\n" 06641 "msg_id=%s\n", 06642 ext, 06643 ast_channel_context(chan), 06644 ast_channel_macrocontext(chan), 06645 ast_channel_exten(chan), 06646 S_COR(ast_channel_redirecting(chan)->from.number.valid, 06647 ast_channel_redirecting(chan)->from.number.str, "unknown"), 06648 ast_channel_priority(chan), 06649 ast_channel_name(chan), 06650 callerid, 06651 date, (long) time(NULL), 06652 category ? category : "", 06653 msg_id); 06654 } else { 06655 ast_log(AST_LOG_WARNING, "Error opening text file for output\n"); 06656 inprocess_count(vmu->mailbox, vmu->context, -1); 06657 if (ast_check_realtime("voicemail_data")) { 06658 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06659 } 06660 res = ast_streamfile(chan, "vm-mailboxfull", ast_channel_language(chan)); 06661 goto leave_vm_out; 06662 } 06663 res = play_record_review(chan, NULL, tmptxtfile, vmu->maxsecs, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain, vms, flag, msg_id); 06664 06665 if (txt) { 06666 fprintf(txt, "flag=%s\n", flag); 06667 if (sound_duration < vmu->minsecs) { 06668 fclose(txt); 06669 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, vmu->minsecs); 06670 ast_filedelete(tmptxtfile, NULL); 06671 unlink(tmptxtfile); 06672 if (ast_check_realtime("voicemail_data")) { 06673 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06674 } 06675 inprocess_count(vmu->mailbox, vmu->context, -1); 06676 } else { 06677 fprintf(txt, "duration=%d\n", duration); 06678 fclose(txt); 06679 if (vm_lock_path(dir)) { 06680 ast_log(AST_LOG_ERROR, "Couldn't lock directory %s. Voicemail will be lost.\n", dir); 06681 /* Delete files */ 06682 ast_filedelete(tmptxtfile, NULL); 06683 unlink(tmptxtfile); 06684 inprocess_count(vmu->mailbox, vmu->context, -1); 06685 } else if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 06686 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 06687 unlink(tmptxtfile); 06688 ast_unlock_path(dir); 06689 inprocess_count(vmu->mailbox, vmu->context, -1); 06690 if (ast_check_realtime("voicemail_data")) { 06691 ast_destroy_realtime("voicemail_data", "filename", tmptxtfile, SENTINEL); 06692 } 06693 } else { 06694 #ifndef IMAP_STORAGE 06695 msgnum = last_message_index(vmu, dir) + 1; 06696 #endif 06697 make_file(fn, sizeof(fn), dir, msgnum); 06698 06699 /* assign a variable with the name of the voicemail file */ 06700 #ifndef IMAP_STORAGE 06701 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", fn); 06702 #else 06703 pbx_builtin_setvar_helper(chan, "VM_MESSAGEFILE", "IMAP_STORAGE"); 06704 #endif 06705 06706 snprintf(txtfile, sizeof(txtfile), "%s.txt", fn); 06707 ast_filerename(tmptxtfile, fn, NULL); 06708 rename(tmptxtfile, txtfile); 06709 inprocess_count(vmu->mailbox, vmu->context, -1); 06710 06711 /* Properly set permissions on voicemail text descriptor file. 06712 Unfortunately mkstemp() makes this file 0600 on most unix systems. */ 06713 if (chmod(txtfile, VOICEMAIL_FILE_MODE) < 0) 06714 ast_log(AST_LOG_ERROR, "Couldn't set permissions on voicemail text file %s: %s", txtfile, strerror(errno)); 06715 06716