Ejemplo n.º 1
0
void f_thread() {

	int sv[2];
	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 debug() 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, sp-3);
        set_write_callback(fd, sp-2);
        set_close_callback(fd, sp-1);
        lpc_socks[fd].owner_ob = current_object;
        lpc_socks[fd].mode = MUD;
        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;
	}
	close(sv[0]);
	function_to_call_t cb;
	memset(&cb, 0, sizeof(function_to_call_t));
	process_efun_callback(0, &cb, F_THREAD);
	for(i=0; i<5; i++)
	  if(external_port[i].port)
	    close(external_port[i].fd); //close external ports
	for(i=0;i<sizeof(lpc_socks)/sizeof(lpc_socks[0]);i++)
		close(lpc_sock[i].fd);
	svalue_t *res = call_efun_callback(&cb, 1);
	switch (res->type) {

	        case T_OBJECT:
	            break;
	        default:
	            save_svalue_depth = 0;
	            int len = svalue_save_size(message);
	            if (save_svalue_depth > MAX_SAVE_SVALUE_DEPTH) {
	            	OS_socket_write(sv[1], "\x00\x00\x00\x11\"result too big\"", 21);
	            	break;
	            }
	            char *buf = (char *)
	                DMALLOC(len + 5, TAG_TEMPORARY, "socket_write: default");
	            if (buf == NULL)
	                break;
	            *(INT_32 *) buf = htonl((long) len);
	            len += 4;
	            buf[4] = '\0';
	            p = buf + 4;
	            save_svalue(message, &p);
	            int ret,written = 0;
	            while(written < len){
	            	ret = OS_socket_write(sv[1], buf+written, len-written);
	            	if(ret < 0)
	            		break;
	            	written += ret;
	            }
	            break;
	        }
	fflush(0);
	exit(0);
}
Ejemplo n.º 2
0
/*
 * Create an LPC efun socket
 */
int socket_create (enum socket_mode mode, svalue_t * read_callback, svalue_t * close_callback)
{
    int type, i, fd, optval;
#ifndef NO_BUFFER_TYPE
    int binary = 0;

    if (mode == STREAM_BINARY) {
        binary = 1;
        mode = STREAM;
    } else if (mode == DATAGRAM_BINARY) {
        binary = 1;
        mode = DATAGRAM;
    }
#endif
    switch (mode) {

        case MUD:
        case STREAM:
            type = SOCK_STREAM;
            break;
        case DATAGRAM:
            type = SOCK_DGRAM;
            break;

        default:
            return EEMODENOTSUPP;
    }

    i = find_new_socket();
    if (i >= 0) {
#ifdef IPV6
        fd = socket(PF_INET6, type, 0);
#else
        fd = socket(PF_INET, type, 0);
#endif
        if (fd == INVALID_SOCKET) {
            socket_perror("socket_create: socket", 0);
            return EESOCKET;
        }
        optval = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &optval,
                    sizeof(optval)) == -1) {
            socket_perror("socket_create: setsockopt", 0);
            OS_socket_close(fd);
            return EESETSOCKOPT;
        }
        if (set_socket_nonblocking(fd, 1) == -1) {
            socket_perror("socket_create: set_socket_nonblocking", 0);
            OS_socket_close(fd);
            return EENONBLOCK;
        }
        lpc_socks[i].fd = fd;
        lpc_socks[i].flags = S_HEADER;

        if (type == SOCK_DGRAM) close_callback = 0;
        set_read_callback(i, read_callback);
        set_write_callback(i, 0);
        set_close_callback(i, close_callback);

#ifndef NO_BUFFER_TYPE
        if (binary) {
            lpc_socks[i].flags |= S_BINARY;
        }
#endif
        lpc_socks[i].mode = mode;
        lpc_socks[i].state = STATE_UNBOUND;
        memset((char *) &lpc_socks[i].l_addr, 0, sizeof(lpc_socks[i].l_addr));
        memset((char *) &lpc_socks[i].r_addr, 0, sizeof(lpc_socks[i].r_addr));
        lpc_socks[i].owner_ob = current_object;
        lpc_socks[i].release_ob = NULL;
        lpc_socks[i].r_buf = NULL;
        lpc_socks[i].r_off = 0;
        lpc_socks[i].r_len = 0;
        lpc_socks[i].w_buf = NULL;
        lpc_socks[i].w_off = 0;
        lpc_socks[i].w_len = 0;

        current_object->flags |= O_EFUN_SOCKET;

        debug(sockets, ("socket_create: created socket %d mode %d fd %d\n",
                    i, mode, fd));
    }

    return i;
}
Ejemplo n.º 3
0
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;
	}
}