#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
Go to the source code of this file.
Data Structures | |
struct | sortable_keys |
Defines | |
#define | ERROR_NOARG (-1) |
#define | ERROR_NOMEM (-2) |
#define | ERROR_USAGE (-3) |
#define | MAXRESULT 1024 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | acf_cut_exec (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | acf_sort_exec (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | cut_internal (struct ast_channel *chan, char *data, char *buffer, size_t buflen) |
static int | load_module (void) |
static int | sort_internal (struct ast_channel *chan, char *data, char *buffer, size_t buflen) |
static int | sort_subroutine (const void *arg1, const void *arg2) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Cut out information from a string" , .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } |
ast_custom_function | acf_cut |
ast_custom_function | acf_sort |
static const struct ast_module_info * | ast_module_info = &__mod_info |
Definition in file func_cut.c.
#define ERROR_NOARG (-1) |
Definition at line 63 of file func_cut.c.
Referenced by acf_cut_exec(), acf_sort_exec(), cut_internal(), and sort_internal().
#define ERROR_NOMEM (-2) |
Definition at line 64 of file func_cut.c.
Referenced by acf_cut_exec(), acf_sort_exec(), and cut_internal().
#define ERROR_USAGE (-3) |
#define MAXRESULT 1024 |
Definition at line 45 of file func_cut.c.
Referenced by cut_internal(), exec_exec(), and tryexec_exec().
static void __reg_module | ( | void | ) | [static] |
Definition at line 331 of file func_cut.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 331 of file func_cut.c.
static int acf_cut_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 252 of file func_cut.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, ast_module_user::chan, cut_internal(), ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, and LOG_ERROR.
00253 { 00254 int ret = -1; 00255 struct ast_module_user *u = NULL; 00256 00257 if (chan) { 00258 u = ast_module_user_add(chan); 00259 } 00260 00261 switch (cut_internal(chan, data, buf, len)) { 00262 case ERROR_NOARG: 00263 ast_log(LOG_ERROR, "Syntax: CUT(<varname>,<char-delim>,<range-spec>) - missing argument!\n"); 00264 break; 00265 case ERROR_NOMEM: 00266 ast_log(LOG_ERROR, "Out of memory\n"); 00267 break; 00268 case ERROR_USAGE: 00269 ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n"); 00270 break; 00271 case 0: 00272 ret = 0; 00273 break; 00274 default: 00275 ast_log(LOG_ERROR, "Unknown internal error\n"); 00276 } 00277 00278 if (chan) { 00279 ast_module_user_remove(u); 00280 } 00281 00282 return ret; 00283 }
static int acf_sort_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 226 of file func_cut.c.
References ast_log(), ast_module_user_add, ast_module_user_remove, ast_module_user::chan, ERROR_NOARG, ERROR_NOMEM, LOG_ERROR, and sort_internal().
00227 { 00228 struct ast_module_user *u; 00229 int ret = -1; 00230 00231 u = ast_module_user_add(chan); 00232 00233 switch (sort_internal(chan, data, buf, len)) { 00234 case ERROR_NOARG: 00235 ast_log(LOG_ERROR, "SORT() requires an argument\n"); 00236 break; 00237 case ERROR_NOMEM: 00238 ast_log(LOG_ERROR, "Out of memory\n"); 00239 break; 00240 case 0: 00241 ret = 0; 00242 break; 00243 default: 00244 ast_log(LOG_ERROR, "Unknown internal error\n"); 00245 } 00246 00247 ast_module_user_remove(u); 00248 00249 return ret; 00250 }
static int cut_internal | ( | struct ast_channel * | chan, | |
char * | data, | |||
char * | buffer, | |||
size_t | buflen | |||
) | [static] |
Definition at line 118 of file func_cut.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strdupa, ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, LOG_WARNING, MAXRESULT, parse(), and pbx_substitute_variables_helper().
Referenced by acf_cut_exec().
00119 { 00120 char *parse; 00121 AST_DECLARE_APP_ARGS(args, 00122 AST_APP_ARG(varname); 00123 AST_APP_ARG(delimiter); 00124 AST_APP_ARG(field); 00125 ); 00126 00127 memset(buffer, 0, buflen); 00128 00129 parse = ast_strdupa(data); 00130 00131 AST_STANDARD_APP_ARGS(args, parse); 00132 00133 /* Check and parse arguments */ 00134 if(args.argc < 3){ 00135 return ERROR_NOARG; 00136 } else { 00137 char d, ds[2]; 00138 char *tmp = alloca(strlen(args.varname) + 4); 00139 char varvalue[MAXRESULT], *tmp2=varvalue; 00140 00141 if (tmp) { 00142 snprintf(tmp, strlen(args.varname) + 4, "${%s}", args.varname); 00143 memset(varvalue, 0, sizeof(varvalue)); 00144 } else { 00145 return ERROR_NOMEM; 00146 } 00147 00148 if (args.delimiter[0] == '\\') { 00149 if (args.delimiter[1] == 'n') 00150 d = '\n'; 00151 else if (args.delimiter[1] == 't') 00152 d = '\t'; 00153 else if (args.delimiter[1] == 'r') 00154 d = '\r'; 00155 else if (args.delimiter[1]) 00156 d = args.delimiter[1]; 00157 else 00158 d = '-'; 00159 } else if (args.delimiter[0]) 00160 d = args.delimiter[0]; 00161 else 00162 d = '-'; 00163 00164 /* String form of the delimiter, for use with strsep(3) */ 00165 snprintf(ds, sizeof(ds), "%c", d); 00166 00167 pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1); 00168 00169 if (tmp2) { 00170 int curfieldnum = 1, firstfield = 1; 00171 while (tmp2 != NULL && args.field != NULL) { 00172 char *nextgroup = strsep(&(args.field), "&"); 00173 int num1 = 0, num2 = MAXRESULT; 00174 char trashchar; 00175 00176 if (sscanf(nextgroup, "%30d-%30d", &num1, &num2) == 2) { 00177 /* range with both start and end */ 00178 } else if (sscanf(nextgroup, "-%30d", &num2) == 1) { 00179 /* range with end */ 00180 num1 = 0; 00181 } else if ((sscanf(nextgroup, "%30d%1c", &num1, &trashchar) == 2) && (trashchar == '-')) { 00182 /* range with start */ 00183 num2 = MAXRESULT; 00184 } else if (sscanf(nextgroup, "%30d", &num1) == 1) { 00185 /* single number */ 00186 num2 = num1; 00187 } else { 00188 return ERROR_USAGE; 00189 } 00190 00191 /* Get to start, if any */ 00192 if (num1 > 0) { 00193 while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) { 00194 tmp2 = strchr(tmp2, d) + 1; 00195 curfieldnum++; 00196 } 00197 } 00198 00199 /* Most frequent problem is the expectation of reordering fields */ 00200 if ((num1 > 0) && (curfieldnum > num1)) 00201 ast_log(LOG_WARNING, "We're already past the field you wanted?\n"); 00202 00203 /* Re-null tmp2 if we added 1 to NULL */ 00204 if (tmp2 == (char *)NULL + 1) 00205 tmp2 = NULL; 00206 00207 /* Output fields until we either run out of fields or num2 is reached */ 00208 while (tmp2 != NULL && curfieldnum <= num2) { 00209 char *tmp3 = strsep(&tmp2, ds); 00210 int curlen = strlen(buffer); 00211 00212 if (firstfield) { 00213 snprintf(buffer, buflen, "%s", tmp3); 00214 firstfield = 0; 00215 } else { 00216 snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3); 00217 } 00218 curfieldnum++; 00219 } 00220 } 00221 } 00222 } 00223 return 0; 00224 }
static int load_module | ( | void | ) | [static] |
Definition at line 321 of file func_cut.c.
References acf_cut, acf_sort, and ast_custom_function_register().
00322 { 00323 int res = 0; 00324 00325 res |= ast_custom_function_register(&acf_cut); 00326 res |= ast_custom_function_register(&acf_sort); 00327 00328 return res; 00329 }
static int sort_internal | ( | struct ast_channel * | chan, | |
char * | data, | |||
char * | buffer, | |||
size_t | buflen | |||
) | [static] |
Definition at line 67 of file func_cut.c.
References ast_strdupa, ERROR_NOARG, sortable_keys::key, sort_subroutine(), and sortable_keys::value.
Referenced by acf_sort_exec().
00068 { 00069 char *strings, *ptrkey, *ptrvalue; 00070 int count=1, count2, element_count=0; 00071 struct sortable_keys *sortable_keys; 00072 00073 memset(buffer, 0, buflen); 00074 00075 if (!data) 00076 return ERROR_NOARG; 00077 00078 strings = ast_strdupa(data); 00079 00080 for (ptrkey = strings; *ptrkey; ptrkey++) { 00081 if (*ptrkey == '|') 00082 count++; 00083 } 00084 00085 sortable_keys = alloca(count * sizeof(struct sortable_keys)); 00086 00087 memset(sortable_keys, 0, count * sizeof(struct sortable_keys)); 00088 00089 /* Parse each into a struct */ 00090 count2 = 0; 00091 while ((ptrkey = strsep(&strings, "|"))) { 00092 ptrvalue = strchr(ptrkey, ':'); 00093 if (!ptrvalue) { 00094 count--; 00095 continue; 00096 } 00097 *ptrvalue++ = '\0'; 00098 sortable_keys[count2].key = ptrkey; 00099 sscanf(ptrvalue, "%30f", &sortable_keys[count2].value); 00100 count2++; 00101 } 00102 00103 /* Sort the structs */ 00104 qsort(sortable_keys, count, sizeof(struct sortable_keys), sort_subroutine); 00105 00106 for (count2 = 0; count2 < count; count2++) { 00107 int blen = strlen(buffer); 00108 if (element_count++) { 00109 strncat(buffer + blen, ",", buflen - blen - 1); 00110 blen++; 00111 } 00112 strncat(buffer + blen, sortable_keys[count2].key, buflen - blen - 1); 00113 } 00114 00115 return 0; 00116 }
static int sort_subroutine | ( | const void * | arg1, | |
const void * | arg2 | |||
) | [static] |
Definition at line 52 of file func_cut.c.
References sortable_keys::value.
Referenced by sort_internal().
00053 { 00054 const struct sortable_keys *one=arg1, *two=arg2; 00055 if (one->value < two->value) 00056 return -1; 00057 else if (one->value == two->value) 00058 return 0; 00059 else 00060 return 1; 00061 }
static int unload_module | ( | void | ) | [static] |
Definition at line 309 of file func_cut.c.
References acf_cut, acf_sort, ast_custom_function_unregister(), and ast_module_user_hangup_all.
00310 { 00311 int res = 0; 00312 00313 res |= ast_custom_function_unregister(&acf_cut); 00314 res |= ast_custom_function_unregister(&acf_sort); 00315 00316 ast_module_user_hangup_all(); 00317 00318 return res; 00319 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Cut out information from a string" , .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 331 of file func_cut.c.
struct ast_custom_function acf_cut |
struct ast_custom_function acf_sort |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 331 of file func_cut.c.