static void client_close(struct client *client) { assert(num_clients > 0); assert(clients != NULL); clients = g_list_remove(clients, client); --num_clients; client_set_expired(client); if (client->cmd_list) { free_cmd_list(client->cmd_list); client->cmd_list = NULL; } g_queue_foreach(client->deferred_send, deferred_buffer_free, NULL); g_queue_free(client->deferred_send); g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE, "[%u] closed", client->num); g_free(client); }
void client_close(struct client *client) { client_list_remove(client); client_set_expired(client); g_timer_destroy(client->last_activity); if (client->cmd_list) { free_cmd_list(client->cmd_list); client->cmd_list = NULL; } g_queue_foreach(client->deferred_send, deferred_buffer_free, NULL); g_queue_free(client->deferred_send); fifo_buffer_free(client->input); g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE, "[%u] closed", client->num); g_free(client); }
enum command_return client_process_line(struct client *client, char *line) { enum command_return ret; if (strcmp(line, "noidle") == 0) { if (client->idle_waiting) { /* send empty idle response and leave idle mode */ client->idle_waiting = false; command_success(client); client_write_output(client); } /* do nothing if the client wasn't idling: the client has already received the full idle response from client_idle_notify(), which he can now evaluate */ return COMMAND_RETURN_OK; } else if (client->idle_waiting) { /* during idle mode, clients must not send anything except "noidle" */ g_warning("[%u] command \"%s\" during idle", client->num, line); return COMMAND_RETURN_CLOSE; } if (client->cmd_list_OK >= 0) { if (strcmp(line, CLIENT_LIST_MODE_END) == 0) { g_debug("[%u] process command list", client->num); /* for scalability reasons, we have prepended each new command; now we have to reverse it to restore the correct order */ client->cmd_list = g_slist_reverse(client->cmd_list); ret = client_process_command_list(client, client->cmd_list_OK, client->cmd_list); g_debug("[%u] process command " "list returned %i", client->num, ret); if (ret == COMMAND_RETURN_CLOSE || client_is_expired(client)) return COMMAND_RETURN_CLOSE; if (ret == COMMAND_RETURN_OK) command_success(client); client_write_output(client); free_cmd_list(client->cmd_list); client->cmd_list = NULL; client->cmd_list_OK = -1; } else { size_t len = strlen(line) + 1; client->cmd_list_size += len; if (client->cmd_list_size > client_max_command_list_size) { g_warning("[%u] command list size (%lu) " "is larger than the max (%lu)", client->num, (unsigned long)client->cmd_list_size, (unsigned long)client_max_command_list_size); return COMMAND_RETURN_CLOSE; } new_cmd_list_ptr(client, line); ret = COMMAND_RETURN_OK; } } else { if (strcmp(line, CLIENT_LIST_MODE_BEGIN) == 0) { client->cmd_list_OK = 0; ret = COMMAND_RETURN_OK; } else if (strcmp(line, CLIENT_LIST_OK_MODE_BEGIN) == 0) { client->cmd_list_OK = 1; ret = COMMAND_RETURN_OK; } else { g_debug("[%u] process command \"%s\"", client->num, line); ret = command_process(client, 0, line); g_debug("[%u] command returned %i", client->num, ret); if (ret == COMMAND_RETURN_CLOSE || client_is_expired(client)) return COMMAND_RETURN_CLOSE; if (ret == COMMAND_RETURN_OK) command_success(client); client_write_output(client); } } return ret; }
int serve(client_node_t* client) { client->pid = getpid(); client_id = client->id; signal(SIGUSR1, signal_handle); int c; // replace stdin, stdout, stderr to client fd for(c=0; c<3; c++){ dup2(client->client_sc_fd, c); } for(c=0; c<client->num_env; c++) { setenv(client->env[c], client->env_val[c], 1); } printf("%s\n", welcome_message); fflush(stdout); char broad_msg[1024]; bzero(broad_msg, 1024); sprintf(broad_msg, "*** User '(no name)' entered from %s/%d. ***\n", client->ip, client->port); broad_cast(client, broad_msg); printf("%% "); fflush(stdout); while(1){ cmd_node_t* cmd_node_list = NULL; parse_tokens(&cmd_node_list); int state; if(cmd_node_list != NULL) { // handle_from_user_node(&cmd_node_list); // process commands // despatch node to right palce while(cmd_node_list != NULL) { cmd_node_t* node_to_exec = pull_cmd_node(&cmd_node_list); if(node_to_exec->pipe_count == -1) { break; } int errnum = exec_cmd_node(node_to_exec, client); if(errnum == -1) { // command not found printf("Unknown command: [%s].\n", node_to_exec->cmd); fflush(stdout); free_cmd_list(&cmd_node_list); } else if(errnum == -2) { // pipe to me not exist printf("*** Error: the pipe #%d->#%d does not exist yet. ***\n", node_to_exec->from_user_id, client->id); fflush(stdout); free_cmd_list(&cmd_node_list); } else if(errnum == -3) { // pipe to other exist printf("*** Error: the pipe #%d->#%d already exists. ***\n", client->id, node_to_exec->to_user_id); fflush(stdout); } else if(errnum == -4) { // logout return -1; } } } printf("%% "); fflush(stdout); } return 0; }