#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "asterisk.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 char * | acf_cut_exec (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static char * | acf_sort_exec (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | cut_exec (struct ast_channel *chan, void *data) |
static int | cut_internal (struct ast_channel *chan, char *data, char *buffer, size_t buflen) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static int | sort_exec (struct ast_channel *chan, void *data) |
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) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
ast_custom_function | acf_cut |
ast_custom_function | acf_sort |
static char * | app_cut = "Cut" |
static char * | app_sort = "Sort" |
static char * | app_sort_descrip |
static char * | app_sort_synopsis = "Sorts a list of keywords and values" |
static char * | cut_descrip |
static char * | cut_synopsis = "Splits a variable's contents using the specified delimiter" |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
static char * | tdesc = "Cut out information from a string" |
Definition in file app_cut.c.
#define ERROR_NOARG (-1) |
Definition at line 92 of file app_cut.c.
Referenced by acf_cut_exec(), acf_sort_exec(), cut_exec(), cut_internal(), sort_exec(), and sort_internal().
#define ERROR_NOMEM (-2) |
Definition at line 93 of file app_cut.c.
Referenced by acf_cut_exec(), acf_sort_exec(), cut_exec(), cut_internal(), sort_exec(), and sort_internal().
#define ERROR_USAGE (-3) |
Definition at line 94 of file app_cut.c.
Referenced by acf_cut_exec(), cut_exec(), and cut_internal().
#define MAXRESULT 1024 |
Definition at line 42 of file app_cut.c.
Referenced by cut_internal(), eval_exec(), and exec_exec().
static char* acf_cut_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 383 of file app_cut.c.
References ast_log(), localuser::chan, cut_internal(), ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, LOCAL_USER_ACF_ADD, LOCAL_USER_REMOVE, and LOG_ERROR.
00384 { 00385 struct localuser *u; 00386 00387 LOCAL_USER_ACF_ADD(u); 00388 00389 switch (cut_internal(chan, data, buf, len)) { 00390 case ERROR_NOARG: 00391 ast_log(LOG_ERROR, "CUT() requires an argument\n"); 00392 break; 00393 case ERROR_NOMEM: 00394 ast_log(LOG_ERROR, "Out of memory\n"); 00395 break; 00396 case ERROR_USAGE: 00397 ast_log(LOG_ERROR, "Usage: %s\n", cut_synopsis); 00398 break; 00399 case 0: 00400 break; 00401 default: 00402 ast_log(LOG_ERROR, "Unknown internal error\n"); 00403 } 00404 LOCAL_USER_REMOVE(u); 00405 return buf; 00406 }
static char* acf_sort_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 361 of file app_cut.c.
References ast_log(), localuser::chan, ERROR_NOARG, ERROR_NOMEM, LOCAL_USER_ACF_ADD, LOCAL_USER_REMOVE, LOG_ERROR, and sort_internal().
00362 { 00363 struct localuser *u; 00364 00365 LOCAL_USER_ACF_ADD(u); 00366 00367 switch (sort_internal(chan, data, buf, len)) { 00368 case ERROR_NOARG: 00369 ast_log(LOG_ERROR, "SORT() requires an argument\n"); 00370 break; 00371 case ERROR_NOMEM: 00372 ast_log(LOG_ERROR, "Out of memory\n"); 00373 break; 00374 case 0: 00375 break; 00376 default: 00377 ast_log(LOG_ERROR, "Unknown internal error\n"); 00378 } 00379 LOCAL_USER_REMOVE(u); 00380 return buf; 00381 }
static int cut_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 310 of file app_cut.c.
References ast_log(), ast_strdupa, localuser::chan, cut_internal(), dep_warning, ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, pbx_builtin_setvar_helper(), result, s, and strsep().
Referenced by load_module().
00311 { 00312 int res=0; 00313 struct localuser *u; 00314 char *s, *newvar=NULL, result[512]; 00315 static int dep_warning = 0; 00316 00317 LOCAL_USER_ADD(u); 00318 00319 if (!dep_warning) { 00320 ast_log(LOG_WARNING, "The application Cut is deprecated. Please use the CUT() function instead.\n"); 00321 dep_warning=1; 00322 } 00323 00324 /* Check and parse arguments */ 00325 if (data) { 00326 s = ast_strdupa((char *)data); 00327 if (s) { 00328 newvar = strsep(&s, "="); 00329 } else { 00330 ast_log(LOG_ERROR, "Out of memory\n"); 00331 LOCAL_USER_REMOVE(u); 00332 return -1; 00333 } 00334 } 00335 00336 switch (cut_internal(chan, s, result, sizeof(result))) { 00337 case ERROR_NOARG: 00338 ast_log(LOG_ERROR, "Cut() requires an argument\n"); 00339 res = 0; 00340 break; 00341 case ERROR_NOMEM: 00342 ast_log(LOG_ERROR, "Out of memory\n"); 00343 res = -1; 00344 break; 00345 case ERROR_USAGE: 00346 ast_log(LOG_ERROR, "Usage: %s\n", cut_synopsis); 00347 res = 0; 00348 break; 00349 case 0: 00350 pbx_builtin_setvar_helper(chan, newvar, result); 00351 res = 0; 00352 break; 00353 default: 00354 ast_log(LOG_ERROR, "Unknown internal error\n"); 00355 res = -1; 00356 } 00357 LOCAL_USER_REMOVE(u); 00358 return res; 00359 }
static int cut_internal | ( | struct ast_channel * | chan, | |
char * | data, | |||
char * | buffer, | |||
size_t | buflen | |||
) | [static] |
Definition at line 156 of file app_cut.c.
References ast_app_separate_args(), ast_log(), ast_strdupa, ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, LOG_WARNING, MAXRESULT, pbx_substitute_variables_helper(), s, and strsep().
Referenced by acf_cut_exec(), and cut_exec().
00157 { 00158 char *s, *args[3], *varname=NULL, *delimiter=NULL, *field=NULL; 00159 int args_okay = 0; 00160 00161 memset(buffer, 0, buflen); 00162 00163 /* Check and parse arguments */ 00164 if (data) { 00165 s = ast_strdupa((char *)data); 00166 if (s) { 00167 ast_app_separate_args(s, '|', args, 3); 00168 varname = args[0]; 00169 delimiter = args[1]; 00170 field = args[2]; 00171 00172 if (field) { 00173 args_okay = 1; 00174 } 00175 } else { 00176 return ERROR_NOMEM; 00177 } 00178 } 00179 00180 if (args_okay) { 00181 char d, ds[2]; 00182 char *tmp = alloca(strlen(varname) + 4); 00183 char varvalue[MAXRESULT], *tmp2=varvalue; 00184 00185 if (tmp) { 00186 snprintf(tmp, strlen(varname) + 4, "${%s}", varname); 00187 memset(varvalue, 0, sizeof(varvalue)); 00188 } else { 00189 return ERROR_NOMEM; 00190 } 00191 00192 if (delimiter[0]) 00193 d = delimiter[0]; 00194 else 00195 d = '-'; 00196 00197 /* String form of the delimiter, for use with strsep(3) */ 00198 snprintf(ds, sizeof(ds), "%c", d); 00199 00200 pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1); 00201 00202 if (tmp2) { 00203 int curfieldnum = 1; 00204 while ((tmp2 != NULL) && (field != NULL)) { 00205 char *nextgroup = strsep(&field, "&"); 00206 int num1 = 0, num2 = MAXRESULT; 00207 char trashchar; 00208 00209 if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) { 00210 /* range with both start and end */ 00211 } else if (sscanf(nextgroup, "-%d", &num2) == 1) { 00212 /* range with end */ 00213 num1 = 0; 00214 } else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) { 00215 /* range with start */ 00216 num2 = MAXRESULT; 00217 } else if (sscanf(nextgroup, "%d", &num1) == 1) { 00218 /* single number */ 00219 num2 = num1; 00220 } else { 00221 return ERROR_USAGE; 00222 } 00223 00224 /* Get to start, if any */ 00225 if (num1 > 0) { 00226 while ((tmp2 != (char *)NULL + 1) && (curfieldnum < num1)) { 00227 tmp2 = index(tmp2, d) + 1; 00228 curfieldnum++; 00229 } 00230 } 00231 00232 /* Most frequent problem is the expectation of reordering fields */ 00233 if ((num1 > 0) && (curfieldnum > num1)) { 00234 ast_log(LOG_WARNING, "We're already past the field you wanted?\n"); 00235 } 00236 00237 /* Re-null tmp2 if we added 1 to NULL */ 00238 if (tmp2 == (char *)NULL + 1) 00239 tmp2 = NULL; 00240 00241 /* Output fields until we either run out of fields or num2 is reached */ 00242 while ((tmp2 != NULL) && (curfieldnum <= num2)) { 00243 char *tmp3 = strsep(&tmp2, ds); 00244 int curlen = strlen(buffer); 00245 00246 if (curlen) { 00247 snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3); 00248 } else { 00249 snprintf(buffer, buflen, "%s", tmp3); 00250 } 00251 00252 curfieldnum++; 00253 } 00254 } 00255 } 00256 } else { 00257 return ERROR_NOARG; 00258 } 00259 return 0; 00260 }
char* description | ( | void | ) |
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 470 of file app_cut.c.
References ASTERISK_GPL_KEY.
00471 { 00472 return ASTERISK_GPL_KEY; 00473 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 446 of file app_cut.c.
References acf_cut, acf_sort, ast_custom_function_register(), ast_register_application(), cut_exec(), and sort_exec().
00447 { 00448 int res; 00449 00450 res = ast_custom_function_register(&acf_cut); 00451 res |= ast_custom_function_register(&acf_sort); 00452 res |= ast_register_application(app_sort, sort_exec, app_sort_synopsis, app_sort_descrip); 00453 res |= ast_register_application(app_cut, cut_exec, cut_synopsis, cut_descrip); 00454 00455 return res; 00456 }
static int sort_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 262 of file app_cut.c.
References ast_log(), ast_strdupa, localuser::chan, dep_warning, ERROR_NOARG, ERROR_NOMEM, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_ERROR, LOG_WARNING, pbx_builtin_setvar_helper(), result, sort_internal(), and strsep().
Referenced by load_module().
00263 { 00264 int res=0; 00265 struct localuser *u; 00266 char *varname, *strings, result[512] = ""; 00267 static int dep_warning=0; 00268 00269 if (!dep_warning) { 00270 ast_log(LOG_WARNING, "The application Sort is deprecated. Please use the SORT() function instead.\n"); 00271 dep_warning=1; 00272 } 00273 00274 if (!data) { 00275 ast_log(LOG_ERROR, "Sort() requires an argument\n"); 00276 return 0; 00277 } 00278 00279 LOCAL_USER_ADD(u); 00280 00281 strings = ast_strdupa((char *)data); 00282 if (!strings) { 00283 ast_log(LOG_ERROR, "Out of memory\n"); 00284 LOCAL_USER_REMOVE(u); 00285 return 0; 00286 } 00287 00288 varname = strsep(&strings, "="); 00289 switch (sort_internal(chan, strings, result, sizeof(result))) { 00290 case ERROR_NOARG: 00291 ast_log(LOG_ERROR, "Sort() requires an argument\n"); 00292 res = 0; 00293 break; 00294 case ERROR_NOMEM: 00295 ast_log(LOG_ERROR, "Out of memory\n"); 00296 res = -1; 00297 break; 00298 case 0: 00299 pbx_builtin_setvar_helper(chan, varname, result); 00300 res = 0; 00301 break; 00302 default: 00303 ast_log(LOG_ERROR, "Unknown internal error\n"); 00304 res = -1; 00305 } 00306 LOCAL_USER_REMOVE(u); 00307 return res; 00308 }
static int sort_internal | ( | struct ast_channel * | chan, | |
char * | data, | |||
char * | buffer, | |||
size_t | buflen | |||
) | [static] |
Definition at line 96 of file app_cut.c.
References ast_strdupa, ERROR_NOARG, ERROR_NOMEM, key(), sort_subroutine(), strsep(), and sortable_keys::value.
Referenced by acf_sort_exec(), and sort_exec().
00097 { 00098 char *strings, *ptrkey, *ptrvalue; 00099 int count=1, count2, element_count=0; 00100 struct sortable_keys *sortable_keys; 00101 00102 memset(buffer, 0, buflen); 00103 00104 if (!data) { 00105 return ERROR_NOARG; 00106 } 00107 00108 strings = ast_strdupa((char *)data); 00109 if (!strings) { 00110 return ERROR_NOMEM; 00111 } 00112 00113 for (ptrkey = strings; *ptrkey; ptrkey++) { 00114 if (*ptrkey == '|') { 00115 count++; 00116 } 00117 } 00118 00119 sortable_keys = alloca(count * sizeof(struct sortable_keys)); 00120 if (!sortable_keys) { 00121 return ERROR_NOMEM; 00122 } 00123 00124 memset(sortable_keys, 0, count * sizeof(struct sortable_keys)); 00125 00126 /* Parse each into a struct */ 00127 count2 = 0; 00128 while ((ptrkey = strsep(&strings, "|"))) { 00129 ptrvalue = index(ptrkey, ':'); 00130 if (!ptrvalue) { 00131 count--; 00132 continue; 00133 } 00134 *ptrvalue = '\0'; 00135 ptrvalue++; 00136 sortable_keys[count2].key = ptrkey; 00137 sscanf(ptrvalue, "%f", &sortable_keys[count2].value); 00138 count2++; 00139 } 00140 00141 /* Sort the structs */ 00142 qsort(sortable_keys, count, sizeof(struct sortable_keys), sort_subroutine); 00143 00144 for (count2 = 0; count2 < count; count2++) { 00145 int blen = strlen(buffer); 00146 if (element_count++) { 00147 strncat(buffer + blen, ",", buflen - blen - 1); 00148 blen++; 00149 } 00150 strncat(buffer + blen, sortable_keys[count2].key, buflen - blen - 1); 00151 } 00152 00153 return 0; 00154 }
static int sort_subroutine | ( | const void * | arg1, | |
const void * | arg2 | |||
) | [static] |
Definition at line 80 of file app_cut.c.
References sortable_keys::value.
Referenced by sort_internal().
00081 { 00082 const struct sortable_keys *one=arg1, *two=arg2; 00083 if (one->value < two->value) { 00084 return -1; 00085 } else if (one->value == two->value) { 00086 return 0; 00087 } else { 00088 return 1; 00089 } 00090 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 432 of file app_cut.c.
References acf_cut, acf_sort, ast_custom_function_unregister(), ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.
00433 { 00434 int res; 00435 00436 res = ast_custom_function_unregister(&acf_cut); 00437 res |= ast_custom_function_unregister(&acf_sort); 00438 res |= ast_unregister_application(app_sort); 00439 res |= ast_unregister_application(app_cut); 00440 00441 STANDARD_HANGUP_LOCALUSERS; 00442 00443 return res; 00444 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 463 of file app_cut.c.
References STANDARD_USECOUNT.
00464 { 00465 int res; 00466 STANDARD_USECOUNT(res); 00467 return res; 00468 }
struct ast_custom_function acf_cut |
struct ast_custom_function acf_sort |
char* app_sort_descrip [static] |
Initial value:
" Sort(newvar=key1:val1[,key2:val2[[...],keyN:valN]]): This application will\n" "sort the list provided in ascending order. The result will be stored in the\n" "specified variable name.\n" " This applicaiton has been deprecated in favor of the SORT function.\n"
char* app_sort_synopsis = "Sorts a list of keywords and values" [static] |
char* cut_descrip [static] |
char* cut_synopsis = "Splits a variable's contents using the specified delimiter" [static] |