/***************************************************************
*
* 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);
}