bool Connection::command(CommandLine &command, Process *process) { // Remove the command and process name, leaving only the process command line CommandLine::iterator start = command.begin(); CommandLine::iterator end = start + 2; command.erase(start, end); // Change the command line for the process process->command = command; //FIXME - Log just the executable or everything? log_printf("Changed command for \"%s\"\n", process->name.c_str()); log_printf(" argc == %d:\n", command.size()); for (CommandLine::const_iterator i = command.begin(); i != command.end(); ++i) { log_printf(" \"%s\"\n", (*i).c_str()); } return true; }
void Connection::run() { // True while the process list mutex is held. // This lets the exception handler know when to unlock the mutex. bool locked = false; // in_addr_t a = ntohl(remote_addr.sin_addr.s_addr); // log_printf("Received connection from %d.%d.%d.%d:%d\n", a >> 24, (a >> 16) & 255, (a >> 8) & 255, a & 255, ntohs(remote_addr.sin_port)); try { // Identify ourselves write("Watchdog v2.0\n"); while (1) { // Read a command CommandLine command; if (!read_command(command)) { write("Command cancelled\n"); continue; } int words = command.size(); if (words == 0) { // Blank line continue; } #if 0 printf("%d words:\n", words); for (Command::const_iterator i = command.begin(); i != command.end(); ++i) { printf(" \"%s\"\n", (*i).c_str()); } #endif // Find a handler for this command for (int i = 0; command_table[i].command; i++) { // Check the command name if (command[0] == command_table[i].command) { // Check the number of words if (command_table[i].words > 0 && words != command_table[i].words) { write("Wrong number of parameters\n"); goto next_command; } Process::lock(); locked = true; // Check the process name if required by the table Process *process = 0; if (command_table[i].check_process) { // If a process name is given, try to find it. // // This test handles the case where the table // requires zero words but check_process is true. if (words > 1) { process = Process::find(command[1]); } if (!process) { Process::unlock(); locked = false; write("No such process\n"); goto next_command; } } // Call the handler if (command_table[i].handler) { if ((this->*command_table[i].handler)(command, process)) { write("OK\n"); } } else { write("Unimplemented command\n"); } Process::unlock(); locked = false; goto next_command; } } write("Unrecognized command\n"); next_command: ; } } catch (connection_closed) { } catch (std::exception &ex) { log_printf("Connection::run() exception: %s\n", ex.what()); } // Unlock the process list in case an exception was thrown while it was locked. if (locked) { Process::unlock(); } // log_printf("Closed connection from %d.%d.%d.%d:%d\n", a >> 24, (a >> 16) & 255, (a >> 8) & 255, a & 255, ntohs(remote_addr.sin_port)); close(conn_socket); }