#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/localtime.h"
Go to the source code of this file.
Defines | |
#define | SPRINTF_CONVERSION 4 |
#define | SPRINTF_FLAG 0 |
#define | SPRINTF_LENGTH 3 |
#define | SPRINTF_PRECISION 2 |
#define | SPRINTF_WIDTH 1 |
Functions | |
static int | acf_sprintf (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | acf_strftime (struct ast_channel *chan, char *cmd, char *parse, char *buf, size_t len) |
static int | acf_strptime (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | array (struct ast_channel *chan, char *cmd, char *var, const char *value) |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"String handling dialplan functions") | |
static int | filter (struct ast_channel *chan, char *cmd, char *parse, char *buf, size_t len) |
static int | function_eval (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | function_fieldqty (struct ast_channel *chan, char *cmd, char *parse, char *buf, size_t len) |
static int | keypadhash (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | len (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | load_module (void) |
static int | quote (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | regex (struct ast_channel *chan, char *cmd, char *parse, char *buf, size_t len) |
static int | unload_module (void) |
Variables | |
static struct ast_custom_function | array_function |
static struct ast_custom_function | eval_function |
static struct ast_custom_function | fieldqty_function |
static struct ast_custom_function | filter_function |
static struct ast_custom_function | keypadhash_function |
static struct ast_custom_function | len_function |
static struct ast_custom_function | quote_function |
static struct ast_custom_function | regex_function |
static struct ast_custom_function | sprintf_function |
static struct ast_custom_function | strftime_function |
static struct ast_custom_function | strptime_function |
Definition in file func_strings.c.
#define SPRINTF_CONVERSION 4 |
Referenced by acf_sprintf().
#define SPRINTF_FLAG 0 |
Referenced by acf_sprintf().
#define SPRINTF_LENGTH 3 |
Referenced by acf_sprintf().
#define SPRINTF_PRECISION 2 |
Referenced by acf_sprintf().
#define SPRINTF_WIDTH 1 |
Referenced by acf_sprintf().
static int acf_sprintf | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 229 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, format, LOG_ERROR, SPRINTF_CONVERSION, SPRINTF_FLAG, SPRINTF_LENGTH, SPRINTF_PRECISION, SPRINTF_WIDTH, and var.
00230 { 00231 #define SPRINTF_FLAG 0 00232 #define SPRINTF_WIDTH 1 00233 #define SPRINTF_PRECISION 2 00234 #define SPRINTF_LENGTH 3 00235 #define SPRINTF_CONVERSION 4 00236 int i, state = -1, argcount = 0; 00237 char *formatstart = NULL, *bufptr = buf; 00238 char formatbuf[256] = ""; 00239 int tmpi; 00240 double tmpd; 00241 AST_DECLARE_APP_ARGS(arg, 00242 AST_APP_ARG(format); 00243 AST_APP_ARG(var)[100]; 00244 ); 00245 00246 AST_STANDARD_APP_ARGS(arg, data); 00247 00248 /* Scan the format, converting each argument into the requisite format type. */ 00249 for (i = 0; arg.format[i]; i++) { 00250 switch (state) { 00251 case SPRINTF_FLAG: 00252 if (strchr("#0- +'I", arg.format[i])) 00253 break; 00254 state = SPRINTF_WIDTH; 00255 case SPRINTF_WIDTH: 00256 if (arg.format[i] >= '0' && arg.format[i] <= '9') 00257 break; 00258 00259 /* Next character must be a period to go into a precision */ 00260 if (arg.format[i] == '.') { 00261 state = SPRINTF_PRECISION; 00262 } else { 00263 state = SPRINTF_LENGTH; 00264 i--; 00265 } 00266 break; 00267 case SPRINTF_PRECISION: 00268 if (arg.format[i] >= '0' && arg.format[i] <= '9') 00269 break; 00270 state = SPRINTF_LENGTH; 00271 case SPRINTF_LENGTH: 00272 if (strchr("hl", arg.format[i])) { 00273 if (arg.format[i + 1] == arg.format[i]) 00274 i++; 00275 state = SPRINTF_CONVERSION; 00276 break; 00277 } else if (strchr("Lqjzt", arg.format[i])) 00278 state = SPRINTF_CONVERSION; 00279 break; 00280 state = SPRINTF_CONVERSION; 00281 case SPRINTF_CONVERSION: 00282 if (strchr("diouxXc", arg.format[i])) { 00283 /* Integer */ 00284 00285 /* Isolate this format alone */ 00286 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf)); 00287 formatbuf[&arg.format[i] - formatstart + 1] = '\0'; 00288 00289 /* Convert the argument into the required type */ 00290 if (sscanf(arg.var[argcount++], "%d", &tmpi) != 1) { 00291 ast_log(LOG_ERROR, "Argument '%s' is not an integer number for format '%s'\n", arg.var[argcount - 1], formatbuf); 00292 goto sprintf_fail; 00293 } 00294 00295 /* Format the argument */ 00296 snprintf(bufptr, buf + len - bufptr, formatbuf, tmpi); 00297 00298 /* Update the position of the next parameter to print */ 00299 bufptr = strchr(buf, '\0'); 00300 } else if (strchr("eEfFgGaA", arg.format[i])) { 00301 /* Double */ 00302 00303 /* Isolate this format alone */ 00304 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf)); 00305 formatbuf[&arg.format[i] - formatstart + 1] = '\0'; 00306 00307 /* Convert the argument into the required type */ 00308 if (sscanf(arg.var[argcount++], "%lf", &tmpd) != 1) { 00309 ast_log(LOG_ERROR, "Argument '%s' is not a floating point number for format '%s'\n", arg.var[argcount - 1], formatbuf); 00310 goto sprintf_fail; 00311 } 00312 00313 /* Format the argument */ 00314 snprintf(bufptr, buf + len - bufptr, formatbuf, tmpd); 00315 00316 /* Update the position of the next parameter to print */ 00317 bufptr = strchr(buf, '\0'); 00318 } else if (arg.format[i] == 's') { 00319 /* String */ 00320 00321 /* Isolate this format alone */ 00322 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf)); 00323 formatbuf[&arg.format[i] - formatstart + 1] = '\0'; 00324 00325 /* Format the argument */ 00326 snprintf(bufptr, buf + len - bufptr, formatbuf, arg.var[argcount++]); 00327 00328 /* Update the position of the next parameter to print */ 00329 bufptr = strchr(buf, '\0'); 00330 } else if (arg.format[i] == '%') { 00331 /* Literal data to copy */ 00332 *bufptr++ = arg.format[i]; 00333 } else { 00334 /* Not supported */ 00335 00336 /* Isolate this format alone */ 00337 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf)); 00338 formatbuf[&arg.format[i] - formatstart + 1] = '\0'; 00339 00340 ast_log(LOG_ERROR, "Format type not supported: '%s' with argument '%s'\n", formatbuf, arg.var[argcount++]); 00341 goto sprintf_fail; 00342 } 00343 state = -1; 00344 break; 00345 default: 00346 if (arg.format[i] == '%') { 00347 state = SPRINTF_FLAG; 00348 formatstart = &arg.format[i]; 00349 break; 00350 } else { 00351 /* Literal data to copy */ 00352 *bufptr++ = arg.format[i]; 00353 } 00354 } 00355 } 00356 return 0; 00357 sprintf_fail: 00358 return -1; 00359 }
static int acf_strftime | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 422 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_get_time_t(), ast_localtime(), ast_log(), AST_STANDARD_APP_ARGS, format, and LOG_WARNING.
00424 { 00425 AST_DECLARE_APP_ARGS(args, 00426 AST_APP_ARG(epoch); 00427 AST_APP_ARG(timezone); 00428 AST_APP_ARG(format); 00429 ); 00430 time_t epochi; 00431 struct tm tm; 00432 00433 buf[0] = '\0'; 00434 00435 AST_STANDARD_APP_ARGS(args, parse); 00436 00437 ast_get_time_t(args.epoch, &epochi, time(NULL), NULL); 00438 ast_localtime(&epochi, &tm, args.timezone); 00439 00440 if (!args.format) 00441 args.format = "%c"; 00442 00443 if (!strftime(buf, len, args.format, &tm)) 00444 ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n"); 00445 00446 buf[len - 1] = '\0'; 00447 00448 return 0; 00449 }
static int acf_strptime | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 458 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), ast_mktime(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), format, LOG_ERROR, and LOG_WARNING.
00460 { 00461 AST_DECLARE_APP_ARGS(args, 00462 AST_APP_ARG(timestring); 00463 AST_APP_ARG(timezone); 00464 AST_APP_ARG(format); 00465 ); 00466 struct tm time; 00467 00468 memset(&time, 0, sizeof(struct tm)); 00469 00470 buf[0] = '\0'; 00471 00472 if (!data) { 00473 ast_log(LOG_ERROR, 00474 "Asterisk function STRPTIME() requires an argument.\n"); 00475 return -1; 00476 } 00477 00478 AST_STANDARD_APP_ARGS(args, data); 00479 00480 if (ast_strlen_zero(args.format)) { 00481 ast_log(LOG_ERROR, 00482 "No format supplied to STRPTIME(<timestring>|<timezone>|<format>)"); 00483 return -1; 00484 } 00485 00486 if (!strptime(args.timestring, args.format, &time)) { 00487 ast_log(LOG_WARNING, "C function strptime() output nothing?!!\n"); 00488 } else { 00489 snprintf(buf, len, "%d", (int) ast_mktime(&time, args.timezone)); 00490 } 00491 00492 return 0; 00493 }
static int array | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 165 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, LOG_DEBUG, option_debug, and pbx_builtin_setvar_helper().
00167 { 00168 AST_DECLARE_APP_ARGS(arg1, 00169 AST_APP_ARG(var)[100]; 00170 ); 00171 AST_DECLARE_APP_ARGS(arg2, 00172 AST_APP_ARG(val)[100]; 00173 ); 00174 char *value2; 00175 int i; 00176 00177 value2 = ast_strdupa(value); 00178 if (!var || !value2) 00179 return -1; 00180 00181 /* The functions this will generally be used with are SORT and ODBC_*, which 00182 * both return comma-delimited lists. However, if somebody uses literal lists, 00183 * their commas will be translated to vertical bars by the load, and I don't 00184 * want them to be surprised by the result. Hence, we prefer commas as the 00185 * delimiter, but we'll fall back to vertical bars if commas aren't found. 00186 */ 00187 if (option_debug) 00188 ast_log(LOG_DEBUG, "array (%s=%s)\n", var, value2); 00189 if (strchr(var, ',')) 00190 AST_NONSTANDARD_APP_ARGS(arg1, var, ','); 00191 else 00192 AST_STANDARD_APP_ARGS(arg1, var); 00193 00194 if (strchr(value2, ',')) 00195 AST_NONSTANDARD_APP_ARGS(arg2, value2, ','); 00196 else 00197 AST_STANDARD_APP_ARGS(arg2, value2); 00198 00199 for (i = 0; i < arg1.argc; i++) { 00200 if (option_debug) 00201 ast_log(LOG_DEBUG, "array set value (%s=%s)\n", arg1.var[i], 00202 arg2.val[i]); 00203 if (i < arg2.argc) { 00204 pbx_builtin_setvar_helper(chan, arg1.var[i], arg2.val[i]); 00205 } else { 00206 /* We could unset the variable, by passing a NULL, but due to 00207 * pushvar semantics, that could create some undesired behavior. */ 00208 pbx_builtin_setvar_helper(chan, arg1.var[i], ""); 00209 } 00210 } 00211 00212 return 0; 00213 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"String handling dialplan functions" | ||||
) |
static int filter | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 83 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, and LOG_ERROR.
00085 { 00086 AST_DECLARE_APP_ARGS(args, 00087 AST_APP_ARG(allowed); 00088 AST_APP_ARG(string); 00089 ); 00090 char *outbuf = buf; 00091 00092 AST_STANDARD_APP_ARGS(args, parse); 00093 00094 if (!args.string) { 00095 ast_log(LOG_ERROR, "Usage: FILTER(<allowed-chars>|<string>)\n"); 00096 return -1; 00097 } 00098 00099 for (; *(args.string) && (buf + len - 1 > outbuf); (args.string)++) { 00100 if (strchr(args.allowed, *(args.string))) 00101 *outbuf++ = *(args.string); 00102 } 00103 *outbuf = '\0'; 00104 00105 return 0; 00106 }
static int function_eval | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 510 of file func_strings.c.
References ast_log(), ast_strlen_zero(), LOG_WARNING, and pbx_substitute_variables_helper().
00512 { 00513 memset(buf, 0, len); 00514 00515 if (ast_strlen_zero(data)) { 00516 ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<string>)\n"); 00517 return -1; 00518 } 00519 00520 pbx_substitute_variables_helper(chan, data, buf, len - 1); 00521 00522 return 0; 00523 }
static int function_fieldqty | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 46 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strlen_zero(), pbx_substitute_variables_helper(), and strsep().
00048 { 00049 char *varsubst, varval[8192] = "", *varval2 = varval; 00050 int fieldcount = 0; 00051 AST_DECLARE_APP_ARGS(args, 00052 AST_APP_ARG(varname); 00053 AST_APP_ARG(delim); 00054 ); 00055 00056 AST_STANDARD_APP_ARGS(args, parse); 00057 if (args.delim) { 00058 varsubst = alloca(strlen(args.varname) + 4); 00059 00060 sprintf(varsubst, "${%s}", args.varname); 00061 pbx_substitute_variables_helper(chan, varsubst, varval, sizeof(varval) - 1); 00062 if (ast_strlen_zero(varval2)) 00063 fieldcount = 0; 00064 else { 00065 while (strsep(&varval2, args.delim)) 00066 fieldcount++; 00067 } 00068 } else { 00069 fieldcount = 1; 00070 } 00071 snprintf(buf, len, "%d", fieldcount); 00072 00073 return 0; 00074 }
static int keypadhash | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 541 of file func_strings.c.
00542 { 00543 char *bufptr, *dataptr; 00544 00545 for (bufptr = buf, dataptr = data; bufptr < buf + len - 1; dataptr++) { 00546 if (*dataptr == '1') { 00547 *bufptr++ = '1'; 00548 } else if (strchr("AaBbCc2", *dataptr)) { 00549 *bufptr++ = '2'; 00550 } else if (strchr("DdEeFf3", *dataptr)) { 00551 *bufptr++ = '3'; 00552 } else if (strchr("GgHhIi4", *dataptr)) { 00553 *bufptr++ = '4'; 00554 } else if (strchr("JjKkLl5", *dataptr)) { 00555 *bufptr++ = '5'; 00556 } else if (strchr("MmNnOo6", *dataptr)) { 00557 *bufptr++ = '6'; 00558 } else if (strchr("PpQqRrSs7", *dataptr)) { 00559 *bufptr++ = '7'; 00560 } else if (strchr("TtUuVv8", *dataptr)) { 00561 *bufptr++ = '8'; 00562 } else if (strchr("WwXxYyZz9", *dataptr)) { 00563 *bufptr++ = '9'; 00564 } else if (*dataptr == '0') { 00565 *bufptr++ = '0'; 00566 } else if (*dataptr == '\0') { 00567 *bufptr++ = '\0'; 00568 break; 00569 } 00570 } 00571 buf[len - 1] = '\0'; 00572 00573 return 0; 00574 }
static int len | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 402 of file func_strings.c.
00404 { 00405 int length = 0; 00406 00407 if (data) 00408 length = strlen(data); 00409 00410 snprintf(buf, len, "%d", length); 00411 00412 return 0; 00413 }
static int load_module | ( | void | ) | [static] |
Definition at line 603 of file func_strings.c.
References ast_custom_function_register().
00604 { 00605 int res = 0; 00606 00607 res |= ast_custom_function_register(&fieldqty_function); 00608 res |= ast_custom_function_register(&filter_function); 00609 res |= ast_custom_function_register(®ex_function); 00610 res |= ast_custom_function_register(&array_function); 00611 res |= ast_custom_function_register("e_function); 00612 res |= ast_custom_function_register(&len_function); 00613 res |= ast_custom_function_register(&strftime_function); 00614 res |= ast_custom_function_register(&strptime_function); 00615 res |= ast_custom_function_register(&eval_function); 00616 res |= ast_custom_function_register(&keypadhash_function); 00617 res |= ast_custom_function_register(&sprintf_function); 00618 00619 return res; 00620 }
static int quote | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 372 of file func_strings.c.
Referenced by ast_app_separate_args(), and make_email_file().
00373 { 00374 char *bufptr = buf, *dataptr = data; 00375 *bufptr++ = '"'; 00376 for (; bufptr < buf + len - 1; dataptr++) { 00377 if (*dataptr == '\\') { 00378 *bufptr++ = '\\'; 00379 *bufptr++ = '\\'; 00380 } else if (*dataptr == '"') { 00381 *bufptr++ = '\\'; 00382 *bufptr++ = '"'; 00383 } else if (*dataptr == '\0') { 00384 break; 00385 } else { 00386 *bufptr++ = *dataptr; 00387 } 00388 } 00389 *bufptr++ = '"'; 00390 *bufptr = '\0'; 00391 return 0; 00392 }
static int regex | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | parse, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 115 of file func_strings.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, LOG_DEBUG, LOG_ERROR, LOG_WARNING, and option_debug.
00117 { 00118 AST_DECLARE_APP_ARGS(args, 00119 AST_APP_ARG(null); 00120 AST_APP_ARG(reg); 00121 AST_APP_ARG(str); 00122 ); 00123 int errcode; 00124 regex_t regexbuf; 00125 00126 buf[0] = '\0'; 00127 00128 AST_NONSTANDARD_APP_ARGS(args, parse, '"'); 00129 00130 if (args.argc != 3) { 00131 ast_log(LOG_ERROR, "Unexpected arguments: should have been in the form '\"<regex>\" <string>'\n"); 00132 return -1; 00133 } 00134 if ((*args.str == ' ') || (*args.str == '\t')) 00135 args.str++; 00136 00137 if (option_debug) 00138 ast_log(LOG_DEBUG, "FUNCTION REGEX (%s)(%s)\n", args.reg, args.str); 00139 00140 if ((errcode = regcomp(®exbuf, args.reg, REG_EXTENDED | REG_NOSUB))) { 00141 regerror(errcode, ®exbuf, buf, len); 00142 ast_log(LOG_WARNING, "Malformed input %s(%s): %s\n", cmd, parse, buf); 00143 return -1; 00144 } 00145 00146 strcpy(buf, regexec(®exbuf, args.str, 0, NULL, 0) ? "0" : "1"); 00147 00148 regfree(®exbuf); 00149 00150 return 0; 00151 }
static int unload_module | ( | void | ) | [static] |
Definition at line 584 of file func_strings.c.
References ast_custom_function_unregister().
00585 { 00586 int res = 0; 00587 00588 res |= ast_custom_function_unregister(&fieldqty_function); 00589 res |= ast_custom_function_unregister(&filter_function); 00590 res |= ast_custom_function_unregister(®ex_function); 00591 res |= ast_custom_function_unregister(&array_function); 00592 res |= ast_custom_function_unregister("e_function); 00593 res |= ast_custom_function_unregister(&len_function); 00594 res |= ast_custom_function_unregister(&strftime_function); 00595 res |= ast_custom_function_unregister(&strptime_function); 00596 res |= ast_custom_function_unregister(&eval_function); 00597 res |= ast_custom_function_unregister(&keypadhash_function); 00598 res |= ast_custom_function_unregister(&sprintf_function); 00599 00600 return res; 00601 }
struct ast_custom_function array_function [static] |
Definition at line 215 of file func_strings.c.
struct ast_custom_function eval_function [static] |
Definition at line 525 of file func_strings.c.
struct ast_custom_function fieldqty_function [static] |
Definition at line 76 of file func_strings.c.
struct ast_custom_function filter_function [static] |
Definition at line 108 of file func_strings.c.
struct ast_custom_function keypadhash_function [static] |
Definition at line 576 of file func_strings.c.
struct ast_custom_function len_function [static] |
Definition at line 415 of file func_strings.c.
struct ast_custom_function quote_function [static] |
Definition at line 394 of file func_strings.c.
struct ast_custom_function regex_function [static] |
Definition at line 153 of file func_strings.c.
struct ast_custom_function sprintf_function [static] |
Definition at line 361 of file func_strings.c.
struct ast_custom_function strftime_function [static] |
Definition at line 451 of file func_strings.c.
struct ast_custom_function strptime_function [static] |
Definition at line 495 of file func_strings.c.