home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume36
/
msend
/
part01
/
network.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-22
|
5KB
|
241 lines
/* 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);
}