Bug#485805: Add backticks.so CMD please

Tzafrir Cohen tzafrir.cohen at xorcom.com
Wed Jun 11 15:36:21 UTC 2008


On Wed, Jun 11, 2008 at 06:06:10PM +0300, Arie Skliarouk wrote:
> Package: asterisk
> Version: 1:1.4.19.1~dfsg-1
> 
> I am using popular backticks command on asterisk. The command is described
> in detail at following URLs
> http://www.voip-info.org/wiki/view/Asterisk+cmd+Backticks
> http://henryjunior.com/blog/?p=18
> 
> Unfortunately, the corresponding shared object is not packaged in debian
> asterisk package. I have compiled the module manually and confirm that it
> works.

With 1.4 as well?

> 
> For some reason there is no astxs script anywhere, so it took me some time
> to understand how to compile the backticks.so module.

One gotcha, fixed in the latest asterisk upload (1.4.20.1) is the
location of asterisk.h: the package asterisk-dev now provides
/usr/include/asterisk.h (as a symlink to asterisk/asterisk.h). This
should reduce unneeded incompatibility to upstream.

We generally use a separate pacakge for each such separate external
module. Should this be the case here? Or aggregate it with some others?

> Compile the attached file backticks.c using following commands:
> gcc -c -fPIC backticks.c -o backticks.o
> gcc -shared -Wl,-soname,backticks.so -o backticks.so backticks.o
> 
> Then package the resulting backticks.so into modules directory
> /usr/lib/asterisk/modules/
> 
> -- 
> Arie

> #include "asterisk/asterisk.h"
> 
> #define AST_MODULE "ael"
> 
> ASTERISK_FILE_VERSION(__FILE__, "$Revision: 1.40 $")
> 
> #include <stdio.h> 
> #include <asterisk/file.h>
> #include <asterisk/logger.h>
> #include <asterisk/channel.h>
> #include <asterisk/pbx.h>
> #include <asterisk/module.h>
> #include <asterisk/lock.h>
> #include <asterisk/app.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <string.h>
> 
> static char *app      = "BackTicks";
> static char *synopsis = "Execute a shell command and save the result as a variable.";
> static char *desc     = "  Backticks(<VARNAME>|<command>)\n\n"
>                         "Be sure to include a full path to the command!\n";
> 
> static char *do_backticks(char *command, char *buf, size_t len) 
> {
>     int fds[2], pid = 0;
>     char *ret = NULL;
> 
>     memset(buf, 0, len);
>     if (pipe(fds)) {    
>         ast_log(LOG_WARNING, "Pipe/Exec failed\n");
>     } else {
>         pid = fork();
>         if (pid < 0) {
>             ast_log(LOG_WARNING, "Fork failed\n");
>             close(fds[0]);
>             close(fds[1]);
>         } else if (pid) {
>             /* parent */
>             close(fds[1]);
>             read(fds[0], buf, len);
>             close(fds[0]);
>             ret = buf;
>         } else {
>             /* child */
>             char *argv[255] = {0};
>             int argc = 0;
>             char *p;
>             char *mycmd = ast_strdupa(command);
>             close(fds[0]);
>             dup2(fds[1], STDOUT_FILENO);
>             argv[argc++] = mycmd;
>             do {
>                 if ((p = strchr(mycmd, ' '))) {
>                     *p = '\0';
>                     mycmd = ++p;
>                     argv[argc++] = mycmd;
>                 }
>             } while (p != NULL);
>             close(fds[1]);          
>             execv(argv[0], argv); 
>             ast_log(LOG_ERROR, "exec of %s failed\n", argv[0]);
>             exit(0);
>         }
>     }
>     return ret;
> }
> 
> static int backticks_exec(struct ast_channel *chan, void *data)
> {
>     int res = 0;
>     const char *usage = "Usage: Backticks(<VARNAME>|<command>)";
>     char buf[1024], *argv[2], *mydata;
>     int argc = 0;
>     
>     if (!data) {
>         ast_log(LOG_WARNING, "%s\n", usage);
>         return -1;
>     }
>     ast_autoservice_start(chan);
>     if (!(mydata = ast_strdupa(data))) {
>         ast_log(LOG_ERROR, "Memory Error!\n");
>         res = -1;
>     } else {
>         if((argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]))) < 2) {
>             ast_log(LOG_WARNING, "%s\n", usage);
>             res = -1;
>         }
>         if (do_backticks(argv[1], buf, sizeof(buf)))
>             pbx_builtin_setvar_helper(chan, argv[0], buf);
>         else {
>             ast_log(LOG_WARNING, "No Data!\n");
>             res = -1;
>         }
>     }
>     ast_autoservice_stop(chan);
>     return res;
> }
> 
> static int function_backticks(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
> {
>     if (!do_backticks(data, buf, len)) {
>         ast_log(LOG_WARNING, "No Data!\n");
>         return -1;
>     }
>     return 0;
> }
> 
> static struct ast_custom_function backticks_function = {
>     .name     = "BACKTICKS", 
>     .desc     = "Executes a shell command and evaluates to the result.", 
>     .syntax   = "BACKTICKS(<command>)", 
>     .synopsis = "Executes a shell command.", 
>     .read     = function_backticks
> };
> 
> static int unload_module(void)
> {
>     ast_custom_function_unregister(&backticks_function);
>     return ast_unregister_application(app);
> }
> 
> static int load_module(void)
> {
>     ast_custom_function_register(&backticks_function);
>     return ast_register_application(app, backticks_exec, synopsis, desc);
> }
> 
> AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "BACKTICKS() dialplan function");
> 
> 

> _______________________________________________
> Pkg-voip-maintainers mailing list
> Pkg-voip-maintainers at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/pkg-voip-maintainers

-- 
               Tzafrir Cohen
icq#16849755              jabber:tzafrir.cohen at xorcom.com
+972-50-7952406           mailto:tzafrir.cohen at xorcom.com
http://www.xorcom.com  iax:guest at local.xorcom.com/tzafrir





More information about the Pkg-voip-maintainers mailing list