home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
-
- #include "headers.h"
-
- //
- // These variables are set by ScanAndLoadHeaders() -- however, it is
- // the caller's responsibility to ENSURE that they are valid.
- // The caller should set the requested pointers to NULL prior to
- // calling the routine.
- //
- char
- *Date,
- *Distribution,
- *Followup_To,
- *From,
- *Message_ID,
- *Newsgroups,
- *Organization,
- *Path,
- *References,
- *Reply_To,
- *Subject,
- *To,
- *X_NewsSoftware;
-
- // options for ScanAndLoadHeaders() --
- // Don't close the article file, return the fd as the result value.
- #ifndef OPT_DONT_CLOSE
- #define OPT_DONT_CLOSE 1
- #endif
-
- #define IF_HEADER(header_def, header_str, header_length, header_dest) \
- if ((headers & header_def) && \
- STREQN (p, header_str, header_length)) { \
- header_dest = p + header_length; \
- }
-
- char *header_buf; // buffer used by ScanAndLoadHeaders()
- int header_size; // size of header_buf
- int header_len; // length of header (until double newline)
-
- void AllocHeaderBuf (int size)
- {
- if (size == 0 && header_buf) {
- free (header_buf);
- header_buf = NULL;
- header_size = 0;
- return;
- }
- if (size <= header_size)
- // ignore it
- return;
- header_size = size;
- header_buf = malloc (size);
- return;
- }
-
- // the header munging routine
- int ScanAndLoadHeaders (const char *filename,
- const unsigned long headers,
- const unsigned long opt)
- {
- int fd;
- int len;
- extern int errno;
- register char *p;
- register char *bufe;
-
- // FIXME: Deal with LWSP (linear white space) in headers, esp. Refs
-
- // FIXME: We really should be using BPTR FileHandles to
- // get the best performance
-
- if ((fd = open (filename, O_RDONLY)) < 0)
- return -1;
- if (!header_buf)
- AllocHeaderBuf (MAX_HEADER_SIZE + 1);
-
- len = read (fd, header_buf, MAX_HEADER_SIZE);
- header_buf [len] = '\0';
-
- if (!(opt & OPT_DONT_CLOSE)) {
- close (fd);
- fd = 0;
- }
-
- if (!(bufe = strstr (header_buf, "\n\n"))) {
- // No empty line in the buffer.
- close (fd);
- header_len = 0;
- return -3;
- }
- bufe++; // point to separating newline
- p = header_buf; // register variable is faster...
-
- header_len = bufe - header_buf;
-
- while (p < bufe) {
- switch (*p) {
- case 'D':
- IF_HEADER (HEADER_DATE,
- "Date: ", 6, Date)
- else
- IF_HEADER (HEADER_DISTRIBUTION,
- "Distribution: ", 14, Distribution);
- break;
- case 'F':
- IF_HEADER (HEADER_FOLLOWUP_TO,
- "Followup-To: ", 13, Followup_To)
- else
- IF_HEADER (HEADER_FROM,
- "From: ", 6, From);
- break;
- case 'M':
- IF_HEADER (HEADER_MESSAGE_ID,
- "Message-ID: ", 12, Message_ID);
- break;
- case 'N':
- IF_HEADER (HEADER_NEWSGROUPS,
- "Newsgroups: ", 12, Newsgroups);
- break;
- case 'O':
- IF_HEADER (HEADER_ORGANIZATION,
- "Organization: ", 14, Organization);
- break;
- case 'P':
- IF_HEADER (HEADER_PATH,
- "Path: ", 6, Path);
- break;
- case 'R':
- IF_HEADER (HEADER_REPLY_TO,
- "Reply-To: ", 10, Reply_To)
- else
- IF_HEADER (HEADER_REFERENCES,
- "References: ", 12, References);
- break;
- case 'S':
- IF_HEADER (HEADER_SUBJECT,
- "Subject: ", 9, Subject);
- break;
- case 'T':
- IF_HEADER (HEADER_TO,
- "To: ", 4, To);
- break;
- case 'X':
- IF_HEADER (HEADER_X_NEWSSOFTWARE,
- "X-NewsSoftware: ", 16, X_NewsSoftware);
- break;
- }
- while (*p != '\n')
- p++;
- *p = '\0';
- p++;
- }
-
- return fd;
- }
-