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

  1. /* network.c:
  2.  *
  3.  * raw networking commands.  these commands are independent of the
  4.  * application protocol; they are not tuned specifically for msend,
  5.  * but instead make up a library that i use to work with networking.
  6.  *
  7.  * (c) Copyright 1988, 1989, 1990 Jim Frost.  All Rights Reserved.  Please see
  8.  * the accompanying file "Copyright" for more information.
  9.  */
  10.  
  11. #include "Copyright"
  12. #include "config.h"    /* for NOHERROR */
  13. #include "msend.h"     /* for MAXHOSTNAME */
  14. #include <sys/errno.h>
  15.  
  16. #define MAXCONNECTS 1  /* max number of connects we need */
  17.  
  18. extern errno;
  19. extern int h_errno;
  20.  
  21. static int  init= 1;
  22. static int  socki[MAXCONNECTS];
  23. static char sockh[MAXCONNECTS][MAXHOSTNAME+1];
  24.  
  25. static void hinit()
  26. { int a;
  27.  
  28.   for (a= 0; a < MAXCONNECTS; a++)
  29.     socki[a]= -1;
  30.   init= 0;
  31. }
  32.  
  33. int hopen(hostname)
  34. char *hostname;
  35. { struct sockaddr_in sa;
  36.   struct hostent     *hp;
  37.   unsigned long address = 0;
  38.   unsigned long inet_addr();
  39.   int a,i;
  40. #ifdef SECURE_PORT
  41.   int lport = IPPORT_RESERVED - 1;
  42.   int uid;
  43. #endif
  44.  
  45.   if (init)
  46.     hinit();
  47.  
  48.   /* find host table entry
  49.    */
  50.  
  51.   if ((address = inet_addr(hostname)) == (unsigned long) -1) {
  52.     address = 0;
  53.     if((hp= gethostbyname(hostname)) == NULL) {
  54.       errno= ECONNREFUSED;
  55. #ifdef NOHERROR
  56.       h_errno = 1; /* Unknown Host */
  57. #endif
  58.       return(-1);
  59.     }
  60.   }
  61.  
  62.   h_errno = 0;
  63.  
  64.  
  65.   /* see if we're already talking
  66.    */
  67.  
  68.   for (a= 0; (a < MAXCONNECTS) && ((socki[a] == -1) ||
  69.              strcmp(sockh[a], address ? hostname : hp->h_name)); a++)
  70.     ;
  71.   if (a < MAXCONNECTS) /* great!  don't need a connection */
  72.     return(socki[a]);
  73.  
  74.   /* find an empty spot
  75.    */
  76.  
  77.   for (a= 0; (a < MAXCONNECTS) && (socki[a] != -1); a++)
  78.     ;
  79.   if (a >= MAXCONNECTS) {
  80.     errno= EMFILE;
  81.     return(-1);
  82.   }
  83.  
  84.   strcpy(sockh[a],address ? hostname : hp->h_name);
  85.   bzero(&sa,sizeof(sa));
  86.   if (getprotobyname("tcp") == NULL) {
  87.     errno= ENOPROTOOPT;
  88.     return(-1);
  89.   }
  90.   if (address)
  91.     sa.sin_addr.s_addr = address;
  92.   else
  93.     bcopy(hp->h_addr,(char *)&sa.sin_addr,hp->h_length);
  94.   sa.sin_family= address ? AF_INET : hp->h_addrtype;
  95.   i=portnum();
  96.   sa.sin_port= htons((u_short)i);
  97. #ifndef SECURE_PORT
  98.   if ((socki[a]= socket(address ? AF_INET : hp->h_addrtype,SOCK_STREAM,0)) < 0)
  99.     return(-1);
  100. #else
  101.   uid= geteuid();
  102.   seteuid(ROOTUID);
  103.   if((socki[a] = rresvport(&lport)) < 0) {
  104.     seteuid(uid);
  105.     return(-1);
  106.   }
  107.   seteuid(uid);
  108. #endif
  109. #if defined(h_addr)  /* 4.3 or greater system. Has "h_addr_list". */
  110.   while((connect(socki[a],&sa,sizeof sa) < 0)) {
  111.     (void) close(socki[a]);
  112. #ifdef SECURE_PORT
  113.     if (errno == EADDRINUSE) {
  114.       lport--;
  115.       seteuid(ROOTUID);
  116.       if((socki[a] = rresvport(&lport)) < 0) {
  117.     seteuid(uid);
  118.     return(-1);
  119.       }
  120.       seteuid(uid);
  121.       continue;
  122.     }
  123. #endif
  124.     if (address) 
  125.       return(-1);
  126.     if (!hp->h_addr_list[1])
  127.       return(-1);
  128.     hp->h_addr_list++;
  129.     bcopy(hp->h_addr_list[0],&sa.sin_addr,hp->h_length);
  130. #ifndef SECURE_PORT
  131.     if ((socki[a]= socket( hp->h_addrtype,SOCK_STREAM,0)) < 0)
  132.       return(-1);
  133. #else
  134.     seteuid(ROOTUID);
  135.     if((socki[a] = rresvport(&lport)) < 0) {
  136.       seteuid(uid);
  137.       return(-1);
  138.     }
  139.     seteuid(uid);
  140. #endif
  141.   }
  142. #else
  143. #ifdef SECURE_PORT
  144. for(;;) {
  145. #endif
  146.   if (connect(socki[a],&sa,sizeof sa) < 0) {
  147.     (void) close(socki[a]);
  148. #ifndef SECURE_PORT
  149.     return(-1);
  150. #else
  151.     if (errno == EADDRINUSE) {
  152.       lport--;
  153.       seteuid(ROOTUID);
  154.       if((socki[a] = rresvport(&lport)) < 0) {
  155.     seteuid(uid);
  156.     return(-1);
  157.       }
  158.       seteuid(uid);
  159.       continue;
  160.     }
  161.     break;
  162. #endif
  163.   }
  164. }
  165.  
  166. #endif
  167.   /* at this point you should be connected to the host for commands */
  168.  
  169.   return(socki[a]);
  170. }
  171.  
  172. /* close a single network connection
  173.  */
  174.  
  175. void hclose(s)
  176. int s;
  177. { int a;
  178.  
  179.   for (a= 0; (a < MAXCONNECTS) && (socki[a] != s); a++)
  180.   if (a < MAXCONNECTS) {
  181.     close(socki[a]);
  182.     socki[a]= -1;
  183.   }
  184.   else        /* not one of ours, but close it anyway */
  185.     close(s);
  186. }
  187.  
  188. /* this closes all open network connections
  189.  */
  190.  
  191. void hcleanup()
  192. { int     a;
  193.  
  194.   for (a= 0; a < MAXCONNECTS; a++)
  195.     if (socki[a] != -1) {
  196.       close(socki[a]);
  197.       socki[a]= -1;
  198.     }
  199. }
  200.  
  201. int hread(s,buf,n)
  202. int  s;
  203. char *buf;
  204. int  n;
  205. { int bcount,                      /* counts bytes read */
  206.       br;                          /* bytes read this pass */
  207.  
  208.   bcount= 0;
  209.   br= 0;
  210.   while (bcount < n) {             /* loop until full buffer */
  211.     if ((br= read(s,buf,n-bcount)) > 0) {
  212.       bcount += br;                /* increment byte counter */
  213.       buf += br;                   /* move buffer ptr for next read */
  214.     }
  215.     if (br == 0)                    /* EOF */
  216.       return(0);
  217.     if (br < 0)                    /* signal an error to the caller */
  218.       return(-1);
  219.   }
  220.   return(bcount);
  221. }
  222.  
  223. int hwrite(s,buf,n)
  224. int  s;
  225. char *buf;
  226. int  n;
  227. { int bcount,
  228.       bw;
  229.  
  230.   bcount=0;
  231.   while (bcount < n) {
  232.     if ((bw= write(s,buf,n-bcount))>0) {
  233.       bcount += bw;
  234.       buf += bw;
  235.     }
  236.     if (bw < 0)
  237.       return(-1);
  238.   }
  239.   return(bcount);
  240. }
  241.