This is sltcp.c in view mode; [Download] [Up]
/* Copyright (c) 1996 John E. Davis (davis@space.mit.edu)
* All rights reserved.
*/
#include "config.h"
#include "features.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <netdb.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include "sltcp.h"
static int TCP_Verbose_Reporting = 0;
/* This function attempts to make a connection to a specified port on an
* internet host. It returns a socket descriptor upon success or -1
* upon failure.
*/
static int get_tcp_socket (char *host, int port)
{
char **h_addr_list;
/* h_addr_list is NULL terminated if h_addr is defined. If h_addr
* is not defined, h_addr is the only element in the list. When
* h_addr is defined, its value is h_addr_list[0].
*/
int h_length;
int h_addr_type;
char *fake_h_addr_list[2];
unsigned long fake_addr;
struct sockaddr_in s_in;
int s;
int not_connected;
/* If it does not look like a numerical address, use nameserver */
if (!isdigit(*host) || (-1L == (long)(fake_addr = inet_addr (host))))
{
struct hostent *hp;
hp = gethostbyname (host);
if (hp == NULL)
{
fprintf(stderr, "%s: Unknown host.\n", host);
return -1;
}
#ifdef h_addr
h_addr_list = hp->h_addr_list;
#else
h_addr_list = fake_h_addr_list;
h_addr_list [0] = hp->h_addr;
h_addr_list [1] = NULL;
#endif
h_length = hp->h_length;
h_addr_type = hp->h_addrtype;
}
else
{
h_addr_list = fake_h_addr_list;
h_addr_list [0] = (char *) &fake_addr;
h_addr_list [1] = NULL;
h_length = sizeof(struct in_addr);
h_addr_type = AF_INET;
}
memset ((char *) &s_in, 0, sizeof(s_in));
s_in.sin_family = h_addr_type;
s_in.sin_port = htons((unsigned short) port);
if (-1 == (s = socket (h_addr_type, SOCK_STREAM, 0)))
{
perror("socket");
return -1;
}
not_connected = -1;
while (not_connected
&& (h_addr_list != NULL)
&& (*h_addr_list != NULL))
{
char *this_host;
memcpy ((char *) &s_in.sin_addr, *h_addr_list, h_length);
this_host = (char *) inet_ntoa (s_in.sin_addr);
if (TCP_Verbose_Reporting) fprintf (stderr, "trying %s\n", this_host);
not_connected = connect (s, (struct sockaddr *)&s_in, sizeof (s_in));
if (not_connected == -1)
{
#ifdef EINTR
if (errno == EINTR) /* If interrupted, try again. */
continue;
#endif
fprintf (stderr, "connection to %s: ", (char *) this_host);
perror ("");
}
h_addr_list++;
}
if (not_connected)
{
fprintf(stderr, "Unable to make connection. Giving up.\n");
close (s);
return -1;
}
return s;
}
int sltcp_open_connection (SLTCP_Type *tcp, char *host, int port)
{
int rd, wd;
FILE *r, *w;
if (tcp == NULL) return -1;
tcp->fp_read = tcp->fp_write = NULL;
rd = get_tcp_socket (host, port);
if (rd == -1) return -1;
/* Now setup for buffered i/o */
if (NULL == (r = fdopen (rd, "r")))
{
fprintf (stderr, "fdopen for read failed.");
close (rd);
return (-1);
}
if (-1 == (wd = dup (rd)))
{
fprintf (stderr, "dup failed.");
fclose (r);
return -1;
}
if (NULL == (w = fdopen (wd, "w")))
{
fprintf (stderr, "fdopen for write failed.");
fclose (r);
close (wd);
return (-1);
}
tcp->fp_read = r;
tcp->fp_write = w;
return 0;
}
void sltcp_close (SLTCP_Type *tcp)
{
if (tcp == NULL) return;
if (tcp->fp_read != NULL) fclose (tcp->fp_read);
if (tcp->fp_write != NULL) fclose (tcp->fp_write);
tcp->fp_read = tcp->fp_write = NULL;
}
unsigned sltcp_fread (SLTCP_Type *tcp, char *s, unsigned int len)
{
if ((tcp == NULL) || (tcp->fp_read == NULL))
return 0;
return fread (s, 1, len, tcp->fp_read);
}
unsigned sltcp_fwrite (SLTCP_Type *tcp, char *s, unsigned int len)
{
if ((tcp == NULL) || (tcp->fp_write == NULL))
return 0;
return fwrite (s, 1, len, tcp->fp_write);
}
int sltcp_fputs (SLTCP_Type *tcp, char *s)
{
if ((tcp == NULL) || (tcp->fp_write == NULL))
return EOF;
return fputs (s, tcp->fp_write);
}
char *sltcp_fgets (SLTCP_Type *tcp, char *s, int size)
{
if ((tcp == NULL) || (tcp->fp_read == NULL))
return NULL;
return fgets (s, size, tcp->fp_read);
}
int sltcp_fflush (SLTCP_Type *tcp)
{
if ((tcp == NULL) || (tcp->fp_write == NULL))
return EOF;
return fflush (tcp->fp_write);
}
int sltcp_vfprintf (SLTCP_Type *tcp, char *fmt, va_list ap)
{
if ((tcp == NULL) || (tcp->fp_write == NULL))
return -1;
if (vfprintf (tcp->fp_write, fmt, ap) < 0)
return -1;
return 0;
}
int sltcp_map_service_to_port (char *service)
{
struct servent *sv;
sv = getservbyname (service, "tcp");
if (sv == NULL) return -1;
return (int) ntohs (sv->s_port);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.