don't execve() a shell process but always double-fork and then exec the program directly
[lcr.git] / action.cpp
index bf7c23d..352efb4 100644 (file)
@@ -111,6 +111,8 @@ void EndpointAppPBX::action_dialing_internal(void)
                        capainfo.bearer_mode = INFO_BMODE_PACKET;
                }
                capainfo.bearer_info1 = INFO_INFO1_NONE;
+               capainfo.hlc = INFO_HLC_NONE;
+               capainfo.exthlc = INFO_HLC_NONE;
        }
        if ((rparam = routeparam(e_action, PARAM_BMODE))) {
                capainfo.bearer_mode = rparam->integer_value;
@@ -135,7 +137,7 @@ void EndpointAppPBX::action_dialing_internal(void)
                trace_header("ACTION extension (extension doesn't exist)", DIRECTION_NONE);
                add_trace("extension", NULL, dialinginfo.id);
                end_trace();
-               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0);
+               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0, 0);
                new_state(EPOINT_STATE_OUT_DISCONNECT);
                message_disconnect_port(portlist, CAUSE_UNALLOCATED, LOCATION_PRIVATE_LOCAL, "");
                set_tone(portlist, "cause_86");
@@ -147,7 +149,7 @@ void EndpointAppPBX::action_dialing_internal(void)
                add_trace("extension", NULL, dialinginfo.id);
                end_trace();
                new_state(EPOINT_STATE_OUT_DISCONNECT);
-               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0);
+               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0, 0);
                message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
                set_tone(portlist, "cause_81");
                return;
@@ -206,7 +208,7 @@ void EndpointAppPBX::action_dialing_external(void)
        memcpy(&redirinfo, &e_redirinfo, sizeof(redirinfo));
        memset(&dialinginfo, 0, sizeof(dialinginfo));
        dialinginfo.itype = INFO_ITYPE_ISDN;
-       dialinginfo.sending_complete = 0;
+//     dialinginfo.sending_complete = 0;
        SCPY(dialinginfo.id, e_extdialing);
 
        /* process prefix */
@@ -221,8 +223,6 @@ void EndpointAppPBX::action_dialing_external(void)
 
        /* process number complete */
        if ((rparam = routeparam(e_action, PARAM_COMPLETE)))
-               if ((rparam = routeparam(e_action, PARAM_PREFIX)))
-                       SCPY(dialinginfo.id, rparam->string_value);
                dialinginfo.sending_complete = 1;
 
        /* process number type */
@@ -237,6 +237,8 @@ void EndpointAppPBX::action_dialing_external(void)
                        capainfo.bearer_mode = INFO_BMODE_PACKET;
                }
                capainfo.bearer_info1 = INFO_INFO1_NONE;
+               capainfo.hlc = INFO_HLC_NONE;
+               capainfo.exthlc = INFO_HLC_NONE;
        }
        if ((rparam = routeparam(e_action, PARAM_BMODE))) {
                capainfo.bearer_mode = rparam->integer_value;
@@ -273,7 +275,7 @@ void EndpointAppPBX::action_dialing_external(void)
        if (e_ext.rights < 2) {
                trace_header("ACTION extern (calling denied)", DIRECTION_NONE);
                end_trace();
-               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0);
+               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0, 0);
                set_tone(portlist, "cause_82");
                denied:
                message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
@@ -288,7 +290,7 @@ void EndpointAppPBX::action_dialing_external(void)
                if (e_ext.rights < 3) {
                        trace_header("ACTION extern (national calls denied)", DIRECTION_NONE);
                        end_trace();
-                       release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0);
+                       release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0, 0);
                        set_tone(portlist, "cause_83");
                        goto denied;
                }
@@ -300,7 +302,7 @@ void EndpointAppPBX::action_dialing_external(void)
                if (e_ext.rights < 4) {
                        trace_header("ACTION extern (international calls denied)", DIRECTION_NONE);
                        end_trace();
-                       release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0);
+                       release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0, 0);
                        set_tone(portlist, "cause_84");
                        goto denied;
                }
