/*
* process init 'internal' / 'external' / 'remote' / 'vbox-record' / 'partyline'...
*/
-void EndpointAppPBX::_action_init_call(char *remote)
+int EndpointAppPBX::_action_init_call(char *remote)
{
class Join *join;
struct port_list *portlist = ea_endpoint->ep_portlist;
{
if (options.deb & DEBUG_EPOINT)
PERROR("EPOINT(%d): We already have a call instance, this should never happen!\n", ea_endpoint->ep_serial);
- return;
+ return(0);
}
/* create join */
message_disconnect_port(portlist, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, "");
new_state(EPOINT_STATE_OUT_DISCONNECT);
set_tone(portlist,"cause_1b");
- return;
+ return(0);
}
join = new JoinRemote(ea_endpoint->ep_serial, remote, admin->sock);
}
if (!join)
FATAL("No memoy for Join instance.\n");
ea_endpoint->ep_join_id = join->j_serial;
+ return(1);
}
void EndpointAppPBX::action_init_call(void)
{
}
/* check if extension exists AND only if not multiple extensions */
- if (!read_extension(&ext, dialinginfo.id) && !strchr(dialinginfo.id,','))
+ if (!strchr(dialinginfo.id,',') && !read_extension(&ext, dialinginfo.id))
{
trace_header("ACTION extension (extension doesn't exist)", DIRECTION_NONE);
add_trace("extension", NULL, dialinginfo.id);
char context[128] = "";
char remote[32];
- if (e_state == EPOINT_STATE_IN_SETUP && !ea_endpoint->ep_join_id)
+ if (!ea_endpoint->ep_join_id)
{
/* no join yet, sending setup */
if (!(rparam = routeparam(e_action, PARAM_APPLICATION)))
return;
}
SCPY(remote, rparam->string_value);
- _action_init_call(remote);
+ if (!_action_init_call(remote))
+ return;
/* create bearer/caller/dialinginfo */
memcpy(&capainfo, &e_capainfo, sizeof(capainfo));
{
SCPY(dialinginfo.id, e_extdialing);
}
+ e_extdialing = e_dialinginfo.id + strlen(e_dialinginfo.id);
/* send setup to remote */
trace_header("ACTION remote (setup)", DIRECTION_NONE);
add_trace("number", NULL, dialinginfo.id);
{
/* find next entry */
e_select++;
- if (e_select >= MAX_REMEMBER)
+ if (e_select >= MAX_REMEMBER) {
e_select--;
- else if (in)
+ } else if (in) {
if (e_ext.last_in[e_select][0] == '\0')
e_select--;
- else
+ } else
if (e_ext.last_out[e_select][0] == '\0')
e_select--;
struct port_list *portlist = ea_endpoint->ep_portlist;
struct lcr_msg *message;
double value1, value2, v, sign1;
- int komma1, komma2, k, state, mode, first;
+ int komma1, komma2, k, state, mode = 0, first;
char *p;
portlist = ea_endpoint->ep_portlist;
{
}
+/*
+ * 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;
- char *command = "", isdn_port[10];
+ pid_t pid2;
+ int iWaitStatus;
+ char *command = (char *)"";
+ char isdn_port[10];
char *argv[11]; /* check also number of args below */
int i = 0;
end_trace();
return;
}
- argv[i++] = "/bin/sh";
- argv[i++] = "-c";
+ argv[i++] = (char *)"/bin/sh";
+ argv[i++] = (char *)"-c";
argv[i++] = command;
argv[i++] = command;
if ((rparam = routeparam(e_action, PARAM_PARAM)))
argv[i++] = rparam->string_value;
}
argv[i++] = e_extdialing;
- argv[i++] = numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international);
+ argv[i++] = (char *)numberrize_callerinfo(e_callerinfo.id, e_callerinfo.ntype, options.national, options.international);
argv[i++] = e_callerinfo.extension;
argv[i++] = e_callerinfo.name;
SPRINT(isdn_port, "%d", e_callerinfo.isdn_port);
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;
}
}
void EndpointAppPBX::action_hangup_file(void)
{
struct route_param *rparam;
- char *file, *content, *mode;
+ const char *file, *content, *mode;
FILE *fp;
/* get file / content */
//PDEBUG(~0, "HANG-BUG-DEBUGGING: before action-timeout processing\n");
/* process timeout */
- if (e_action_timeout)
+ if (e_action && e_action_timeout) /* e_action may be NULL, but e_action_timeout may still be set and must be ignored */
{
e_action_timeout = 0;
if (e_state == EPOINT_STATE_CONNECT)