139 lines
3.0 KiB
C
139 lines
3.0 KiB
C
#include "../lpc_incl.h"
|
|
#include "../file_incl.h"
|
|
#include "../network_incl.h"
|
|
#include "../socket_efuns.h"
|
|
#include "../include/socket_err.h"
|
|
#include "../main.h"
|
|
|
|
char *external_cmd[NUM_EXTERNAL_CMDS];
|
|
|
|
#ifdef F_EXTERNAL_START
|
|
int external_start (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]);
|
|
for(i=0; i<5; i++)
|
|
if(external_port[i].port)
|
|
close(external_port[i].fd); //close external ports
|
|
dup2(sv[1], 0);
|
|
dup2(sv[1], 1);
|
|
dup2(sv[1], 2);
|
|
execv(cmd, argv);
|
|
exit(0);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void f_external_start (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
|