home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / gopher / gopher1.01 / object / util.c < prev    next >
C/C++ Source or Header  |  1992-04-29  |  6KB  |  320 lines

  1. /*
  2.  * Various useful utilities for gopher clients and servers
  3.  *
  4.  */
  5.  
  6. #include "Malloc.h"
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "boolean.h"
  10. #include "util.h"
  11.  
  12.  
  13. /* Read "n" bytes from a descriptor.
  14.  * Use in place of read() when fd is a stream socket
  15.  *
  16.  * Returns the number of total bytes read.
  17.  */
  18.  
  19. int readn(fd, ptr, nbytes)
  20.   int fd;
  21.   char *ptr;
  22.   int nbytes;
  23. {
  24.      int nleft, nread;
  25.      
  26.      nleft = nbytes;
  27.      while (nleft > 0) {
  28.       nread = read(fd, ptr, nleft);
  29.       if (nread < 0)
  30.            return(nread);    /* error, return <0 */
  31.       else if (nread == 0)    /* EOF */
  32.            break;
  33.       
  34.       nleft     -= nread;
  35.       ptr     += nread;
  36.      }
  37.      return(nbytes - nleft);    /* return >= 0) */
  38. }
  39.  
  40.  
  41.  
  42. /*
  43.  * Write "n" bytes to a descriptor.
  44.  * Use in place of write() when fd is a stream socket
  45.  *
  46.  * We return the number of bytes written
  47.  */
  48.  
  49. int 
  50. writen(fd, ptr, nbytes)
  51.   int    fd;
  52.   char    *ptr;
  53.   int    nbytes;
  54. {
  55.      int nleft, nwritten;
  56.      
  57.      nleft = nbytes;
  58.      while(nleft > 0) {
  59.       nwritten = write(fd, ptr, nleft);
  60.       if (nwritten <= 0)
  61.            return(nwritten);    /* error */
  62.       
  63.       nleft    -= nwritten;
  64.       ptr    += nwritten;
  65.      }
  66.      return(nbytes - nleft);
  67. }
  68.  
  69.  
  70. /*
  71.  * Writestring uses the writen and strlen calls to write a
  72.  * string to the file descriptor fd.  If the write fails
  73.  * a -1 is returned. Otherwise zero is returned.
  74.  */
  75.  
  76. int writestring(fd, stringptr)
  77.   int    fd;
  78.   char    *stringptr;
  79. {
  80.      int length;
  81.      
  82.      length = strlen(stringptr);
  83.      if (writen(fd, stringptr, length) != length) {
  84.       return(-1);
  85.      }
  86.      else
  87.       return(0);
  88. }
  89.  
  90.  
  91. /*
  92.  * Read a line from a descriptor.  Read the line one byte at a time,
  93.  * looking for the newline.  We store the newline in the buffer,
  94.  * then follow it with a null (the same as fgets(3)).
  95.  * We return the number of characters up to, but not including,
  96.  * the null (the same as strlen(3))
  97.  */
  98.  
  99. int readline(fd, ptr, maxlen)
  100.   int    fd;
  101.   char    *ptr;
  102.   int     maxlen;
  103. {
  104.      int n;
  105.      int rc;
  106.      char c;
  107.      
  108.      for (n=1; n < maxlen; n++) {
  109.       if ( (rc = read(fd, &c, 1)) == 1) {
  110.            *ptr++ = c;
  111.            if (c == '\n')
  112.             break;
  113.       }
  114.       else if (rc == 0) {
  115.            if (n == 1)
  116.             return(0);    /* EOF, no data read */
  117.            else
  118.             break;        /* EOF, some data was read */
  119.       }
  120.       else
  121.            return(-1);        /* error */
  122.      }
  123.      
  124.      *ptr = 0;                 /* Tack a NULL on the end */
  125.      return(n);
  126. }
  127.  
  128. /*
  129.  * Readfield reads data up to a tab, (like readline above)
  130.  */
  131.  
  132. int 
  133. readfield(fd, ptr, maxlen)
  134.   int    fd;
  135.   char    *ptr;
  136.   int     maxlen;
  137. {
  138.      int n;
  139.      int rc;
  140.      char c;
  141.      
  142.      for (n=1; n < maxlen; n++) {
  143.       if ( (rc = read(fd, &c, 1)) == 1) {
  144.            *ptr++ = c;
  145.            if (c == '\t') {
  146.             *(ptr - 1) = '\0';
  147.             break;
  148.            }
  149.       }
  150.       else if (rc == 0) {
  151.            if (n == 1)
  152.             return(0);    /* EOF, no data read */
  153.            else
  154.             break;        /* EOF, some data was read */
  155.       }
  156.       else
  157.            return(-1);        /* error */
  158.      }
  159.      
  160.      *ptr = 0;                 /* Tack a NULL on the end */
  161.      return(n);
  162. }
  163.  
  164.  
  165. int
  166. sreadword(input, output, maxlen)
  167.   char *input;
  168.   char *output;
  169.   int maxlen;
  170. {
  171.      int n;
  172.      char c;
  173.      
  174.      for (n=0; n < maxlen; n++) {
  175.       c = *input++;
  176.       *output++ = c;
  177.       if (isspace(c)) {
  178.            *(output - 1) = '\0';
  179.            break;
  180.       }
  181.       
  182.       if (c == '\0') {
  183.            break;
  184.       }
  185.      }
  186.      
  187.      *output = '\0';                 /* Tack a NULL on the end */
  188.      return(n);
  189. }
  190.  
  191.  
  192. /*
  193.  * ZapCRLF removes all carriage returns and linefeeds from a C-string.
  194.  */
  195.  
  196. void
  197. ZapCRLF(inputline)
  198.   char *inputline;
  199. {
  200.      char *cp;
  201.  
  202.      cp = strchr(inputline, '\r');    /* Zap CR-LF */
  203.      if (cp != NULL)
  204.       *cp = '\0';
  205.      else {
  206.       cp = strchr(inputline, '\n');
  207.       if (cp != NULL)
  208.            *cp = '\0';
  209.      }
  210. }
  211.  
  212. /*
  213.  *  Utilities for dealing with HTML junk
  214.  */
  215.  
  216. static boolean acceptable[256];
  217. static boolean acceptable_inited = FALSE;
  218.  
  219. void init_acceptable()
  220. {
  221.     unsigned int i;
  222.     char * good = 
  223.       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./-_$";
  224.     for(i=0; i<256; i++) acceptable[i] = FALSE;
  225.     for(;*good; good++) acceptable[(unsigned int)*good] = TRUE;
  226.     acceptable_inited = TRUE;
  227. }
  228.  
  229. static char hex[17] = "0123456789abcdef";
  230.  
  231. char from_hex(c)
  232.   char c;
  233. {
  234.      return (c>='0')&&(c<='9') ? c-'0'
  235.       : (c>='A')&&(c<='F') ? c-'A'+10
  236.            : (c>='a')&&(c<='f') ? c-'a'+10
  237.             :                      0;
  238. }
  239.  
  240.  
  241. /*
  242.  * Finds out if a character is printable & non white space.
  243.  * if it is, then return a hex encoding of the char,
  244.  * otherwise, just return a reference to the character
  245.  */
  246.  
  247. char *to_hex(c)
  248.   char c;
  249. {
  250.      static char out[4];
  251.  
  252.      if (acceptable_inited == FALSE)
  253.       init_acceptable();
  254.  
  255.      out[0] = '\0';
  256.  
  257.      if (acceptable[c] == TRUE) {
  258.       out[0] = c;
  259.       out[1] = '\0';
  260.      }
  261.      else {
  262.       out[0]='%';
  263.       out[1]=hex[c >> 4];
  264.       out[2]=hex[c & 15];
  265.       out[3]='\0';
  266.      }
  267. }
  268.      
  269. /*
  270.  * Replace hex escape sequences with the proper codes...
  271.  *
  272.  * input and output can be the same if you want
  273.  */
  274.  
  275. void
  276. Fromhexstr(input, output)
  277.   char *input, *output;
  278. {
  279.      char c;
  280.      unsigned int b;
  281.  
  282.      while (*input) {
  283.       if (*input == '%') {
  284.            input++;
  285.            c = *input++;
  286.            b = from_hex(c);
  287.            c = *input++;
  288.            if (!c) break;
  289.            *output++ = (b<<4) + from_hex(c);
  290.       }
  291.       else 
  292.            *output++ = *input++;
  293.      }
  294.      *output = '\0';
  295. }
  296.       
  297. void
  298. Tohexstr(input, output)
  299.   char *input, *output;
  300. {
  301.  
  302.      if (acceptable_inited == FALSE)
  303.       init_acceptable();
  304.      
  305.      while (*input) {
  306.  
  307.       if (acceptable[*input] == TRUE) {
  308.            *output++ = *input++;
  309.       }
  310.       else {
  311.            *output++ = '%';
  312.            *output++ = hex[*input >> 4];
  313.            *output++ = hex[*input & 15];
  314.            input++;
  315.       }
  316.      }
  317.  
  318.      *output = '\0';
  319. }
  320.