/*************************************************************** * * Update these defines: * MY_NOME is the path to your home directory where the sshr_cron will run. * MY_SSH_TARGET is the node name or IP of the machine you ware attaching * to. (Your home machine). * MY_IDRSA Name of the id_rsa file in the .ssh directory when it is not * in it's "live" name. * The alternate name means that it only is active when we make * the connection. The default version is probably good. * ***************************************************************/ #define MY_HOME "/home/stymar" #define MY_SSH_TARGET "styma8a" #define MY_IDRSA "id_rsa8a" #define SSH_PATH "/usr/bin/ssh" #define NOHUP_PATH "/usr/bin/nohup" /******************************************************************* PROGRAM: sshr_cron - SSH Roll Your Own VPN Monitor keep alive DESCRIPTION: This program is made to be called by cron from the user setting up the personal roll your own VPN. It checks to see if the echo port forwarded through ssh is open. If not, it kills and restarts the ssh service. INPUT ARGUMENTS: (see manual page for descriptions) -c<cmd> - The ssh command to execute -d - debug option -e <name> - Name to search for in the process table to restart server -f <pscmd> - PS command to run to find process to restart server -h - Print help message and quit -p <port> - echo server port at this end. -r - force restart even if everything is OK -t - Use the daytime service instead of the echo service INTERNAL ROUTINES: echo_test - Connect to the remote echo server via a forwarded port. wait_for_data - Wait for response from the echo server restart_ssh - Restart the ssh command on the local node kill_process - Kill a process after getting the PID from the ps output. catch - Interupt handler system_w_timeout - Call the system command with a timeout usage - Print usage prompt and exit. *******************************************************************/ #include <stdio.h> /* /usr/include/stdio.h */ #include <string.h> /* /usr/include/string.h */ #include <sys/types.h> /* /usr/include/sys/types.h */ #include <fcntl.h> /* /usr/include/fcntl.h */ #include <sys/times.h> /* /usr/include/sys/times.h */ #include <time.h> /* /usr/include/time.h */ #include <signal.h> /* /usr/include/signal.h */ #include <setjmp.h> /* /usr/include/setjmp.h */ #include <errno.h> /* /usr/include/errno.h */ #include <unistd.h> /* /usr/include/unistd.h */ #include <stdlib.h> /* /usr/include/stdlib.h */ #include <sys/socket.h> /* /usr/include/sys/socket.h */ #include <netinet/in.h> /* /usr/include/netinet/in.h */ #include <arpa/inet.h> /* /usr/include/arpa/inet.h */ #include <netdb.h> /* /usr/include/netdb.h */ #ifndef FD_ZERO #include <sys/select.h> /* /usr/include/sys/select.h */ #endif #include <malloc.h> /* /usr/include/malloc.h */ #ifdef solaris #define SA1 (struct sockaddr *) #else #define SA1 #endif #ifndef True #define True 1 #endif #ifndef False #define False 0 #endif /*************************************************************** * * Values from command line arguments * ***************************************************************/ /* -c <cmd> */ char command[256] = "mv " MY_HOME "/.ssh/" MY_IDRSA " " MY_HOME "/.ssh/id_rsa;" NOHUP_PATH " " SSH_PATH " -N -f " MY_SSH_TARGET ";mv " MY_HOME "/.ssh/id_rsa " MY_HOME "/.ssh/" MY_IDRSA; /* -d Debug option */ int debug = 0; /* -e <string> */ char ps_search[256] = " -N -f " MY_SSH_TARGET; /* -f <ps command> */ #ifdef linux char ps_cmd[256] = "ps auxw"; #else char ps_cmd[256] = "ps -ef -o \"user,pid,ppid,stime,tty,time,args\""; #endif /* -p <echo server query port> */ char local_forwarded_port[32]= "7777"; /* -r force restart */ int force_restart = False; /* -t use daytime server */ int use_daytime = False; /*************************************************************** * * Definition for CURRENT_TIME * This macro may be substituted where you need a pointer to * char. such as: * printf("%s\n", CURRENT_TIME); * The current time is what the pointer points to. You can * change _t1_ and _t3_ to something else if needed. * the _t3_ manipulations take off the \n from the string * returned by asctime. * If you copy this definition, you need an include for <time.h> * ***************************************************************/ time_t _t1_; char *_t3_; #define CURRENT_TIME ((_t3_ = asctime(localtime((_t1_ = time(NULL), &_t1_)))),(_t3_[strlen(_t3_)-1]='\0'), _t3_ ) /*************************************************************** * * Local prototypes * ***************************************************************/ static int echo_test(const char *echo_local_forward_port); static int daytime_test(const char *time_local_forward_port); static int wait_for_data(int fd); static void restart_ssh(const char *command, const char *ps_search, const char *ps_cmd); static void kill_process(const char *ps_line); void catch(); static int system_w_timeout(const char *cmd); jmp_buf setjmp_env; /* used when alarm goes off */ static void usage(void); static int tcp_open(const char *host, const char *service, int reserved, char *msg); /*************************************************************** * * Main Entry Point * ***************************************************************/ int main (int argc, char *argv[]) { char ch; int i; int rc; /****************************************** check the arguments to get the host name, mvs process name (from offer), and the Debug parm. *****************************************/ while ((ch = getopt(argc, argv, "c:de:f:hp:rt")) != EOF) switch (ch) { case 'c' : strncpy(command, optarg, sizeof(command)); break; case 'd' : debug++; break; case 'e' : strncpy(ps_search, optarg, sizeof(ps_search)); break; case 'f' : strncpy(ps_cmd, optarg, sizeof(ps_cmd)); break; case 'h' : usage(); /* usage does not return */ break; case 'p' : /* echo server forwarded port */ strncpy(local_forwarded_port, optarg, sizeof(local_forwarded_port)); break; case 'r' : force_restart = True; break; case 't' : use_daytime = True; break; default : usage(); /* usage does not return */ break; } /* end of switch on ch */ /*************************************************************** * Dump the args is -d was specified. ***************************************************************/ if (debug) { fprintf(stderr, "Running with options:\n"); fprintf(stderr, " -c <command> = %s\n", command); fprintf(stderr, " -e <ps_search_str> = %s\n", ps_search); fprintf(stderr, " -f <ps_cmd> = %s\n", ps_cmd); fprintf(stderr, " -p <forwarded_port> = %s\n", local_forwarded_port); fprintf(stderr, " -r = %s\n", (force_restart ? "True" : "False")); fprintf(stderr, " -t = %s\n", (use_daytime ? "True" : "False")); } /*************************************************************** * One last sanity check on the args ***************************************************************/ if (optind < argc) { fprintf(stderr, "%s takes no positional arguments -> \"%s\"\n", argv[0], argv[optind]); usage(); /* usage does not return */ } /*************************************************************** * See if we can contact the echo server. If not, or if -r * was specified, do the restart. ***************************************************************/ if (!force_restart) { if (use_daytime) rc = daytime_test(local_forwarded_port); else rc = echo_test(local_forwarded_port); } else rc = 1; if (rc != 0) restart_ssh(command, ps_search, ps_cmd); return(0); } /* end of main procedure */ /******************************************************************* MODULE: echo_test - Connect to the remote echo server via a forwarded port. DESCRIPTION: Use the forwarded ssh port to connect to the tcp echo server on the remote node. This tests to see if the port forwarding is working. INPUT PARAMETERS: 1. echo_local_forward_port - This is the local port which is forwarded to the echo server on the remote host. FUNCTIONS: 1. Set an alarm and a longjump so we can time out the tcp open in case it hanges. 2. Open a connection to the remote echo server via the local forwarded port. 3. Write a message out and read it badc/ RETURNED VALUES: rc - return code 0 - All is well, the echo server was contacted -1 - error, Message output *******************************************************************/ #define TEST_ECHO_MESSAGE "Test Echo Message" static int echo_test(const char *echo_local_forward_port) { int i; int cli_addr_size; int rc; int nread; int sockfd; char msg_buff[1024]; rc = setjmp(setjmp_env); if (rc == 0) { signal(SIGALRM, catch); /* Timeout doing the socket open call */ alarm(30); /* set alarm for 30 seconds, more than enough time */ sockfd = tcp_open("localhost", echo_local_forward_port, 0, msg_buff); if (sockfd < 0) { fprintf(stderr, "Could not connect to echo server port localhost:%s (%s)\n", echo_local_forward_port, strerror(errno)); fputs(msg_buff, stderr); rc = -1; } else if (debug) fprintf(stderr, "Connected to localhost : %s\n", echo_local_forward_port ); } else fprintf(stderr, "? Timeout opening tcp socket\n"); alarm(0); /* cancel the alarm */ signal(SIGALRM, SIG_DFL); /* Timeout doing a system call */ if (rc == 0) { nread = send(sockfd, TEST_ECHO_MESSAGE, sizeof(TEST_ECHO_MESSAGE), 0); if (nread < 0) { fprintf(stderr, "Send error on echo server port localhost:%s (%s)\n", echo_local_forward_port, strerror(errno)); rc = -1; } if (rc == 0) { nread = wait_for_data(sockfd); /* returns result of a select */ if (nread > 0) { nread = recv(sockfd, msg_buff, sizeof(msg_buff), 0); if (nread < 0) { fprintf(stderr, "Recv error on echo server port localhost:%s (%s)\n", echo_local_forward_port, strerror(errno)); rc = -1; } else if (nread != sizeof(TEST_ECHO_MESSAGE)) { msg_buff[nread] = '\0'; fprintf(stderr, "Data sent not echoed - Sent %d bytes '%s' Received %d bytes '%s'\n", sizeof(TEST_ECHO_MESSAGE), TEST_ECHO_MESSAGE, nread, msg_buff); rc = -1; } else { if (debug) { msg_buff[nread] = '\0'; fprintf(stderr, "Echo worked - Sent '%s' Received '%s'\n", TEST_ECHO_MESSAGE, msg_buff); } rc = 0; } } else if (nread < 0) { fprintf(stderr, "Select failure on echo server port localhost:%s (%s)\n", echo_local_forward_port, strerror(errno)); rc = -1; } else { fprintf(stderr, "Select timed out on echo server port localhost:%s\n", echo_local_forward_port); rc = -1; } } close(sockfd); } return(rc); } /* end of echo_test */ /******************************************************************* MODULE: daytime_test - Connect to the remote http server via a forwarded port. DESCRIPTION: Use the forwarded ssh port to connect to the daytime server on the remote node. This server just sends the current time back. This tests to see if the port forwarding is working. INPUT PARAMETERS: 1. daytime_test_local_forward_port - This is the local port which is forwarded to the daytime server (port 13) on the remote host. FUNCTIONS: 1. Set an alarm and a longjump so we can time out the tcp open in case it hanges. 2. Open a connection to the remote http server via the local forwarded port. 3. Write a message out and read it badc/ RETURNED VALUES: rc - return code 0 - All is well, the http server was contacted -1 - error, Message output *******************************************************************/ static int daytime_test(const char *daytime_test_local_forward_port) { int i; int cli_addr_size; int rc; int nread; int sockfd; char msg_buff[8192]; rc = setjmp(setjmp_env); if (rc == 0) { signal(SIGALRM, catch); /* Timeout doing the socket open call */ alarm(30); /* set alarm for 30 seconds, more than enough time */ sockfd = tcp_open("localhost", daytime_test_local_forward_port, 0, msg_buff); if (sockfd < 0) { fprintf(stderr, "Could not connect to daytime server port localhost:%s (%s)\n", daytime_test_local_forward_port, strerror(errno)); fputs(msg_buff, stderr); rc = -1; } } else fprintf(stderr, "? Timeout opening tcp socket\n"); alarm(0); /* cancel the alarm */ signal(SIGALRM, SIG_DFL); /* Timeout doing a system call */ if (rc == 0) { nread = wait_for_data(sockfd); /* returns result of a select */ if (nread > 0) { nread = recv(sockfd, msg_buff, sizeof(msg_buff)-1, 0); if (nread < 0) { fprintf(stderr, "Recv error on daytime server port localhost:%s\n", daytime_test_local_forward_port); rc = -1; } else if (nread == 0) { fprintf(stderr, "No data read from daytime server on forwarded local port localhost:%s\n", daytime_test_local_forward_port); rc = -1; } else { if (debug) { msg_buff[nread] = '\0'; fprintf(stderr, "%s (%d bytes)\n", msg_buff, nread); } rc = 0; } } else if (nread < 0) { fprintf(stderr, "Select failure on daytime server port localhost:%s (%s)\n", daytime_test_local_forward_port, strerror(errno)); rc = -1; } else { fprintf(stderr, "Select timed out on daytime server port localhost:%s\n", daytime_test_local_forward_port); rc = -1; } close(sockfd); } return(rc); } /* end of daytime_test */ /************************************************************************ NAME: wait_for_data - Wait for response from the echo server PURPOSE: This routine is called after a sendto to wait for the server to respond. The select is used to allow a timeout after 10 seconds. PARAMETERS: 1. sockfd - int (INPUT) This is the UDP datagram socket file descriptor. FUNCTIONS : 1. Issue a select on the file descriptor with a timeout of 10 seconds. RETURNED VALUE: rc - int >0 - Datagram ready 0 - select timed out -1 - Timeout *************************************************************************/ #ifdef _INCLUDE_HPUX_SOURCE #define HT (int *) #else #define HT (fd_set *) #endif static int wait_for_data(int fd) { fd_set readfds; struct timeval time_out; int nfound; FD_ZERO(&readfds); FD_SET(fd, &readfds); /* wait 75 seconds for data to be ready */ time_out.tv_sec = 75; time_out.tv_usec = 0; nfound = select(fd+1, HT &readfds, NULL, NULL, &time_out); return(nfound); } /* end of wait_for_data */ /************************************************************************ NAME: restart_ssh - Restart the ssh command on the local node PURPOSE: This routine is called to restart an ssh command. It is called when the server cannot respond and also after a SIGUSR1. PARAMETERS: 1. command - pointer to const char (INPUT) This is the command used to restart the ssh 2. ps_search - pointer to const char (INPUT) This is the string to search for in the ps output. 2. ps_cmd - pointer to const char (INPUT) This is the ps command to popen to look for the command to restart. FUNCTIONS : 1. Popen the ps command. 2. Read through the list looking for the ssh command to stop. 3. If found call the routine to kill the process. 4. Use the system command to restart the server. *************************************************************************/ static void restart_ssh(const char *ssh_cmd, const char *ps_search, const char *ps_cmd) { int rc; char cmd_buff[1024]; char msg_buff[2048]; char subj[80]; char *p; FILE *ps_stream; ps_stream = popen(ps_cmd, "r"); if (ps_stream != NULL) { while(fgets(msg_buff, sizeof(msg_buff), ps_stream) != NULL) { if (strstr(msg_buff, ps_search) != NULL) { fprintf(stderr, "Killing process %s", msg_buff); kill_process(msg_buff); } } rc = pclose(ps_stream); if (rc < 0) fprintf(stderr, "pclose failure (%s)\n", strerror(errno)); } else fprintf(stderr, "Popen failed for \"%s\" (%s)\n", ps_cmd, strerror(errno)); errno = 0; rc = system_w_timeout(ssh_cmd); sprintf(msg_buff, "Return code from system call to restart = %d (%s)\n", rc, (errno ? strerror(errno) : "no error")); } /* end of restart_ssh */ /************************************************************************ NAME: kill_process - Kill a process given its PS line. PURPOSE: This routine is called to kill an ssh command. The process table entry for the command is passed. The second token in the line is the PID PARAMETERS: 1. ps_line - pointer to const char (INPUT) This is the line from the ps coomand which has the PID of the process to kill as the second token. FUNCTIONS : 1. Parse the PS line to get the PID. 2. Hit it with a sigterm (15) 3. Hit it with a sigkill (9) 4. Report any errors. *************************************************************************/ static void kill_process(const char *ps_line) { int rc; char cmd_buff[1024]; char user[256]; int pid_to_kill; if (sscanf(ps_line, "%s %d", user, &pid_to_kill) == 2) { rc = kill(pid_to_kill, SIGTERM); /* try to kill it nicely */ if (rc != 0) fprintf(stderr, "SIGTERM to process %d failed (%s)\n", pid_to_kill, strerror(errno)); rc = kill(pid_to_kill, SIGKILL); /* blast it */ if ((rc != 0) && (errno != ESRCH)) fprintf(stderr, "SIGTERM to process %d failed (%s)\n", pid_to_kill, strerror(errno)); fprintf(stderr, "sent kill to %d\n", pid_to_kill); } else { fprintf(stderr, "Cannot parse process id from second token in line \"%s\"\n", ps_line); } } /******************************************************************* * * MODULE: catch - interupt handler * * DESCRIPTION: * This routine will catch assorted signals and deal with them. * It is called asyncronously by the system. * * * PARAMETERS: * 1. sig - int (INPUT) * The signal handler is passed the signal number. * * * *******************************************************************/ void catch(int sig) { switch(sig) { case SIGHUP: /* got a hup */ break; case SIGALRM: /* got a SIGALRM, something timed out */ fprintf(stderr, "Caught SIGALRM\n"); longjmp(setjmp_env, 1); break; default: fprintf(stderr, "Unexpected signal trapped %d\n", sig); break; /* makes lint happy */ } signal(sig, catch); /* reset signal handler */ } /******************************************************************* * * MODULE: system_w_timeout - Call the system command with a timeout * * DESCRIPTION: * This routine issues the system call to execute a program or * shell script. It has a timeout to deal with the node hanging. * * * PARAMETERS: * 1. cmd - pointer to const char (INPUT) * This is the command to pass to the system command. * * FUNCTIONS: * 1. Set the signal handler to trap alarm signals. If the handler * catches the alarm signal, a longjmp will take place. * * 2. Set an alarm clock for 10 minutes. If it goes off, we hare * hung up for sure. * * 3. Issue the system call. * * 4. If the call completes, cancel the alarm and the signal handler. * * 5. If the timeout occurs, the longjmp will return to the setjmp * position with a non-zero return code. * * RETURNED VALUE: * rc - int * The return code from system, or setjmp in the event * of a timeout. * * *******************************************************************/ static int system_w_timeout(const char *cmd) { int rc = 0; FILE *sys_stream; char msg_buff[1024]; rc = setjmp(setjmp_env); if (rc == 0) { signal(SIGALRM, catch); /* Timeout doing a system call */ alarm(120); /* set alarm for 2 minutes, more than enough time */ rc = system(cmd); fprintf(stderr, "rc = %d, from call to system \"%s\"\n", rc, cmd); if (rc != 0) fprintf(stderr, "%s\n", strerror(errno)); } else fprintf(stderr, "? Timeout processing system command \"%s\"\n", cmd); alarm(0); /* cancel the alarm */ signal(SIGALRM, SIG_DFL); /* Timeout doing a system call */ return(rc); } /* end of system_w_timeout */ /************************************************************************ NAME: tcp_open - open a TCP socket for a client PURPOSE: This routine opens a socket for a client. The clien specifies who he wants to talk to. PARAMETERS: 1. host - pointer to char (INPUT) This is the host to connect to. It may be the name or the dotted number address. 2. service - pointer to char (INPUT) The name of the service to connect to. This can be either a character string port number or a service name. ei, "1069" or na_server 3. reserved - int (INPUT) This flag specifies that a reserved port is to be used instead of a normal port. Root only. FUNCTIONS : 1. Determine whether the passed service is a service name or a port number. 2. Determine whether the passed host is a dotted TCP/IP Internet address or a name of the host. 3. Bind to either a reserved or a non-reserved port based on the reseved parm 4. Do a connect to the host. 5. If the connect works and debug is on, dump the socket data. OUTPUTS: fd - file descriptor The socket file descriptor is returned. On error, -1 is returned. OTHER OUTPUTS: stderr - debugging and error messages are written to stderr. *************************************************************************/ static int tcp_open(const char *host, const char *service, int reserved, char *msg) { struct sockaddr_in tcp_srv_addr; /* servers' Internet socket addr */ int fd; #if !defined(OMVS) && !defined(WIN32) int resvport; #endif unsigned long inaddr; struct servent *sp; struct hostent *hp; char scrap[50]; int server_port; int count; char lcl_msg[256]; #ifdef WIN32 init_sock(); #endif *msg = '\0'; /*************************************************************** * * Initialize the server's Internet address structure. * Service can be either a string of digits representing * a port or a service name. We use sscanf to tell the * difference. If count is 1, everything was digits. * If count is 2 or 0, this is a service name. * ***************************************************************/ memset((char *) &tcp_srv_addr, 0, sizeof(tcp_srv_addr)); tcp_srv_addr.sin_family = AF_INET; count = sscanf(service, "%d%s", &server_port, scrap); if (count != 1) /* not all digits, must be a server name */ { #ifdef DEBUG_OUTPUT if (debug > 2) fprintf(stderr, "Assuming %s is a service name\n", service); #endif if ((sp = getservbyname(service, "tcp")) == NULL) { #ifdef WIN32 sprintf(lcl_msg, "? tcp_open: Cannot get port information for service name %s (%s)\n", service, getWSAmsg(NULL, 0)); #else sprintf(lcl_msg, "? tcp_open: Cannot get port information for service name %s (%s)\n", service, strerror(errno)); #endif strcat(msg, lcl_msg); return(-1); } tcp_srv_addr.sin_port = sp->s_port; #ifdef DEBUG_OUTPUT if (debug > 2) fprintf(stderr, "%s is port %d\n", service, ntohs(tcp_srv_addr.sin_port)); #endif } else { #ifdef DEBUG_OUTPUT if (debug > 2) fprintf(stderr, "Assuming %s is a port number\n", service); #endif tcp_srv_addr.sin_port = htons((short)server_port); } /*************************************************************** * * Try to use the host address as a dotted-decimal number. If * this fails, try to get the host value by name. * ***************************************************************/ if ((inaddr = inet_addr(host)) != -1) { /* it worked, it's dotted decimal */ memcpy((char *)&tcp_srv_addr.sin_addr, (char *)&inaddr, sizeof(inaddr)); #ifdef DEBUG_OUTPUT if (debug > 2) fprintf(stderr, "%s is a dotted Internet address\n", host); #endif } else { if ((hp = gethostbyname(host)) == NULL) { #ifdef WIN32 sprintf(lcl_msg, "? tcp_open: Cannot convert hostname %s to an internet address(%s)\n", host, getWSAmsg(NULL, 0)); #else sprintf(lcl_msg, "? tcp_open: Cannot convert hostname %s to an internet address(%s)\n", host, strerror(errno)); #endif strcat(msg, lcl_msg); return(-1); } memcpy((char *)&tcp_srv_addr.sin_addr, hp->h_addr, hp->h_length); #ifdef DEBUG_OUTPUT if (debug > 2) { fprintf(stderr, "%s is a host name\n", host); fprintf(stderr, " host addr: %s\n", inet_ntoa(*(struct in_addr *)(hp->h_addr))); } #endif } /*************************************************************** * * Now take care of the client side. Get a socket, either * regular or reserved depending upon the parm. * ***************************************************************/ #if !defined(OMVS) && !defined(WIN32) if (reserved) { #ifdef DEBUG_OUTPUT if (debug > 2) fprintf(stderr, "Requesting reserved port\n"); #endif resvport = IPPORT_RESERVED - 1; if ((fd = rresvport(&resvport)) < 0) { sprintf(lcl_msg, "? tcp_open: Cannot get a reserved TCP port for service %s on host %s (%s)\n", service, host, strerror(errno)); strcat(msg, lcl_msg); return(-1); } } else #endif { #ifdef DEBUG_OUTPUT if (debug > 2) fprintf(stderr, "Requesting default port\n"); #endif #ifdef WIN32 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { sprintf(lcl_msg, "? tcp_open: Cannot get a socket file descriptor for service %s on host %s (%s)\n", service, host, getWSAmsg(NULL, 0)); strcat(msg, lcl_msg); return(-1); } #else if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { sprintf(lcl_msg, "? tcp_open: Cannot get a socket file descriptor for service %s on host %s (%s)\n", service, host, strerror(errno)); strcat(msg, lcl_msg); return(-1); } #endif } /*************************************************************** * * Now we are ready to establish the connection * ***************************************************************/ if (connect(fd, (struct sockaddr *)&tcp_srv_addr, sizeof(tcp_srv_addr)) < 0) { #ifdef WIN32 sprintf(lcl_msg, "? tcp_open: Cannot connect to service %s on host %s (%s)\n", service, host, getWSAmsg(NULL, 0)); #else sprintf(lcl_msg, "? tcp_open: Cannot connect to service %s on host %s (%s)\n", service, host, strerror(errno)); #endif strcat(msg, lcl_msg); close(fd); return(-1); } #ifdef DEBUG_OUTPUT if (debug > 2) { fprintf(stderr, "Socket file descriptor: %d\n", fd); display_port(fd, DISPLAY_PORT_REMOTE, DISPLAY_PORT_VERBOSE); display_port(fd, DISPLAY_PORT_LOCAL, DISPLAY_PORT_VERBOSE); } #endif return(fd); /* all is ok */ } /* end of tcp_open */ /*** * * Usage * * Print a blurb saying how to invoke this program. * */ static void usage(void) { fprintf(stderr, "usage: sshr_cron [-c<cmd>] [-d] [-e<string>] [-f<cmd>] [-l<port>] [-r]\n"); fprintf(stderr, " -c<cmd> - The ssh command to execute\n"); fprintf(stderr, " -d - debug option\n"); fprintf(stderr, " -h - print this help message\n"); fprintf(stderr, " -p <port> - echo server port at this end.\n"); fprintf(stderr, " -e <string> - Name to search for in the process table to restart server\n"); fprintf(stderr, " -f <pscmd> - PS command to run to find process to restart server\n"); fprintf(stderr, " -r - Force restart\n"); fprintf(stderr, " -t - Use the daytime service instead of the echo service\n"); exit(1); }