Esempio n. 1
0
/* This function is called by handle_connection_fd_event when there is input
 * available on the connection socket.
 */
void
hub_input_available(void)
{
    int start = 0;
    int c;
    int res;

    res = byteq_read(hub_recvq, hub_socket);
    if (res == 0 || (res < 0 && errno != EAGAIN)) {
        warn_socket_error(res, false, _("hub"));
        hub_disconnect();
        return;
    }

    for (c = hub_recvq_last; c < hub_recvq->cur; c++) {
        if (hub_recvq->buf[c] == '|') {
            /* Got a complete command. */
            if (c - start > 0)
                dump_command(_("<--"), hub_recvq->buf + start, c - start + 1);
            hub_recvq->buf[c] = '\0'; /* Just to be on the safe side... */
            hub_handle_command(hub_recvq->buf + start, c - start);
            start = c+1;
            if (hub_socket < 0)
                return;
        }
    }

    if (start != 0)
        byteq_remove(hub_recvq, start);

    hub_recvq_last = hub_recvq->cur;

    update_hub_activity();
}
Esempio n. 2
0
/* Put some data onto the connection, printf style.
 */
bool
hub_putf(const char *format, ...)
{
    va_list args;
    size_t oldcur;
    int res;

    oldcur = hub_sendq->cur;
    va_start(args, format);
    res = byteq_vappendf(hub_sendq, format, args);
    va_end(args);

    if (res < 0) {
        warn(_("Cannot append to hub send queue - %s\n"), errstr);
        hub_disconnect();
        return false;
    }

    dump_command(_("-->"), hub_sendq->buf+oldcur, hub_sendq->cur-oldcur);

    res = byteq_write(hub_sendq, hub_socket);
    if (res == 0 || (res < 0 && errno != EAGAIN)) {
        warn_socket_error(res, true, _("hub"));
        hub_disconnect();
        return false;
    }

    if (oldcur == 0 && hub_sendq->cur > 0)
        FD_SET(hub_socket, &write_fds);

    update_hub_activity();

    return true;
}
Esempio n. 3
0
static void
search_now_writable(void)
{
    while (search_udpmsg_out->cur > 0) {
        DCUDPMessage *msg = (DCUDPMessage*) search_udpmsg_out->buf[0];
        int res;

        /* <Erwin> I don't think you can send off half a UDP packet, no.
         * Therefore we don't attempt to use non-blocking I/O on search_socket.
        */
        dump_command(_("==>"), msg->data, msg->len);

        res = sendto(search_socket, msg->data, msg->len, 0, (struct sockaddr *) &msg->addr, sizeof(struct sockaddr_in));
        if (res == 0 || (res < 0 && errno != EAGAIN))
            warn_socket_error(res, true, _("user (search result)"));
        if (res < 0 && errno == EAGAIN)
            break;

        ptrv_remove_first(search_udpmsg_out);
        free(msg);
    }

    FD_CLR(search_socket, &write_fds);
}
Esempio n. 4
0
static void
search_input_available(void)
{
    struct sockaddr_in addr;
    socklen_t addrlen;
    int res;

    /* UDP socket reads are atomic! We are also non-blocking because select told us
     * there was data available.
     *
     * We don't really keep the received address, so we don't need recvfrom here.
     */
    addrlen = sizeof(addr);
    res = byteq_recvfrom(search_recvq, search_socket, 0, (struct sockaddr *) &addr, &addrlen);
    if (res == 0 || (res < 0 && errno != EAGAIN)) {
        warn_socket_error(res, false, _("user (search result)"));
        return;
    }

    dump_command(_("<=="), search_recvq->buf, search_recvq->cur);
    search_recvq->buf[search_recvq->cur-1] = '\0'; /* not strictly necessary */
    handle_search_result(search_recvq->buf, search_recvq->cur);
    byteq_clear(search_recvq);
}
Esempio n. 5
0
static int get_names(const char *server, struct rfs_list **names, enum rfs_commands cmd_id)
{
	if (*names != NULL)
	{
		destroy_list(names);
	}

	int sock = nss_connect(server);
	if (sock < 0)
	{
		return sock;
	}

	int saved_errno = 0;

	struct rfs_command cmd = { cmd_id, 0 };
	struct rfs_answer ans = { 0 };

#ifdef RFS_DEBUG
	dump_command(&cmd);
#endif

	if (send(sock, &cmd, sizeof(cmd), 0) != sizeof(cmd))
	{
		saved_errno = errno;
		goto error;
	}

	do
	{
		if (recv(sock, &ans, sizeof(ans), 0) != sizeof(ans))
		{
			saved_errno = errno;
			goto error;
		}

#ifdef RFS_DEBUG
		dump_answer(&ans);
#endif

		if (ans.command != cmd_id)
		{
			saved_errno = EINVAL;
			goto error;
		}

		if (ans.data_len > 0)
		{
			char *name = malloc(ans.data_len);

			if (recv(sock, name, ans.data_len, 0) != ans.data_len)
			{
				saved_errno = errno;
				goto error;
			}

			if (add_to_list(names, name) == NULL)
			{
				saved_errno = EIO;
				goto error;
			}
		}
	}
	while (ans.data_len != 0
	&& ans.ret_errno == 0);

	goto success;

error:
	destroy_list(names);

success:
	shutdown(sock, SHUT_RDWR);
	close(sock);

	return saved_errno;
}
Esempio n. 6
0
static int check_name(const char *full_name, enum rfs_commands cmd_id)
{
	char *server = extract_server(full_name);
	if (server == NULL)
	{
		return -EINVAL;
	}

	int sock = nss_connect(server);
	if (sock < 0)
	{
		free(server);
		return sock;
	}

	free(server);

	int saved_errno = 0;

	char *name = extract_name(full_name);

	size_t overall_size = 0;
	struct rfs_command cmd = { 0 };
	struct rfs_answer ans = { 0 };

	if (name == NULL)
	{
		saved_errno = -EINVAL;
		goto error;
	}

	overall_size = strlen(name) + 1;
	cmd.command = cmd_id;
	cmd.data_len = overall_size;

#ifdef RFS_DEBUG
	dump_command(&cmd);
#endif

	if (send(sock, &cmd, sizeof(cmd), 0) != sizeof(cmd))
	{
		saved_errno = errno;
		free(name);
		goto error;
	}

	DEBUG("sending name: %s\n", name);

	if (send(sock, name, overall_size, 0) != overall_size)
	{
		saved_errno = errno;
		free(name);
		goto error;
	}

	free(name);

	if (recv(sock, &ans, sizeof(ans), 0) != sizeof(ans))
	{
		saved_errno = errno;
		goto error;
	}

#ifdef RFS_DEBUG
	dump_answer(&ans);
#endif

	if (ans.command != cmd_id)
	{
		saved_errno = EINVAL;
		goto error;
	}

	saved_errno = ans.ret_errno;

error:
	shutdown(sock, SHUT_RDWR);
	close(sock);

	return -saved_errno;

}