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.