/* * Handle the interaction with the client. Takes the client file descriptor, * the server configuration, and the server credentials. Establishes a * security context, processes requests from the client, checks the ACL file * as appropriate, and then spawns commands, sending the output back to the * client. This function only returns when the client connection has * completed, either successfully or unsuccessfully. */ static void server_handle_connection(int fd, struct config *config, gss_cred_id_t creds) { struct client *client; /* Establish a context with the client. */ client = server_new_client(fd, creds); if (client == NULL) { close(fd); return; } debug("accepted connection from %s (protocol %d)", client->user, client->protocol); /* * Now, we process incoming commands. This is handled differently * depending on the protocol version. These functions won't exit until * the client is done sending commands and we're done replying. */ if (client->protocol == 1) server_v1_handle_messages(client, config); else server_v2_handle_messages(client, config); /* We're done; shut down the client connection. */ server_free_client(client); }
static int server_select(t_server *server, int *actual) { char buff[BUF_SIZE + 1]; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1; if (select(server->max + 1, &server->rdfs, NULL, NULL, &tv) == -1) exit_error("select"); else if (FD_ISSET(server->sock, &server->rdfs)) { if (server_new_client(server, actual, buff)) return (1); } else if (FD_ISSET(server->gfxsock, &server->rdfs)) { if (new_gfxclient(server, buff) == -1) { server->gfx.sock = 0; return (1); } } else client_talking(server, actual, buff); return (0); }