/*
* $Log: tcpopen.c,v $
* Revision 2.2 2002-12-11 10:28:57+05:30 Cprogrammer
* added ERESTART check for errno
*
* Revision 2.1 2002-12-02 21:48:45+05:30 Cprogrammer
* added check for in_addr_t
*
* Revision 1.5 2002-03-03 15:40:47+05:30 Cprogrammer
* changed strncpy to scopy
*
* Revision 1.4 2001-12-19 16:29:10+05:30 Cprogrammer
* added code to bind on unix domain sockets
*
* Revision 1.3 2001-12-13 11:52:27+05:30 Cprogrammer
* variable for inaddr changed to in_addr_t
*
* Revision 1.2 2001-12-11 11:32:53+05:30 Cprogrammer
* inclusion of systeminfo.h for solaris
*
* Revision 1.1 2001-12-07 22:29:09+05:30 Cprogrammer
* Initial revision
*
*/
#ifndef lint
static char sccsid[] = "$Id: tcpopen.c,v 2.2 2002-12-11 10:28:57+05:30 Cprogrammer Stab root $";
#endif
#include "stdlib.h"
#include "netdb.h"
#include "unistd.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include "string.h"
#include "errno.h"
#include "sys/param.h"
#include "sys/types.h"
#include "sys/socket.h"
#include "sys/un.h"
#ifdef sun
#include "sys/systeminfo.h"
#endif
static unsigned sleeptime = MAXSLEEP + 1; /*- 0 for infinite connect */
int
tcpopen(host, service, port) /*- Thanks to Richard's Steven */
char *host;
char *service;
int port;
/*-
* host - Name or dotted decimal address of the
* other system / Pathname for a unix domain socket
* service - Name of the service being requested.
* Can be NULL, if port > 0.
* port - if == 0, nothin special, use port# of the service.
* if <> 0, it is the port# of server (host-byte-order)
*/
{
int resvport, fd, optval, retval;
char *ptr, *hostptr;
#ifdef HAVE_IN_ADDR_T
in_addr_t inaddr;
#else
unsigned long inaddr;
#endif
struct servent *sp;
struct hostent *hp;
struct sockaddr_in tcp_srv_addr;/*- server's Internet socket address */
struct sockaddr_un unixaddr; /*- server's local unix socket address */
struct servent tcp_serv_info; /*- from getservbyname */
struct hostent tcp_host_info; /*- from gethostbyname */
struct linger linger;
char *dir;
char localhost[MAXHOSTNAMELEN];
if(host && *host && ((strchr(host, '/') || ((dir = Dirname(host)) && !access(dir, F_OK)))))
{
if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
return -1;
unixaddr.sun_family = AF_UNIX;
scopy (unixaddr.sun_path, host, sizeof(unixaddr.sun_path));
if (connect (fd, (struct sockaddr *) &unixaddr, sizeof(struct sockaddr_un) ) == -1)
return -1;
return(fd);
}
/*
* Initialize the server's Internet address structure. We'll store
* the actual 4-byte Internet address and the 2-byte port # below.
*/
(void) memset((char *) &tcp_srv_addr, 0, sizeof(tcp_srv_addr));
tcp_srv_addr.sin_family = AF_INET;
if (service != (char *) NULL)
{
if ((sp = getservbyname(service, "tcp")) == NULL)
{
errno = EINVAL;
return (-1);
}
tcp_serv_info = *sp;
if (port > 0)
tcp_srv_addr.sin_port = htons(port); /*- caller's value */
else
tcp_srv_addr.sin_port = sp->s_port; /*- service's value */
} else
if (port <= 0) { errno = EINVAL; return (-1); } else tcp_srv_addr.sin_port = htons(port); #ifdef sun if (sysinfo(SI_HOSTNAME, localhost, MAXHOSTNAMELEN) > MAXHOSTNAMELEN)
#else
if (gethostname(localhost, MAXHOSTNAMELEN))
#endif
return (-1);
if (!strcmp(host, localhost) || !strcmp(host, "localhost"))
hostptr = "localhost";
else
hostptr = host;
/*
* First try to convert the hostname as the dotted decimal number.
* Only if that fails, call gethostbyname.
*/
if ((inaddr = inet_addr(hostptr)) != INADDR_NONE)
{ /*- It's a dotted decimal */
(void) memcpy((char *) &tcp_srv_addr.sin_addr, (char *) &inaddr, sizeof(inaddr));
tcp_host_info.h_name = NULL;
} else
if ((hp = gethostbyname(hostptr)) == NULL)
{
errno = EINVAL;
return (-1);
} else
{
tcp_host_info = *hp; /*- found it by name, structure copy */
(void) memcpy((char *) &tcp_srv_addr.sin_addr, hp->h_addr, hp->h_length);
}
if ((ptr = (char *) getenv("SLEEPTIME")) != (char *) 0)
{
if (isnum(ptr))
sleeptime = atoi(ptr);
else
{
errno = EINVAL;
return (-1);
}
}
for (;;)
{
if (port >= 0)
{
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < resvport =" IPPORT_RESERVED" fd =" rresvport(&resvport))" optval =" 1;" errno =" 0;;)" retval =" connect(fd," errno ="="" errno ="="" errno ="="" errno =" ECONNREFUSED;" errno =" ECONNREFUSED;" errno ="="" optval =" errno;" errno =" optval;" errno =" 0;;)" l_onoff =" 1;" l_linger =" 1;">
#include
#include
#include
/* set the socket buffer sizes */
int
setsockbuf(fd, option, size)
int fd, option, size;
{
int len, retrycount;
len = size;
for (retrycount = 0; retrycount < MAXNOBUFRETRY; retrycount++)
{
if (setsockopt(fd, SOL_SOCKET, option, (void *) &len, sizeof(int)) == -1)
{
if (errno == ENOBUFS)
{
usleep(1000);
continue;
}
close(fd);
return (-1);
}
break;
}
return (errno = 0);
}
#include "ctype.h"
int
isnum(str)
char *str;
{
char *ptr;
for (ptr = str; *ptr; ptr++)
if (!isdigit((int) *ptr))
return (0);
return (1);
}