@@ -309,6 +311,8 @@ void EndpointAppPBX::action_dialing_external(void)
        /* add or update outgoing call */
        trace_header("ACTION extern (calling)", DIRECTION_NONE);
        add_trace("number", NULL, dialinginfo.id);
+       if (dialinginfo.sending_complete)
+       add_trace("number", "complete", "yes");
        if (dialinginfo.interfaces[0])
                add_trace("interfaces", NULL, dialinginfo.interfaces);
        end_trace();
@@ -1781,6 +1785,48 @@ void EndpointAppPBX::action_dialing_disconnect(void)
 
 
 /*
+ * process dialing release
+ */
+void EndpointAppPBX::action_dialing_release(void)
+{
+       struct route_param *rparam;
+       int cause = CAUSE_NORMAL; /* normal call clearing */
+       int location = LOCATION_PRIVATE_LOCAL;
+       char cause_string[256] = "", display[84] = "";
+
+       /* check cause parameter */
+       if ((rparam = routeparam(e_action, PARAM_CAUSE))) {
+               cause = rparam->integer_value;
+               PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'cause' is given: %d\n", ea_endpoint->ep_serial, cause);
+       }
+       if ((rparam = routeparam(e_action, PARAM_LOCATION))) {
+               location = rparam->integer_value;
+               PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'location' is given: %d\n", ea_endpoint->ep_serial, location);
+       }
+
+
+       /* use cause as sample, if not given later */
+       SPRINT(cause_string, "cause_%02x", cause);
+
+       /* check display */
+       if ((rparam = routeparam(e_action, PARAM_DISPLAY))) {
+               SCPY(display, rparam->string_value);
+               PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'display' is given: %s\n", ea_endpoint->ep_serial, display);
+       }
+
+       /* disconnect only if connect parameter is not given */
+       trace_header("ACTION release", DIRECTION_NONE);
+       add_trace("cause", "value", "%d", cause);
+       add_trace("cause", "location", "%d", location);
+       if (display[0])
+               add_trace("display", NULL, "%s", display);
+       end_trace();
+       e_action = NULL;
+       release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, location, cause, 1);
+       return;
+}
+
+/*
  * process dialing help
  */
 void EndpointAppPBX::action_dialing_help(void)
@@ -1919,7 +1965,7 @@ void EndpointAppPBX::action_execute(void)
        int iWaitStatus;
        char *command = (char *)"";
        char isdn_port[10];
-       char *argv[11]; /* check also number of args below */
+       char *argv[12]; /* check also number of args below */
        int i = 0;
 
        /* get script / command */
@@ -1930,9 +1976,11 @@ void EndpointAppPBX::action_execute(void)
                end_trace();
                return;
        }
+#if 0
        argv[i++] = (char *)"/bin/sh";
        argv[i++] = (char *)"-c";
        argv[i++] = command;
+#endif
        argv[i++] = command;
        if ((rparam = routeparam(e_action, PARAM_PARAM))) {
                argv[i++] = rparam->string_value;
@@ -1943,6 +1991,7 @@ void EndpointAppPBX::action_execute(void)
        argv[i++] = e_callerinfo.name;
        SPRINT(isdn_port, "%d", e_callerinfo.isdn_port);
        argv[i++] = isdn_port;
+       argv[i++] = e_callerinfo.imsi;
        argv[i++] = NULL; /* check also number of args above */
        switch (pid = fork ()) {
                case -1:
@@ -1952,7 +2001,7 @@ void EndpointAppPBX::action_execute(void)
                case 0:
                        /* To be shure there are no zombies created double fork */
                        if ((pid2 = fork()) == 0) {
-                               execve("/bin/sh", argv, environ);
+                               execve(command, argv, environ);
                        }
                        else {
                                /* Exit immediately and release the waiting parent. The subprocess falls to init because the parent died */
@@ -2148,10 +2197,10 @@ void EndpointAppPBX::process_dialing(int timeout)
                if (e_action->index == ACTION_DISCONNECT
                 || e_state == EPOINT_STATE_OUT_DISCONNECT) {
                        /* release after disconnect */
-                       release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+                       release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
                        goto end;
                }
-               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0);
+               release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0, 0);
                e_action = e_action->next;
                if (!e_action) {
                        /* nothing more, so we release */