/* 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(); }
/* 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; }
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); }
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); }
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; }
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; }