#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 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) |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Cut out information from a string") | |
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 | |
ast_custom_function | acf_cut |
ast_custom_function | acf_sort |
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 int acf_cut_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 251 of file func_cut.c.
References ast_autoservice_start(), ast_autoservice_stop(), 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.
00252 { 00253 int ret = -1; 00254 struct ast_module_user *u = NULL; 00255 00256 if (chan) { 00257 ast_autoservice_start(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 ast_autoservice_stop(chan); 00281 } 00282 00283 return ret; 00284 }
static int acf_sort_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 225 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().
00226 { 00227 struct ast_module_user *u; 00228 int ret = -1; 00229 00230 u = ast_module_user_add(chan); 00231 00232 switch (sort_internal(chan, data, buf, len)) { 00233 case ERROR_NOARG: 00234 ast_log(LOG_ERROR, "SORT() requires an argument\n"); 00235 break; 00236 case ERROR_NOMEM: 00237 ast_log(LOG_ERROR, "Out of memory\n"); 00238 break; 00239 case 0: 00240 ret = 0; 00241 break; 00242 default: 00243 ast_log(LOG_ERROR, "Unknown internal error\n"); 00244 } 00245 00246 ast_module_user_remove(u); 00247 00248 return ret; 00249 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Cut out information from a string" | ||||
) |
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(), pbx_substitute_variables_helper(), and strsep().
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; 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, "%d-%d", &num1, &num2) == 2) { 00177 /* range with both start and end */ 00178 } else if (sscanf(nextgroup, "-%d", &num2) == 1) { 00179 /* range with end */ 00180 num1 = 0; 00181 } else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) { 00182 /* range with start */ 00183 num2 = MAXRESULT; 00184 } else if (sscanf(nextgroup, "%d", &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 = index(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 (curlen) 00213 snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3); 00214 else 00215 snprintf(buffer, buflen, "%s", tmp3); 00216 00217 curfieldnum++; 00218 } 00219 } 00220 } 00221 } 00222 return 0; 00223 }
static int load_module | ( | void | ) | [static] |
Definition at line 322 of file func_cut.c.
References acf_cut, acf_sort, and ast_custom_function_register().
00323 { 00324 int res = 0; 00325 00326 res |= ast_custom_function_register(&acf_cut); 00327 res |= ast_custom_function_register(&acf_sort); 00328 00329 return res; 00330 }
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(), strsep(), 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 = index(ptrkey, ':'); 00093 if (!ptrvalue) { 00094 count--; 00095 continue; 00096 } 00097 *ptrvalue++ = '\0'; 00098 sortable_keys[count2].key = ptrkey; 00099 sscanf(ptrvalue, "%f", &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 310 of file func_cut.c.
References acf_cut, acf_sort, ast_custom_function_unregister(), and ast_module_user_hangup_all.
00311 { 00312 int res = 0; 00313 00314 res |= ast_custom_function_unregister(&acf_cut); 00315 res |= ast_custom_function_unregister(&acf_sort); 00316 00317 ast_module_user_hangup_all(); 00318 00319 return res; 00320 }
struct ast_custom_function acf_cut |
struct ast_custom_function acf_sort |