Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:01 2009

## Asterisk developer's documentation

# app_cut.c File Reference

Cut application. More...

`#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"`

Include dependency graph for app_cut.c:

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

struct ast_custom_function | acf_cut
struct 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"

## Detailed Description

Cut application.

Definition in file app_cut.c.

## Define Documentation

#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().

## Function Documentation

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(), 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(), 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, 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, "%30d-%30d", &num1, &num2) == 2) {
    00210                /* range with both start and end */
    00211             } else if (sscanf(nextgroup, "-%30d", &num2) == 1) {
    00212                /* range with end */
    00213                num1 = 0;
    00214             } else if ((sscanf(nextgroup, "%30d%1c", &num1, &trashchar) == 2) && (trashchar == '-')) {
    00215                /* range with start */
    00216                num2 = MAXRESULT;
    00217             } else if (sscanf(nextgroup, "%30d", &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 |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 458 of file app_cut.c.

    00459 {
    00460    return tdesc;
    00461 }

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;
     }

Returns:
  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.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

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.

Returns:
  int Always 0.

TE STUFF END

Definition at line 446 of file app_cut.c.

References 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, 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(), sortable_keys::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, "%30f", &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).

Returns:
  Zero on success, or non-zero on error.

Definition at line 432 of file app_cut.c.

References 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.

Returns:
  The module's usecount.

Definition at line 463 of file app_cut.c.

References STANDARD_USECOUNT.

    00464 {
    00465    int res;
    00466    STANDARD_USECOUNT(res);
    00467    return res;
    00468 }

## Variable Documentation

struct ast_custom_function acf_cut

Definition at line 419 of file app_cut.c.

struct ast_custom_function acf_sort

Definition at line 408 of file app_cut.c.

char* app_cut = "Cut"`[static]`

Definition at line 46 of file app_cut.c.

char* app_sort = "Sort"`[static]`

Definition at line 63 of file app_cut.c.

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 application has been deprecated in favor of the SORT function.\n"

Definition at line 65 of file app_cut.c.

char* app_sort_synopsis = "Sorts a list of keywords and values"`[static]`

Definition at line 64 of file app_cut.c.

char* cut_descrip`[static]`

Definition at line 50 of file app_cut.c.

char* cut_synopsis = "Splits a variable's contents using the specified delimiter"`[static]`

Definition at line 48 of file app_cut.c.

LOCAL_USER_DECL

Definition at line 73 of file app_cut.c.

STANDARD_LOCAL_USER

Definition at line 71 of file app_cut.c.

char* tdesc = "Cut out information from a string"`[static]`

Definition at line 44 of file app_cut.c.