Summary: | ASTERISK-00360: [patch] app_cut | ||
Reporter: | John Todd (jtodd) | Labels: | |
Date Opened: | 2003-10-07 14:12:18 | Date Closed: | 2004-09-25 02:21:16 |
Priority: | Major | Regression? | No |
Status: | Closed/Complete | Components: | Core/General |
Versions: | Frequency of Occurrence | ||
Related Issues: | |||
Environment: | Attachments: | ( 0) app_cut.c ( 1) app_cut.c ( 2) app_cut.c ( 3) app_cut.c | |
Description: | Tilghman's app_cut.c, as sent out on the mailing list. I don't see it here, so I figure I'll put it forward to make sure it doesn't get lost. ****** ADDITIONAL INFORMATION ****** /* * Asterisk -- A telephony toolkit for Linux. * * Cut application * * Copyright (c) 2003 Tilghman Lesher. All rights reserved. * * Tilghman Lesher <app_cut__200310@the-tilghman.com> * * This code is released by the author with no restrictions on usage. * */ #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 <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> static char *tdesc = "Cuts up variables"; static char *app_cut = "Cut"; static char *cut_synopsis = "Cut(newvar=varname|delimiter|field)"; static char *cut_descrip = "Cut(varname=wholestring,delimiter,field)\n" " newvar - result string is set to this variable\n" " varname - variable you want cut\n" " delimiter - defaults to -\n" " field - number of the field you want (1-based offset)\n" " Returns 0 or -1 on hangup or error.\n"; STANDARD_LOCAL_USER; LOCAL_USER_DECL; static int cut_exec(struct ast_channel *chan, void *data) { int res=0; struct localuser *u; char *s, *newvar, *varname, *delimiter, *field; int fieldnum, args_okay = 0; LOCAL_USER_ADD(u); /* Check and parse arguments */ if (data) { s = strdupa((char *)data); if (s) { newvar = strsep(&s, "="); if (newvar && (newvar[0] != '\0')) { varname = strsep(&s, "|"); if (varname && (varname[0] != '\0')) { delimiter = strsep(&s, "|"); if (delimiter) { field = strsep(&s, "|"); if (field && (sscanf(field,"%d",&fieldnum) == 1)) { args_okay = 1; } } } } } else { ast_log(LOG_ERROR, "Out of memory\n"); res = -1; } } if (args_okay) { char d; char *tmp; if (delimiter[0]) d = delimiter[0]; else d = '-'; tmp = pbx_builtin_getvar_helper(chan, varname); if (tmp) { tmp = strdupa(tmp); if (tmp) { int i; for (i=1;i<fieldnum;i++) if (tmp && (tmp[0] != '\0')) tmp = index(tmp, d) + 1; } else { ast_log(LOG_ERROR, "Out of memory\n"); res = -1; } } if (tmp) { /* Get end, if any */ /* (if no further fields, then tmp -> NULL, but we don't care anymore) */ char *value = strsep(&tmp, &d); pbx_builtin_setvar_helper(chan, newvar, value); } } else { ast_log(LOG_ERROR, "Usage: %s\n", cut_synopsis); res = -1; } LOCAL_USER_REMOVE(u); return res; } int unload_module(void) { STANDARD_HANGUP_LOCALUSERS; return ast_unregister_application(app_cut); } int load_module(void) { return ast_register_application(app_cut, cut_exec, cut_synopsis, cut_descrip); } char *description(void) { return tdesc; } int usecount(void) { int res; STANDARD_USECOUNT(res); return res; } char *key() { return ASTERISK_GPL_KEY; } | ||
Comments: | By: John Todd (jtodd) 2003-10-07 17:19:17 Alas, this does not seem to work, though it an optimally designed tool for processing what I hope will be the eventual transmission of SIP URIs in their "native" state to the dialplan. I tried with delimiters other than "@" and with diferent strings, to no avail. exten => _.,1,Cut(BAR=bob@nowhere.com|@|1) exten => _.,2,NoOp(${BAR}) -- Executing Cut("SIP/2203-c027", "BAR=bob@nowhere.com|@|1") in new stack -- Executing NoOp("SIP/2203-c027", "") in new stack By: Tilghman Lesher (tilghman) 2003-10-07 20:39:24 Unfortunately, your usage will not work. I wrote this with the idea that a variable value might have a ',' or a '|' embedded, screwing up the parsing of the rest of the arguments, so here's how you use this: exten => 3,1,Cut(mychan=CHANNEL,,1) exten => 3,2,NoOp(${mychan}) or, for your example: exten => 3,1,SetVar(email=bob@nowhere.com) exten => 3,2,Cut(name=email,@,1) exten => 3,3,NoOp(${name}) I know that's an extra step, but I think the reason for doing this is well worth the extra effort. By: John Todd (jtodd) 2003-10-07 21:54:26 OK, the syntax still throws me a bit (the absence of ${} around "name" in your example) but it does work as shown, and I understand the reasoning for it being like that. Thanks! By: Tilghman Lesher (tilghman) 2003-10-10 02:10:25 Second version just uploaded; now includes the ability to specify more than one field, just like the cut(1) Unix application. Instead of using the , (comma) to separate groups of fields, however, app_cut uses & (ampersand) to separate groups of fields. Also supports ranges and the ability to leave off an end to a range, e.g. 2- means all fields after the first, and -2 means the first two fields. By: John Todd (jtodd) 2003-10-19 20:00:13 Tested, and has worked fine for several days with different iterations. By: Mark Spencer (markster) 2003-10-21 22:17:22 app_cut.c: In function `cut_exec': app_cut.c:134: warning: comparison between pointer and integer app_cut.c:146: warning: comparison between pointer and integer app_cut.c:54: warning: `newvar' might be used uninitialized in this function app_cut.c:54: warning: `varname' might be used uninitialized in this function app_cut.c:54: warning: `delimiter' might be used uninitialized in this function gcc -shared -Xlinker -x -o app_cut.so app_cut.o These need to be resolved first. By: Tilghman Lesher (tilghman) 2003-10-21 23:05:41 Requested changes made. By: Mark Spencer (markster) 2003-10-22 08:09:10 Added to CVS |