00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdlib.h>
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #include <dirent.h>
00035 #include <sys/types.h>
00036
00037 #include "asterisk.h"
00038
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7608 $")
00040
00041 #include "asterisk/file.h"
00042 #include "asterisk/logger.h"
00043 #include "asterisk/channel.h"
00044 #include "asterisk/pbx.h"
00045 #include "asterisk/module.h"
00046 #include "asterisk/lock.h"
00047 #include "asterisk/utils.h"
00048 #include "asterisk/app.h"
00049 #include "asterisk/options.h"
00050
00051 static char *tdesc = "Indicator for whether a voice mailbox has messages in a given folder.";
00052 static char *app_hasvoicemail = "HasVoicemail";
00053 static char *hasvoicemail_synopsis = "Conditionally branches to priority + 101 with the right options set";
00054 static char *hasvoicemail_descrip =
00055 "HasVoicemail(vmbox[/folder][@context][|varname[|options]])\n"
00056 " Optionally sets <varname> to the number of messages in that folder."
00057 " Assumes folder of INBOX if not specified.\n"
00058 " The option string may contain zero or the following character:\n"
00059 " 'j' -- jump to priority n+101, if there is voicemail in the folder indicated.\n"
00060 " This application sets the following channel variable upon completion:\n"
00061 " HASVMSTATUS The result of the voicemail check returned as a text string as follows\n"
00062 " <# of messages in the folder, 0 for NONE>\n";
00063
00064 static char *app_hasnewvoicemail = "HasNewVoicemail";
00065 static char *hasnewvoicemail_synopsis = "Conditionally branches to priority + 101 with the right options set";
00066 static char *hasnewvoicemail_descrip =
00067 "HasNewVoicemail(vmbox[/folder][@context][|varname[|options]])\n"
00068 "Assumes folder 'INBOX' if folder is not specified. Optionally sets <varname> to the number of messages\n"
00069 "in that folder.\n"
00070 " The option string may contain zero of the following character:\n"
00071 " 'j' -- jump to priority n+101, if there is new voicemail in folder 'folder' or INBOX\n"
00072 " This application sets the following channel variable upon completion:\n"
00073 " HASVMSTATUS The result of the new voicemail check returned as a text string as follows\n"
00074 " <# of messages in the folder, 0 for NONE>\n";
00075
00076 STANDARD_LOCAL_USER;
00077
00078 LOCAL_USER_DECL;
00079
00080 static int hasvoicemail_internal(char *context, char *box, char *folder)
00081 {
00082 char vmpath[256];
00083 DIR *vmdir;
00084 struct dirent *vment;
00085 int count=0;
00086
00087 snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, box, folder);
00088 if ((vmdir = opendir(vmpath))) {
00089
00090 while ((vment = readdir(vmdir))) {
00091 if (!strncmp(vment->d_name + 7, ".txt", 4)) {
00092 count++;
00093 }
00094 }
00095 closedir(vmdir);
00096 }
00097 return count;
00098 }
00099
00100 static int hasvoicemail_exec(struct ast_channel *chan, void *data)
00101 {
00102 struct localuser *u;
00103 char *input, *varname = NULL, *vmbox, *context = "default";
00104 char *vmfolder;
00105 int vmcount = 0;
00106 static int dep_warning = 0;
00107 int priority_jump = 0;
00108 char tmp[12];
00109 AST_DECLARE_APP_ARGS(args,
00110 AST_APP_ARG(vmbox);
00111 AST_APP_ARG(varname);
00112 AST_APP_ARG(options);
00113 );
00114
00115 if (!dep_warning) {
00116 ast_log(LOG_WARNING, "The applications HasVoicemail and HasNewVoicemail have been deprecated. Please use the VMCOUNT() function instead.\n");
00117 dep_warning = 1;
00118 }
00119
00120 if (!data) {
00121 ast_log(LOG_WARNING, "HasVoicemail requires an argument (vm-box[/folder][@context][|varname[|options]])\n");
00122 return -1;
00123 }
00124
00125 LOCAL_USER_ADD(u);
00126
00127 input = ast_strdupa((char *)data);
00128 if (! input) {
00129 ast_log(LOG_ERROR, "Out of memory error\n");
00130 LOCAL_USER_REMOVE(u);
00131 return -1;
00132 }
00133
00134 AST_STANDARD_APP_ARGS(args, input);
00135
00136 if ((vmbox = strsep(&args.vmbox, "@")))
00137 if (!ast_strlen_zero(args.vmbox))
00138 context = args.vmbox;
00139 if (!vmbox)
00140 vmbox = args.vmbox;
00141
00142 vmfolder = strchr(vmbox, '/');
00143 if (vmfolder) {
00144 *vmfolder = '\0';
00145 vmfolder++;
00146 } else {
00147 vmfolder = "INBOX";
00148 }
00149
00150 if (args.options) {
00151 if (strchr(args.options, 'j'))
00152 priority_jump = 1;
00153 }
00154
00155 vmcount = hasvoicemail_internal(context, vmbox, vmfolder);
00156
00157 if (varname) {
00158 snprintf(tmp, sizeof(tmp), "%d", vmcount);
00159 pbx_builtin_setvar_helper(chan, varname, tmp);
00160 }
00161
00162 if (vmcount > 0) {
00163
00164 if (priority_jump || option_priority_jumping) {
00165 if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
00166 ast_log(LOG_WARNING, "VM box %s@%s has new voicemail, but extension %s, priority %d doesn't exist\n", vmbox, context, chan->exten, chan->priority + 101);
00167 }
00168 }
00169
00170 snprintf(tmp, sizeof(tmp), "%d", vmcount);
00171 pbx_builtin_setvar_helper(chan, "HASVMSTATUS", tmp);
00172
00173 LOCAL_USER_REMOVE(u);
00174
00175 return 0;
00176 }
00177
00178 static char *acf_vmcount_exec(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
00179 {
00180 struct localuser *u;
00181 char *args, *context, *box, *folder;
00182
00183 LOCAL_USER_ACF_ADD(u);
00184
00185 buf[0] = '\0';
00186
00187 args = ast_strdupa(data);
00188 if (!args) {
00189 ast_log(LOG_ERROR, "Out of memory");
00190 LOCAL_USER_REMOVE(u);
00191 return buf;
00192 }
00193
00194 box = strsep(&args, "|");
00195 if (strchr(box, '@')) {
00196 context = box;
00197 box = strsep(&context, "@");
00198 } else {
00199 context = "default";
00200 }
00201
00202 if (args) {
00203 folder = args;
00204 } else {
00205 folder = "INBOX";
00206 }
00207
00208 snprintf(buf, len, "%d", hasvoicemail_internal(context, box, folder));
00209
00210 LOCAL_USER_REMOVE(u);
00211
00212 return buf;
00213 }
00214
00215 struct ast_custom_function acf_vmcount = {
00216 .name = "VMCOUNT",
00217 .synopsis = "Counts the voicemail in a specified mailbox",
00218 .syntax = "VMCOUNT(vmbox[@context][|folder])",
00219 .desc =
00220 " context - defaults to \"default\"\n"
00221 " folder - defaults to \"INBOX\"\n",
00222 .read = acf_vmcount_exec,
00223 };
00224
00225 int unload_module(void)
00226 {
00227 int res;
00228
00229 res = ast_custom_function_unregister(&acf_vmcount);
00230 res |= ast_unregister_application(app_hasvoicemail);
00231 res |= ast_unregister_application(app_hasnewvoicemail);
00232
00233 STANDARD_HANGUP_LOCALUSERS;
00234
00235 return res;
00236 }
00237
00238 int load_module(void)
00239 {
00240 int res;
00241
00242 res = ast_custom_function_register(&acf_vmcount);
00243 res |= ast_register_application(app_hasvoicemail, hasvoicemail_exec, hasvoicemail_synopsis, hasvoicemail_descrip);
00244 res |= ast_register_application(app_hasnewvoicemail, hasvoicemail_exec, hasnewvoicemail_synopsis, hasnewvoicemail_descrip);
00245
00246 return res;
00247 }
00248
00249 char *description(void)
00250 {
00251 return tdesc;
00252 }
00253
00254 int usecount(void)
00255 {
00256 int res;
00257 STANDARD_USECOUNT(res);
00258 return res;
00259 }
00260
00261 char *key()
00262 {
00263 return ASTERISK_GPL_KEY;
00264 }