home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / vsoup128.zip / util.cc < prev    next >
C/C++ Source or Header  |  1997-01-20  |  5KB  |  249 lines

  1. //  $Id: util.cc 1.13 1997/01/20 16:34:50 hardy Exp $
  2. //
  3. //  This progam/module was written by Hardy Griech based on ideas and
  4. //  pieces of code from Chin Huang (cthuang@io.org).  Bug reports should
  5. //  be submitted to rgriech@ibm.net.
  6. //
  7. //  This file is part of soup++ for OS/2.  Soup++ including this file
  8. //  is freeware.  There is no warranty of any kind implied.  The terms
  9. //  of the GNU Gernal Public Licence are valid for this piece of software.
  10. //
  11. //  NNTP client routines
  12. //
  13.  
  14.  
  15. #include <assert.h>
  16. #include <ctype.h>
  17. #include <fcntl.h>
  18. #include <io.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <sys/nls.h>
  23.  
  24. #include "mts.hh"
  25. #include "util.hh"
  26.  
  27.  
  28.  
  29. unsigned hashi( const char *src, unsigned tabSize )
  30. {
  31.     unsigned long res = 0;
  32.     const char *p;
  33.     const unsigned long maxbit  = 0x40000000;   // needs 32bits
  34.     const unsigned long maxmask = maxbit - 1;
  35.  
  36.     for (p = src;  *p != '\0';  ++p) {
  37.     res = (res << 1) ^ _nls_tolower(*p);
  38.     if (res >= maxbit)
  39.         res = (res & maxmask) ^ 0x00000001;
  40.     }
  41.     return res % tabSize;
  42. }   // hashi
  43.  
  44.  
  45.  
  46. int nhandles( int depth )
  47. //
  48. //  directly taken from EMs emx/test/nfiles.c
  49. //  depth is required as a break condition
  50. //
  51. {
  52.     int h, i;
  53.  
  54.     assert( _heapchk() == _HEAPOK );
  55. #ifdef TRACE_ALL
  56.     printfT( "nhandles(%d)\n",depth );
  57. #endif
  58.  
  59.     h = open("nul", O_RDONLY);
  60.     if (h < 0)
  61.     return 0;
  62.     i = (depth > 1) ? nhandles(depth-1) + 1 : 1;
  63.     close (h);
  64.     return i;
  65. }   // nhandles
  66.  
  67.  
  68.  
  69. int isHeader( const char *buf, const char *header )
  70. //
  71. //  according to RFC1036:
  72. //  Each header line consist of a keyword, a colon, a blank, and 
  73. //  some additional information.
  74. //
  75. {
  76.     size_t len = strlen(header);
  77.     return strnicmp(buf, header, len) == 0  &&  buf[len] == ':'  &&
  78.     (buf[len+1] == ' ' || buf[len+1] == '\t');
  79. }   // isHeader
  80.  
  81.  
  82.  
  83. const char *getHeader( TFile &handle, const char *headerField )
  84. //
  85. //  get the value for the message header field (NULL, if not found)
  86. //  the memory for the result is allocated from the heap!
  87. //  handle is the file that contains header/message info
  88. //  on return the file is positioned to its original position
  89. //
  90. {
  91.     char buf[BUFSIZ];
  92.     char *result;
  93.     long offset;
  94.     int headerFieldLen, n;
  95.  
  96.     /* Remember file position */
  97.     offset = handle.tell();
  98.  
  99.     headerFieldLen = strlen(headerField);
  100.  
  101.     //
  102.     //  Look through header
  103.     //
  104.     while (handle.fgets(buf,sizeof(buf),1)) {
  105.     //
  106.     //  end of header ?
  107.     //
  108.     if (buf[0] == '\0')
  109.         break;
  110.  
  111.     //
  112.     //  is there a match with headerField
  113.     //
  114.     if (isHeader(buf,headerField)) {
  115.         //
  116.         //  yes -> allocate memory for result and copy info of headerField
  117.         //         to result
  118.         //
  119.         n = strlen(buf + headerFieldLen + 2);
  120.         result = (char *)xstrdup(buf+headerFieldLen+2);
  121.         handle.seek(offset, SEEK_SET);          //  reposition file
  122.         return result;
  123.     }
  124.     }       
  125.  
  126.     //
  127.     //  Reposition file
  128.     //
  129.     handle.seek(offset, SEEK_SET);
  130.     return NULL;
  131. }   // getHeader
  132.  
  133.  
  134.  
  135. const char *extractAddress( const char *src )
  136. //
  137. //  Extract mail address from the string.
  138. //  Return a pointer to buffer on the heap containing the address or
  139. //  NULL on an error.
  140. //
  141. {
  142.     char buf[BUFSIZ];
  143.     char ch, *put;
  144.     const char *get;
  145.     char gotAddress;
  146.  
  147.     gotAddress = 0;
  148.     put = buf;
  149.     if ((get = strchr(src, '<')) != 0) {
  150.     char ch = *++get;
  151.     while (ch != '>' && ch != '\0') {
  152.         *put++ = ch;
  153.         ch = *++get;
  154.     }
  155.     gotAddress = 1;
  156.     } else {
  157.     get = src;
  158.     ch = *get++;
  159.  
  160.     /* Skip leading whitespace. */
  161.     while (ch != '\0' && isspace(ch))
  162.         ch = *get++;
  163.  
  164.     while (ch != '\0') {
  165.         if (isspace(ch)) {
  166.         ch = *get++;
  167.  
  168.         } else if (ch == '(') {
  169.         /* Skip comment. */
  170.         int nest = 1;
  171.         while (nest > 0 && ch != '\0') {
  172.             ch = *get++;
  173.  
  174.             if (ch == '(')
  175.             ++nest;
  176.             else if (ch == ')')
  177.             --nest;
  178.         }
  179.  
  180.         if (ch == ')') {
  181.             ch = *get++;
  182.         }
  183.  
  184.         } else if (ch == '"') {
  185.         /* Copy quoted string. */
  186.         do {
  187.             *put++ = ch;
  188.             ch = *get++;
  189.         } while (ch != '"' && ch != '\0');
  190.  
  191.         if (ch == '"') {
  192.             *put++ = ch;
  193.             ch = *get++;
  194.         }
  195.  
  196.         } else {
  197.         /* Copy address. */
  198.         while (ch != '\0' && ch != '(' && !isspace(ch)) {
  199.             *put++ = ch;
  200.             ch = *get++;
  201.         }
  202.         gotAddress = 1;
  203.         }
  204.     }
  205.     }
  206.  
  207.     if (gotAddress) {
  208.     *put = '\0';
  209.     return xstrdup( buf );
  210.     } else {
  211.     return NULL;
  212.     }
  213. }   // extractAddress
  214.  
  215.  
  216.  
  217. char *findAddressSep( const char *src )
  218. //
  219. //  Search for ',' separating addresses.
  220. //
  221. {
  222.     char ch, matchCh;
  223.  
  224.     ch = *src; 
  225.     while (ch != '\0' && ch != ',') {
  226.         if (ch == '"') {
  227.             matchCh = '"';
  228.         } else if (ch == '(') {
  229.             matchCh = ')';
  230.         } else if (ch == '<') {
  231.             matchCh = '>';
  232.         } else {
  233.             matchCh = '\0';
  234.         }
  235.  
  236.         if (matchCh) {
  237.             do {
  238.                 ch = *(++src);
  239.             } while (ch != '\0' && ch != matchCh);
  240.  
  241.             if (ch == '\0')
  242.                 break;
  243.         }
  244.         ch = *(++src);
  245.     }
  246.  
  247.     return (char *)src;
  248. }   // findAdressSep
  249.