This is network.c in view mode; [Download] [Up]
/* network.c: * * raw networking commands. these commands are independent of the * application protocol; they are not tuned specifically for msend, * but instead make up a library that i use to work with networking. * * (c) Copyright 1988, 1989, 1990 Jim Frost. All Rights Reserved. Please see * the accompanying file "Copyright" for more information. */ #include "Copyright" #include "config.h" /* for NOHERROR */ #include "msend.h" /* for MAXHOSTNAME */ #include <sys/errno.h> #define MAXCONNECTS 1 /* max number of connects we need */ extern errno; extern int h_errno; static int init= 1; static int socki[MAXCONNECTS]; static char sockh[MAXCONNECTS][MAXHOSTNAME+1]; static void hinit() { int a; for (a= 0; a < MAXCONNECTS; a++) socki[a]= -1; init= 0; } int hopen(hostname) char *hostname; { struct sockaddr_in sa; struct hostent *hp; unsigned long address = 0; unsigned long inet_addr(); int a,i; #ifdef SECURE_PORT int lport = IPPORT_RESERVED - 1; int uid; #endif if (init) hinit(); /* find host table entry */ if ((address = inet_addr(hostname)) == (unsigned long) -1) { address = 0; if((hp= gethostbyname(hostname)) == NULL) { errno= ECONNREFUSED; #ifdef NOHERROR h_errno = 1; /* Unknown Host */ #endif return(-1); } } h_errno = 0; /* see if we're already talking */ for (a= 0; (a < MAXCONNECTS) && ((socki[a] == -1) || strcmp(sockh[a], address ? hostname : hp->h_name)); a++) ; if (a < MAXCONNECTS) /* great! don't need a connection */ return(socki[a]); /* find an empty spot */ for (a= 0; (a < MAXCONNECTS) && (socki[a] != -1); a++) ; if (a >= MAXCONNECTS) { errno= EMFILE; return(-1); } strcpy(sockh[a],address ? hostname : hp->h_name); bzero(&sa,sizeof(sa)); if (getprotobyname("tcp") == NULL) { errno= ENOPROTOOPT; return(-1); } if (address) sa.sin_addr.s_addr = address; else bcopy(hp->h_addr,(char *)&sa.sin_addr,hp->h_length); sa.sin_family= address ? AF_INET : hp->h_addrtype; i=portnum(); sa.sin_port= htons((u_short)i); #ifndef SECURE_PORT if ((socki[a]= socket(address ? AF_INET : hp->h_addrtype,SOCK_STREAM,0)) < 0) return(-1); #else uid= geteuid(); seteuid(ROOTUID); if((socki[a] = rresvport(&lport)) < 0) { seteuid(uid); return(-1); } seteuid(uid); #endif #if defined(h_addr) /* 4.3 or greater system. Has "h_addr_list". */ while((connect(socki[a],&sa,sizeof sa) < 0)) { (void) close(socki[a]); #ifdef SECURE_PORT if (errno == EADDRINUSE) { lport--; seteuid(ROOTUID); if((socki[a] = rresvport(&lport)) < 0) { seteuid(uid); return(-1); } seteuid(uid); continue; } #endif if (address) return(-1); if (!hp->h_addr_list[1]) return(-1); hp->h_addr_list++; bcopy(hp->h_addr_list[0],&sa.sin_addr,hp->h_length); #ifndef SECURE_PORT if ((socki[a]= socket( hp->h_addrtype,SOCK_STREAM,0)) < 0) return(-1); #else seteuid(ROOTUID); if((socki[a] = rresvport(&lport)) < 0) { seteuid(uid); return(-1); } seteuid(uid); #endif } #else #ifdef SECURE_PORT for(;;) { #endif if (connect(socki[a],&sa,sizeof sa) < 0) { (void) close(socki[a]); #ifndef SECURE_PORT return(-1); #else if (errno == EADDRINUSE) { lport--; seteuid(ROOTUID); if((socki[a] = rresvport(&lport)) < 0) { seteuid(uid); return(-1); } seteuid(uid); continue; } break; #endif } } #endif /* at this point you should be connected to the host for commands */ return(socki[a]); } /* close a single network connection */ void hclose(s) int s; { int a; for (a= 0; (a < MAXCONNECTS) && (socki[a] != s); a++) if (a < MAXCONNECTS) { close(socki[a]); socki[a]= -1; } else /* not one of ours, but close it anyway */ close(s); } /* this closes all open network connections */ void hcleanup() { int a; for (a= 0; a < MAXCONNECTS; a++) if (socki[a] != -1) { close(socki[a]); socki[a]= -1; } } int hread(s,buf,n) int s; char *buf; int n; { int bcount, /* counts bytes read */ br; /* bytes read this pass */ bcount= 0; br= 0; while (bcount < n) { /* loop until full buffer */ if ((br= read(s,buf,n-bcount)) > 0) { bcount += br; /* increment byte counter */ buf += br; /* move buffer ptr for next read */ } if (br == 0) /* EOF */ return(0); if (br < 0) /* signal an error to the caller */ return(-1); } return(bcount); } int hwrite(s,buf,n) int s; char *buf; int n; { int bcount, bw; bcount=0; while (bcount < n) { if ((bw= write(s,buf,n-bcount))>0) { bcount += bw; buf += bw; } if (bw < 0) return(-1); } return(bcount); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.