fluffos-1.22/
fluffos-1.22/Win32/
fluffos-1.22/compat/
fluffos-1.22/testsuite/
fluffos-1.22/testsuite/clone/
fluffos-1.22/testsuite/command/
fluffos-1.22/testsuite/data/
fluffos-1.22/testsuite/etc/
fluffos-1.22/testsuite/include/
fluffos-1.22/testsuite/inherit/
fluffos-1.22/testsuite/inherit/master/
fluffos-1.22/testsuite/log/
fluffos-1.22/testsuite/single/
fluffos-1.22/testsuite/single/tests/compiler/
fluffos-1.22/testsuite/single/tests/efuns/
fluffos-1.22/testsuite/single/tests/operators/
fluffos-1.22/testsuite/u/
fluffos-1.22/tmp/
#include "../lpc_incl.h"
#include "../file_incl.h"
#include "../network_incl.h"
#include "../socket_efuns.h"
#include "../include/socket_err.h"

char *external_cmd[NUM_EXTERNAL_CMDS];

#ifdef F_EXTERNAL_START
int external_start P5(int, which, svalue_t *, args,
                      svalue_t *, arg1, svalue_t *, arg2, svalue_t *, arg3) {
    int sv[2];
    char *cmd;
    int fd;
    char **argv;
    pid_t ret;
    
    if (--which < 0 || which > (NUM_EXTERNAL_CMDS-1) || !external_cmd[which])
        error("Bad argument 1 to external_start()\n");
    cmd = external_cmd[which];
    fd = find_new_socket();
    if (fd < 0) return fd;
    
    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
        return EESOCKET;
 
    ret = fork();
    if (ret == -1) {
        error("fork() in external_start() failed: %s\n", strerror(errno));
    }
    if (ret) {
        close(sv[1]);
        lpc_socks[fd].fd = sv[0];
        lpc_socks[fd].flags = S_EXTERNAL;
        set_read_callback(fd, arg1);
        set_write_callback(fd, arg2);
        set_close_callback(fd, arg3);
        lpc_socks[fd].owner_ob = current_object;
        lpc_socks[fd].mode = STREAM;
        lpc_socks[fd].state = STATE_DATA_XFER;
        memset((char *) &lpc_socks[fd].l_addr, 0, sizeof(lpc_socks[fd].l_addr));
        memset((char *) &lpc_socks[fd].r_addr, 0, sizeof(lpc_socks[fd].r_addr));
        lpc_socks[fd].owner_ob = current_object;
        lpc_socks[fd].release_ob = NULL;
        lpc_socks[fd].r_buf = NULL;
        lpc_socks[fd].r_off = 0;
        lpc_socks[fd].r_len = 0;
        lpc_socks[fd].w_buf = NULL;
        lpc_socks[fd].w_off = 0;
        lpc_socks[fd].w_len = 0;

        current_object->flags |= O_EFUN_SOCKET;
        return fd;
    } else {
        int flag = 1;
        int i = 1;
        int n = 1;
        const char *p;
	char *arg;
        
        if (args->type == T_ARRAY) {
            n = args->u.arr->size;
        } else {
            p = args->u.string;
            
            while (*p) {
                if (isspace(*p)) {
                    flag = 1;
                } else {
                    if (flag) {
                        n++;
                        flag = 0;
                    }
                }
                p++;
            }
        }

        argv = CALLOCATE(n, char *, TAG_TEMPORARY, "external args");

        argv[0] = cmd;

        /* need writable version */
        if (args->type == T_ARRAY) {
            int j;
            svalue_t *sv = args->u.arr->item;
            
            for (j = 0; j < n; j++) {
                argv[i++] = alloc_cstring(sv[j].u.string, "external args");
            }
        } else {
            flag = 1;
            arg = alloc_cstring(args->u.string, "external args");
            while (*arg) {
                if (isspace(*arg)) {
                    *arg = 0;
                    flag = 1;
                } else {
                    if (flag) {
                        argv[i++] = arg;
                        flag = 0;
                    }
                }
                arg++;
            }
        }
        argv[i] = 0;
        
        close(sv[0]);
        dup2(sv[1], 0);
        dup2(sv[1], 1);
        dup2(sv[1], 2);
        execv(cmd, argv);
        exit(0);
        return 0;
    }
}

void f_external_start PROT((void))
{
    int fd, num_arg = st_num_arg;
    svalue_t *arg = sp - num_arg + 1;
    
    if (check_valid_socket("external", -1, current_object, "N/A", -1)) {
        fd = external_start(arg[0].u.number, arg + 1,
                            arg + 2, arg + 3, (num_arg == 5 ? arg + 4 : 0));
        pop_n_elems(num_arg - 1);
        sp->u.number = fd;
    } else {
        pop_n_elems(num_arg - 1);
        sp->u.number = EESECURITY;
    }
}
#endif