dsIIr4/bin/
dsIIr4/extra/creremote/
dsIIr4/extra/wolfpaw/
dsIIr4/lib/cmds/admins/
dsIIr4/lib/cmds/common/
dsIIr4/lib/cmds/creators/include/
dsIIr4/lib/cmds/creators/include/SCCS/
dsIIr4/lib/daemon/services/
dsIIr4/lib/doc/
dsIIr4/lib/domains/Ylsrim/
dsIIr4/lib/domains/Ylsrim/adm/
dsIIr4/lib/domains/Ylsrim/armor/
dsIIr4/lib/domains/Ylsrim/broken/
dsIIr4/lib/domains/Ylsrim/fish/
dsIIr4/lib/domains/Ylsrim/meal/
dsIIr4/lib/domains/Ylsrim/npc/
dsIIr4/lib/domains/Ylsrim/virtual/
dsIIr4/lib/domains/Ylsrim/weapon/
dsIIr4/lib/domains/campus/adm/
dsIIr4/lib/domains/campus/etc/
dsIIr4/lib/domains/campus/meals/
dsIIr4/lib/domains/campus/npc/
dsIIr4/lib/domains/campus/save/
dsIIr4/lib/domains/campus/txt/
dsIIr4/lib/domains/campus/txt/ai/charles/
dsIIr4/lib/domains/campus/txt/ai/charles/bak2/
dsIIr4/lib/domains/campus/txt/ai/charles/bak2/bak1/
dsIIr4/lib/domains/campus/txt/ai/charly/
dsIIr4/lib/domains/campus/txt/ai/charly/bak/
dsIIr4/lib/domains/campus/txt/jenny/
dsIIr4/lib/domains/default/creator/
dsIIr4/lib/domains/default/doors/
dsIIr4/lib/domains/default/etc/
dsIIr4/lib/domains/default/virtual/
dsIIr4/lib/domains/default/weap/
dsIIr4/lib/domains/town/virtual/
dsIIr4/lib/lib/comp/
dsIIr4/lib/lib/lvs/
dsIIr4/lib/lib/user/
dsIIr4/lib/lib/virtual/
dsIIr4/lib/log/
dsIIr4/lib/obj/book_source/
dsIIr4/lib/obj/include/
dsIIr4/lib/realms/template/
dsIIr4/lib/realms/template/adm/
dsIIr4/lib/realms/template/area/armor/
dsIIr4/lib/realms/template/area/npc/
dsIIr4/lib/realms/template/area/obj/
dsIIr4/lib/realms/template/area/room/
dsIIr4/lib/realms/template/area/weap/
dsIIr4/lib/realms/template/bak/
dsIIr4/lib/realms/template/cmds/
dsIIr4/lib/save/
dsIIr4/lib/save/kills/o/
dsIIr4/lib/secure/cfg/classes/
dsIIr4/lib/secure/cmds/creators/include/
dsIIr4/lib/secure/cmds/players/
dsIIr4/lib/secure/cmds/players/include/
dsIIr4/lib/secure/daemon/include/
dsIIr4/lib/secure/lib/
dsIIr4/lib/secure/lib/include/
dsIIr4/lib/secure/lib/net/include/
dsIIr4/lib/secure/lib/std/
dsIIr4/lib/secure/modules/
dsIIr4/lib/secure/npc/
dsIIr4/lib/secure/obj/include/
dsIIr4/lib/secure/room/
dsIIr4/lib/secure/save/
dsIIr4/lib/secure/save/boards/
dsIIr4/lib/secure/save/players/g/
dsIIr4/lib/secure/tmp/
dsIIr4/lib/secure/verbs/creators/
dsIIr4/lib/shadows/
dsIIr4/lib/spells/
dsIIr4/lib/std/board/
dsIIr4/lib/std/lib/
dsIIr4/lib/tmp/
dsIIr4/lib/verbs/admins/include/
dsIIr4/lib/verbs/common/
dsIIr4/lib/verbs/common/include/
dsIIr4/lib/verbs/creators/include/
dsIIr4/lib/verbs/players/include/SCCS/
dsIIr4/lib/verbs/rooms/
dsIIr4/lib/verbs/rooms/include/
dsIIr4/lib/www/
dsIIr4/v22.2b14-dsouls2/
dsIIr4/v22.2b14-dsouls2/ChangeLog.old/
dsIIr4/v22.2b14-dsouls2/Win32/
dsIIr4/v22.2b14-dsouls2/compat/
dsIIr4/v22.2b14-dsouls2/compat/simuls/
dsIIr4/v22.2b14-dsouls2/include/
dsIIr4/v22.2b14-dsouls2/mudlib/
dsIIr4/v22.2b14-dsouls2/testsuite/
dsIIr4/v22.2b14-dsouls2/testsuite/clone/
dsIIr4/v22.2b14-dsouls2/testsuite/command/
dsIIr4/v22.2b14-dsouls2/testsuite/data/
dsIIr4/v22.2b14-dsouls2/testsuite/etc/
dsIIr4/v22.2b14-dsouls2/testsuite/include/
dsIIr4/v22.2b14-dsouls2/testsuite/inherit/
dsIIr4/v22.2b14-dsouls2/testsuite/inherit/master/
dsIIr4/v22.2b14-dsouls2/testsuite/log/
dsIIr4/v22.2b14-dsouls2/testsuite/single/
dsIIr4/v22.2b14-dsouls2/testsuite/single/tests/compiler/
dsIIr4/v22.2b14-dsouls2/testsuite/single/tests/efuns/
dsIIr4/v22.2b14-dsouls2/testsuite/single/tests/operators/
dsIIr4/v22.2b14-dsouls2/testsuite/u/
dsIIr4/v22.2b14-dsouls2/tmp/
dsIIr4/win32/
#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;
	char *p, *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);
	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