home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / network / grn1src.lha / headers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-29  |  5.5 KB  |  160 lines

  1. #include <stdlib.h>
  2. #include <fcntl.h>
  3. #include <string.h>
  4.  
  5. #include "headers.h"
  6.  
  7. //
  8. //      These variables are set by ScanAndLoadHeaders() -- however, it is
  9. //      the caller's responsibility to ENSURE that they are valid.
  10. //      The caller should set the requested pointers to NULL prior to
  11. //      calling the routine.
  12. //
  13. char
  14.         *Date,
  15.         *Distribution,
  16.         *Followup_To,
  17.         *From,
  18.         *Message_ID,
  19.         *Newsgroups,
  20.         *Organization,
  21.         *Path,
  22.         *References,
  23.         *Reply_To,
  24.         *Subject,
  25.         *To,
  26.         *X_NewsSoftware;
  27.  
  28. // options for ScanAndLoadHeaders() --
  29. // Don't close the article file, return the fd as the result value.
  30. #ifndef OPT_DONT_CLOSE
  31. #define OPT_DONT_CLOSE                  1
  32. #endif
  33.  
  34. #define IF_HEADER(header_def, header_str, header_length, header_dest)       \
  35.                         if ((headers & header_def) &&                       \
  36.                             STREQN (p, header_str, header_length)) {        \
  37.                                 header_dest = p + header_length;            \
  38.                         }
  39.  
  40. char *header_buf;       // buffer used by ScanAndLoadHeaders()
  41. int header_size;        // size of header_buf
  42. int header_len;         // length of header (until double newline)
  43.  
  44. void AllocHeaderBuf (int size)
  45. {
  46.         if (size == 0 && header_buf) {
  47.                 free (header_buf);
  48.                 header_buf = NULL;
  49.                 header_size = 0;
  50.                 return;
  51.         }
  52.         if (size <= header_size)
  53.                 // ignore it
  54.                 return;
  55.         header_size = size;
  56.         header_buf = malloc (size);
  57.         return;
  58. }
  59.  
  60. // the header munging routine
  61. int ScanAndLoadHeaders (const char *filename,
  62.                         const unsigned long headers,
  63.                         const unsigned long opt)
  64. {
  65.         int fd;
  66.         int len;
  67.         extern int errno;
  68.         register char *p;
  69.         register char *bufe;
  70.  
  71.         // FIXME: Deal with LWSP (linear white space) in headers, esp. Refs
  72.  
  73.         // FIXME: We really should be using BPTR FileHandles to
  74.         //        get the best performance
  75.  
  76.         if ((fd = open (filename, O_RDONLY)) < 0)
  77.                 return -1;
  78.         if (!header_buf)
  79.                 AllocHeaderBuf (MAX_HEADER_SIZE + 1);
  80.  
  81.         len = read (fd, header_buf, MAX_HEADER_SIZE);
  82.         header_buf [len] = '\0';
  83.  
  84.         if (!(opt & OPT_DONT_CLOSE)) {
  85.                 close (fd);
  86.                 fd = 0;
  87.         }
  88.  
  89.         if (!(bufe = strstr (header_buf, "\n\n"))) {
  90.                 // No empty line in the buffer.
  91.                 close (fd);
  92.                 header_len = 0;
  93.                 return -3;
  94.         }
  95.         bufe++;         // point to separating newline
  96.         p = header_buf; // register variable is faster...
  97.  
  98.         header_len = bufe - header_buf;
  99.  
  100.         while (p < bufe) {
  101.                 switch (*p) {
  102.                         case 'D':
  103.                                 IF_HEADER (HEADER_DATE,
  104.                                            "Date: ", 6, Date)
  105.                                 else
  106.                                 IF_HEADER (HEADER_DISTRIBUTION,
  107.                                            "Distribution: ", 14, Distribution);
  108.                                 break;
  109.                         case 'F':
  110.                                 IF_HEADER (HEADER_FOLLOWUP_TO,
  111.                                            "Followup-To: ", 13, Followup_To)
  112.                                 else
  113.                                 IF_HEADER (HEADER_FROM,
  114.                                            "From: ", 6, From);
  115.                                 break;
  116.                         case 'M':
  117.                                 IF_HEADER (HEADER_MESSAGE_ID,
  118.                                            "Message-ID: ", 12, Message_ID);
  119.                                 break;
  120.                         case 'N':
  121.                                 IF_HEADER (HEADER_NEWSGROUPS,
  122.                                            "Newsgroups: ", 12, Newsgroups);
  123.                                 break;
  124.                         case 'O':
  125.                                 IF_HEADER (HEADER_ORGANIZATION,
  126.                                            "Organization: ", 14, Organization);
  127.                                 break;
  128.                         case 'P':
  129.                                 IF_HEADER (HEADER_PATH,
  130.                                            "Path: ", 6, Path);
  131.                                 break;
  132.                         case 'R':
  133.                                 IF_HEADER (HEADER_REPLY_TO,
  134.                                            "Reply-To: ", 10, Reply_To)
  135.                                 else
  136.                                 IF_HEADER (HEADER_REFERENCES,
  137.                                            "References: ", 12, References);
  138.                                 break;
  139.                         case 'S':
  140.                                 IF_HEADER (HEADER_SUBJECT,
  141.                                            "Subject: ", 9, Subject);
  142.                                 break;
  143.                         case 'T':
  144.                                 IF_HEADER (HEADER_TO,
  145.                                            "To: ", 4, To);
  146.                                 break;
  147.                         case 'X':
  148.                                 IF_HEADER (HEADER_X_NEWSSOFTWARE,
  149.                                            "X-NewsSoftware: ", 16, X_NewsSoftware);
  150.                                 break;
  151.                 }
  152.                 while (*p != '\n')
  153.                         p++;
  154.                 *p = '\0';
  155.                 p++;
  156.         }
  157.  
  158.         return fd;
  159. }
  160.