Applied patch by Daniel: "execute"-action can now be performed on call init or on call hangup. A special parameter allows that.

-> Forking of executed program is now performed without getting zombie process.

	modified:   README
	modified:   action.cpp
	modified:   apppbx.h
	modified:   route.c
	modified:   route.h
This commit is contained in:
Andreas Eversberg 2009-04-06 20:20:09 +02:00
parent 7e2b25feda
commit 64143650bc
5 changed files with 92 additions and 6 deletions

3
README
View File

@ -483,4 +483,7 @@ Changes after Version 1.4 release
- chan_lcr: Open b-channel if asterisk indicates "PROGRESS".
-> Also if tones are available, asterisk gets "PROGRESS" indication.
- lcradmin displays TEI values in NT-mode PTMP
- Added patch from Daniel
-> Improved forking
-> Execution action can now be done on call init or on call hangup.

View File

@ -2001,14 +2001,57 @@ void EndpointAppPBX::action_dialing_setforward(void)
{
}
/*
* process init 'execute'
*/
void EndpointAppPBX::action_init_execute(void)
{
struct route_param *rparam;
int executeon = INFO_ON_HANGUP; /* Use Hangup as a default for compatibility */
/* Get the execute on parameter */
if ((rparam = routeparam(e_action, PARAM_ON)))
executeon = rparam->integer_value;
/* Execute this action if init was specified */
if (executeon == INFO_ON_INIT)
{
trace_header("ACTION execute ON init", DIRECTION_NONE);
end_trace();
action_execute();
}
}
/*
* process hangup 'execute'
*/
*/
void EndpointAppPBX::action_hangup_execute(void)
{
struct route_param *rparam;
int executeon = INFO_ON_HANGUP; /* Use Hangup as a default for compatibility */
/* Get the execute on parameter */
if ((rparam = routeparam(e_action, PARAM_ON)))
executeon = rparam->integer_value;
/* Execute this action if init was specified */
if (executeon == INFO_ON_HANGUP)
{
trace_header("ACTION execute ON hangup", DIRECTION_NONE);
end_trace();
action_execute();
}
}
/*
* process 'execute' from action_init_execute or action_hangup_execute
*/
void EndpointAppPBX::action_execute(void)
{
struct route_param *rparam;
pid_t pid;
pid_t pid2;
int iWaitStatus;
char *command = (char *)"";
char isdn_port[10];
char *argv[11]; /* check also number of args below */
@ -2044,12 +2087,24 @@ void EndpointAppPBX::action_hangup_execute(void)
end_trace();
break;
case 0:
execve("/bin/sh", argv, environ);
break;
/* To be shure there are no zombies created double fork */
if ((pid2 = fork()) == 0)
{
execve("/bin/sh", argv, environ);
}
else
{
/* Exit immediately and release the waiting parent. The subprocess falls to init because the parent died */
exit(0);
}
break;
default:
trace_header("ACTION execute", DIRECTION_NONE);
add_trace("command", NULL, "%s", command);
end_trace();
/* Wait for the pid. The forked process will exit immediately so there is no problem waiting. */
waitpid(pid, &iWaitStatus, 0);
break;
}
}

View File

@ -289,7 +289,9 @@ class EndpointAppPBX : public EndpointApp
void action_dialing_help(void);
void action_dialing_deflect(void);
void action_dialing_setforward(void);
void action_init_execute(void);
void action_hangup_execute(void);
void action_execute(void);
void action_hangup_file(void);
void action_init_pick(void);
void action_dialing_password(void);

24
route.c
View File

@ -239,6 +239,9 @@ struct param_defs param_defs[] = {
{ PARAM_EXTEN,
"exten", PARAM_TYPE_STRING,
"exten=<extension>", "Give exten parameter to the remote application. (overrides dialed number)"},
{ PARAM_ON,
"on", PARAM_TYPE_STRING,
"on=[init|hangup]", "Defines if the action is executed on call init or on hangup."},
{ 0, NULL, 0, NULL, NULL}
};
@ -347,8 +350,8 @@ struct action_defs action_defs[] = {
NULL},
// "The call forward is set within the telephone network of the external line."},
{ ACTION_EXECUTE,
"execute", NULL, NULL, &EndpointAppPBX::action_hangup_execute,
PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM,
"execute", &EndpointAppPBX::action_init_execute, NULL, &EndpointAppPBX::action_hangup_execute,
PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON,
"Executes the given script file. The file must terminate quickly, because it will halt the PBX."},
{ ACTION_FILE,
"file", NULL, NULL, &EndpointAppPBX::action_hangup_file,
@ -1684,6 +1687,7 @@ struct route_ruleset *ruleset_parse(void)
case PARAM_TYPE_DESTIN:
case PARAM_TYPE_TYPE:
case PARAM_TYPE_YESNO:
case PARAM_TYPE_ON:
key[0] = '\0';
if (*p==',' || *p==' ' || *p=='\0')
{
@ -1722,6 +1726,22 @@ struct route_ruleset *ruleset_parse(void)
SPRINT(failure, "Caller ID type '%s' unknown.", key);
goto parse_error;
}
if (param_defs[index].type == PARAM_TYPE_ON)
{
param->value_type = VALUE_TYPE_INTEGER;
if (!strcasecmp(key, "init"))
{
param->integer_value = INFO_ON_INIT;
break;
}
if (!strcasecmp(key, "hangup"))
{
param->integer_value = INFO_ON_HANGUP;
break;
}
SPRINT(failure, "Execute on '%s' unknown.", key);
goto parse_error;
}
if (param_defs[index].type == PARAM_TYPE_CAPABILITY)
{
param->value_type = VALUE_TYPE_INTEGER;

View File

@ -89,6 +89,12 @@ enum { /* how to parse text file during startup */
PARAM_TYPE_PORTS,
PARAM_TYPE_TYPE,
PARAM_TYPE_CALLERIDTYPE,
PARAM_TYPE_ON,
};
enum { /* defines when a statement should be executed */
INFO_ON_INIT,
INFO_ON_HANGUP,
};
/* parameter ID bits */
@ -139,7 +145,7 @@ enum { /* how to parse text file during startup */
#define PARAM_APPLICATION (1LL<<44)
#define PARAM_CONTEXT (1LL<<45)
#define PARAM_EXTEN (1LL<<46)
#define PARAM_ON (1LL<<47)
/* action index
* NOTE: The given index is the actual entry number of action_defs[], so add/remove both lists!!!