00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "asterisk.h"
00025
00026 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 182278 $")
00027
00028 #include <sys/stat.h>
00029
00030 #include "asterisk/module.h"
00031 #include "asterisk/channel.h"
00032 #include "asterisk/pbx.h"
00033 #include "asterisk/utils.h"
00034 #include "asterisk/app.h"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static int env_read(struct ast_channel *chan, const char *cmd, char *data,
00091 char *buf, size_t len)
00092 {
00093 char *ret = NULL;
00094
00095 *buf = '\0';
00096
00097 if (data)
00098 ret = getenv(data);
00099
00100 if (ret)
00101 ast_copy_string(buf, ret, len);
00102
00103 return 0;
00104 }
00105
00106 static int env_write(struct ast_channel *chan, const char *cmd, char *data,
00107 const char *value)
00108 {
00109 if (!ast_strlen_zero(data)) {
00110 if (!ast_strlen_zero(value)) {
00111 setenv(data, value, 1);
00112 } else {
00113 unsetenv(data);
00114 }
00115 }
00116
00117 return 0;
00118 }
00119
00120 static int stat_read(struct ast_channel *chan, const char *cmd, char *data,
00121 char *buf, size_t len)
00122 {
00123 char *action;
00124 struct stat s;
00125
00126 ast_copy_string(buf, "0", len);
00127
00128 action = strsep(&data, ",");
00129 if (stat(data, &s)) {
00130 return 0;
00131 } else {
00132 switch (*action) {
00133 case 'e':
00134 strcpy(buf, "1");
00135 break;
00136 case 's':
00137 snprintf(buf, len, "%d", (unsigned int) s.st_size);
00138 break;
00139 case 'f':
00140 snprintf(buf, len, "%d", S_ISREG(s.st_mode) ? 1 : 0);
00141 break;
00142 case 'd':
00143 snprintf(buf, len, "%d", S_ISDIR(s.st_mode) ? 1 : 0);
00144 break;
00145 case 'M':
00146 snprintf(buf, len, "%d", (int) s.st_mtime);
00147 break;
00148 case 'A':
00149 snprintf(buf, len, "%d", (int) s.st_mtime);
00150 break;
00151 case 'C':
00152 snprintf(buf, len, "%d", (int) s.st_ctime);
00153 break;
00154 case 'm':
00155 snprintf(buf, len, "%o", (int) s.st_mode);
00156 break;
00157 }
00158 }
00159
00160 return 0;
00161 }
00162
00163 static int file_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
00164 {
00165 AST_DECLARE_APP_ARGS(args,
00166 AST_APP_ARG(filename);
00167 AST_APP_ARG(offset);
00168 AST_APP_ARG(length);
00169 );
00170 int offset = 0, length, res = 0;
00171 char *contents;
00172 size_t contents_len;
00173
00174 AST_STANDARD_APP_ARGS(args, data);
00175 if (args.argc > 1) {
00176 offset = atoi(args.offset);
00177 }
00178
00179 if (args.argc > 2) {
00180
00181 if ((length = atoi(args.length) + 1) > len) {
00182 ast_log(LOG_WARNING, "Length %d is greater than the max (%d). Truncating output.\n", length - 1, (int)len - 1);
00183 length = len;
00184 }
00185 } else {
00186 length = len;
00187 }
00188
00189 if (!(contents = ast_read_textfile(args.filename))) {
00190 return -1;
00191 }
00192
00193 do {
00194 contents_len = strlen(contents);
00195 if (offset > contents_len) {
00196 res = -1;
00197 break;
00198 }
00199
00200 if (offset >= 0) {
00201 if (length < 0) {
00202 if (contents_len - offset + length < 0) {
00203
00204 res = -1;
00205 break;
00206 }
00207 ast_copy_string(buf, &contents[offset], contents_len + length);
00208 } else {
00209 ast_copy_string(buf, &contents[offset], length);
00210 }
00211 } else {
00212 if (offset * -1 > contents_len) {
00213 ast_log(LOG_WARNING, "Offset is larger than the file size.\n");
00214 offset = contents_len * -1;
00215 }
00216 ast_copy_string(buf, &contents[contents_len + offset], length);
00217 }
00218 } while (0);
00219
00220 ast_free(contents);
00221
00222 return res;
00223 }
00224
00225 static struct ast_custom_function env_function = {
00226 .name = "ENV",
00227 .read = env_read,
00228 .write = env_write
00229 };
00230
00231 static struct ast_custom_function stat_function = {
00232 .name = "STAT",
00233 .read = stat_read
00234 };
00235
00236 static struct ast_custom_function file_function = {
00237 .name = "FILE",
00238 .read = file_read
00239
00240
00241
00242
00243
00244 };
00245
00246 static int unload_module(void)
00247 {
00248 int res = 0;
00249
00250 res |= ast_custom_function_unregister(&env_function);
00251 res |= ast_custom_function_unregister(&stat_function);
00252 res |= ast_custom_function_unregister(&file_function);
00253
00254 return res;
00255 }
00256
00257 static int load_module(void)
00258 {
00259 int res = 0;
00260
00261 res |= ast_custom_function_register(&env_function);
00262 res |= ast_custom_function_register(&stat_function);
00263 res |= ast_custom_function_register(&file_function);
00264
00265 return res;
00266 }
00267
00268 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Environment/filesystem dialplan functions");