Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Requires: ssh and nmap executables
- #include <string>
- #include <iostream>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <sys/wait.h>
- #include <signal.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <errno.h>
- #include <iostream>
- #define MAX_HOSTS 32
- #define BUF_TO_READ_SIZE 256 // in bytes
- using namespace std;
- int hostCount, pid[MAX_HOSTS];
- char **hosts;
- void killChildren()
- {
- for (int i = 0; i < hostCount; i++) {
- if (pid[i] > 0) {
- kill(pid[i], SIGINT);
- cout << "Sent kill signal to pid " << pid[i] << ", host \"" << hosts[i] << "\"\n";
- }
- }
- }
- /* Handle signals */
- void handle_SIGINT(int signal)
- {
- if (pid[hostCount] != 0) {
- /* This is the parent process. Send signals to children. */
- killChildren();
- }
- exit(1);
- }
- int isRunningSSH(string hostname)
- {
- string nmapCmd = "nmap -sT -oG - -p 22 -n ";
- nmapCmd += hostname;
- nmapCmd += " | grep '22.open.*ssh' > /dev/null 2>&1";
- int ret(system(nmapCmd.c_str()));
- fflush(0);
- return (0 == ret);
- }
- int isRunningRexec(string hostname)
- {
- string nmapCmd = "nmap -sT -oG - -p 512 -n ";
- nmapCmd += hostname;
- nmapCmd += " | grep '512.open.*exec' > /dev/null 2>&1";
- int ret(system(nmapCmd.c_str()));
- fflush(0);
- return (0 == ret);
- }
- int runRbuildOnHostUsingSSH(const string hostname, const string username, const string command)
- {
- int pid, status, outpipe[2];
- FILE *pipe_file;
- int ret = 0;
- const char *ssh_prog = "/usr/bin/ssh";
- cout << "Command: " << command << endl;
- fflush(0);
- outpipe[0] = outpipe[1] = 0;
- pipe(outpipe);
- if (!(pid = fork())) {
- close(outpipe[0]);
- dup2(outpipe[1], STDERR_FILENO);
- char *new_env[] = { NULL };
- execle(ssh_prog, ssh_prog,
- "-x", /* No X tunneling */
- "-n", /* No input from stdin */
- "-l",
- username.c_str(),
- hostname.c_str(),
- command.c_str(),
- NULL,
- new_env);
- fprintf(stderr, "Unable to run %s\n", ssh_prog);
- exit(1);
- }
- close(outpipe[1]);
- pipe_file = fdopen(outpipe[0], "r");
- char buf[1024];
- while (fgets(buf, 1024, pipe_file)) {
- fputs(buf, stdout);
- fflush(stdout);
- }
- fclose(pipe_file);
- waitpid(pid, &status, 0);
- if (! WIFEXITED(status)) {
- cout << "SSH subprocess exited abnormally " << endl;
- ret = -1;
- } else {
- cout << "SSH subprocess exit value: " << WEXITSTATUS(status) << endl;
- ret = WEXITSTATUS(status);
- }
- return ret;
- }
- int runRbuildOnHostUsingRexec(string hostname, int port, string username, string password, string command)
- {
- int returnCode, ch, socketDescriptor;
- char *host_ptr;
- host_ptr = (char *) hostname.c_str();
- socketDescriptor = rexec(&host_ptr, port, username.c_str(), password.c_str(), command.c_str(), 0);
- if (socketDescriptor != (-1)) {
- cout << "Command: " << command << endl;
- int readCount = 0;
- FILE *fp = fdopen(socketDescriptor, "r");
- fflush(0);
- while ((ch = getc(fp)) != EOF) {
- putchar(ch);
- if (++readCount >= BUF_TO_READ_SIZE) {
- readCount = 0;
- fflush(stdout);
- }
- }
- fclose(fp);
- close(socketDescriptor);
- returnCode = 0;
- } else {
- cout << "Unable to connect to host " << hostname << " with username " << username << "\n";
- returnCode = -1;
- }
- return returnCode;
- }
- int doRbuildOnHost(string hostname, int port, string username, string password, string command)
- {
- time_t startTime, finishTime;
- cout << endl << "Host: " << hostname << "\tLogin: " << username << endl;
- time(&startTime);
- if (isRunningSSH(hostname)) {
- runRbuildOnHostUsingSSH(hostname, username, command);
- } else if (isRunningRexec(hostname)) {
- runRbuildOnHostUsingRexec(hostname, port, username, password, command);
- } else {
- cout << endl << endl << "Error: The remote host '" << hostname << "' does not support ssh or rexec." << endl << endl;
- }
- time(&finishTime);
- int minutes = (finishTime - startTime) / 60;
- int seconds = (finishTime - startTime) % 60;
- cout << endl << "Running Time: " << minutes << " minutes, " << seconds << " seconds" << endl;
- }
- int main(int argc, char **argv)
- {
- string username("abc");
- string password("common");
- string buildCommand("");
- string buildCommand_withld("");
- string ldlibcommand("");
- string javapathcommand("");
- string classpathcmd("");
- string java_home("");
- string basePath("");
- string logPathPrefix("");
- struct servent *servent;
- int ch;
- string tmpPath;
- int errorFlag = 0, basePathFlag = 0, executeFlag = 0, logPathPrefixFlag = 0;
- int redirectStdout = 1;
- int buildCommandFlag = 0;
- time_t startTime;
- time_t rexecTimeout = 24 * 60 * 60; // 24 hours, measured in seconds
- while ((ch = getopt(argc, argv, "hsb:c:e:t:u:p:l:")) != EOF) {
- switch (ch) {
- case 'b':
- basePath = string(optarg);
- basePathFlag++;
- break;
- case 'l':
- logPathPrefix = string(optarg);
- logPathPrefixFlag++;
- break;
- case 's':
- redirectStdout = 0;
- break;
- case 'c': // manually specify build target with some default pre-setup
- buildCommand = string(optarg);
- buildCommandFlag++;
- break;
- case 'e': // manually specify entire rexec command
- buildCommand = string(optarg);
- executeFlag = 1;
- buildCommandFlag++;
- break;
- case 't': // Specify timeout in minutes
- rexecTimeout = (time_t) strtol(optarg, NULL, 10);
- break;
- case 'u': // Specify username
- username = optarg;
- break;
- case 'p': // Specify password
- password = optarg;
- break;
- case 'h':
- default:
- errorFlag = 1;
- break;
- }
- }
- if (optind >= argc) {
- errorFlag = 1;
- cerr << "Error: You must specify host names\n";
- } else {
- hosts = &argv[optind];
- }
- /* Initialize pid info */
- for (int i = 0; i < MAX_HOSTS; i++) {
- pid[i] = (-1);
- }
- /* Initialize command strings */
- if (! executeFlag) {
- // User used -c
- ldlibcommand = "LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH;";
- java_home="/unixhome/jdk1.6.0_21/unix";
- javapathcommand = "JAVA_HOME=" + java_home + ";export JAVA_HOME;";
- classpathcmd = "CLASSPATH=" + java_home + "/jre/lib:" + java_home + "/lib:.;export CLASSPATH;";
- buildCommand_withld = "PATH=" + java_home + "/bin:/usr/local/bin:/usr/bin:$PATH; export PATH;" + ldlibcommand + javapathcommand + classpathcmd + " cd " + basePath + "; echo UNAME: `uname -a`; " + buildCommand + " ; [ 0 -eq $? ] && echo SUCCESSFUL BUILD";
- buildCommand = "PATH=/bin:/usr/local/bin:/usr/bin:$PATH; export PATH; cd " + basePath + "; echo UNAME: `uname -a`; " + buildCommand + " ; [ 0 -eq $? ] && echo SUCCESSFUL BUILD";
- }
- /* Reopen stdout and stderr to files */
- if (redirectStdout) {
- if (isatty( fileno( stdout )))
- cout << "Redirecting stdout and stderr to rbuild.log and to " << logPathPrefix << "* files.\nUse the -s option if you want to see the output.\n";
- tmpPath = "rbuild.log";
- freopen(tmpPath.c_str(), "w", stdout);
- freopen(tmpPath.c_str(), "w", stderr);
- }
- time(&startTime);
- /* Handle SIGINT */
- signal(SIGINT, handle_SIGINT);
- signal(SIGTERM, handle_SIGINT);
- /* Get service port */
- servent = getservbyname("exec", "tcp");
- fflush(0);
- /* Spawn children and send command to each host */
- hostCount = 0;
- string host;
- while (hosts[hostCount] && (hostCount < MAX_HOSTS)) {
- host = hosts[hostCount];
- tmpPath = logPathPrefix + host;
- pid[hostCount] = fork();
- if (0 == pid[hostCount]) {
- // Child
- if (redirectStdout) {
- freopen(tmpPath.c_str(), "w", stdout);
- freopen(tmpPath.c_str(), "w", stderr);
- }
- if(!host.compare("SOLSPARC"))
- buildCommand = buildCommand_withld ;
- doRbuildOnHost(host, servent->s_port, username, password, buildCommand);
- exit(0); // The child process should exit at this point
- } else if (-1 == pid[hostCount]) {
- cout << "Couldn't fork for host \"" << host << "\"\n";
- } else {
- cout << "Remote execute started for host \"" << host << "\", logfile: \"" << tmpPath << "\", pid: " << pid[hostCount] << " \n";
- }
- hostCount++;
- }
- /* Wait for all sub-processes to exit */
- int statval;
- time_t runningTime;
- int child_pid;
- do {
- child_pid = waitpid(0, &statval, WNOHANG);
- if (child_pid == -1 && errno == ECHILD) {
- break; // All children have exited
- }
- if (rexecTimeout) {
- time(&runningTime);
- if ( (runningTime - startTime) > rexecTimeout ) {
- cout << "Reached timeout of " << rexecTimeout << " seconds; killing rexec processes.\n";
- killChildren();
- rexecTimeout = 0; // We should never come back here again
- }
- }
- sleep(1);
- } while (1);
- fflush(0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement