home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume14 / rn-comments / part01 / checkfrom.c next >
Encoding:
C/C++ Source or Header  |  1990-09-15  |  3.9 KB  |  167 lines

  1. /* checkfrom.c - print information about news article originator. */
  2.  
  3. /* By Eamonn McManus, <em@dce.ie>.  This file is not copyrighted.
  4.  * $Id: checkfrom.c,v 1.2 90/09/11 23:37:39 em Exp $
  5.  *
  6.  * This file contains the checkfrom() function, invoked from (modified) rn
  7.  * after a From: header line to see if the person named is mentioned in the
  8.  * RNPREJUDICE file.  If so, the text for that person is printed, and the
  9.  * number of lines that were printed is returned.  If not, 0 is returned.
  10.  *
  11.  * Each key in the file is on a line of its own,
  12.  * followed by zero or more data lines starting with whitespace.  Lines
  13.  * beginning with # are comments, as are leading indented lines.
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include "config.h"
  21. #ifdef __STDC__
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #undef index
  25. #define index strchr
  26. #else
  27. extern char *malloc();
  28. extern void free();
  29. extern char *getenv();
  30. extern char *index();
  31. #endif
  32.  
  33. typedef char *datum;
  34. #include "stb.h"
  35.  
  36.  
  37. extern char *savestr ARGS((char *str));
  38.  
  39. static stb *db;
  40.  
  41.  
  42. /* Read the file into memory.  Return the number of keys read, or -1 on error.
  43.  */
  44. static int read_file(f)
  45. register FILE *f;
  46. {
  47.     register int c, i;
  48.     int nkeys;
  49.     char key[1024];        /* Hardcoded limits; tough. */
  50.     char data[4096], *datacopy;
  51.     if (db == NULL && (db = stb_new_table()) == NULL)
  52.         return -1;
  53.     nkeys = 0;
  54.     /* Each iteration reads a key and following data. */
  55.     while ((c = getc(f)) != EOF) {
  56.         /* Get the key. */
  57.         for (i = 0; i < sizeof key - 1 && c != '\n'; c = getc(f)) {
  58.             if (c == EOF)
  59.                 return nkeys;
  60.             key[i++] = c;
  61.         }
  62.         if (i == 0 || key[0] == '#' || isspace(key[0]))
  63.             continue;
  64.         key[i] = '\0';
  65.         /* Get the data. */
  66.         i = 0;
  67.         /* Read the indented lines. */
  68.         while (isspace(c = getc(f))) {
  69.             /* Read a line. */
  70.             while (1) {
  71.                 if (c == EOF)
  72.                     return nkeys;
  73.                 if (i < sizeof data - 1)
  74.                     data[i++] = c;
  75.                 if (c == '\n')
  76.                     break;
  77.                 c = getc(f);
  78.             }
  79.         }
  80.         (void) ungetc(c, f);
  81.         data[i] = '\0';
  82.         datacopy = savestr(data);
  83.         if (stb_insert(db, key, &datacopy) == NULL) {
  84.             free(datacopy);
  85.         } else nkeys++;
  86.     }
  87.     return nkeys;
  88. }
  89.  
  90.  
  91. /* Action function for stb_free_tree. */
  92. static int sfree(p)
  93. char *p;
  94. {
  95.     free(p);
  96.     return 0;
  97. }
  98.  
  99.  
  100. /* See if the electronic address in the fromline appears in the prejudice
  101.  * database.  If so, print the indented lines that follow.  Return the
  102.  * number of lines printed.  The string pointed to by fromline is modified.
  103.  */
  104. int checkfrom(fromline)
  105. register char *fromline;
  106. {
  107.     register char *p, *dbname;
  108.     register stb_node *s;
  109.     int lines, t;
  110.     static char beenhere;
  111.     static FILE *f;
  112.     static time_t mtime;
  113.     struct stat st;
  114.     /* Slurp in the database if we haven't already, or if it has been
  115.      * modified since we read it.
  116.      */
  117.     if (beenhere) {
  118.         if (f == NULL)
  119.             return 0;
  120.         if ((t = fstat(fileno(f), &st)) < 0 || st.st_mtime > mtime) {
  121.             (void) stb_free_table(db, sfree); db = NULL;
  122.             if (t < 0) {
  123.                 fclose(f); f = NULL;
  124.                 return 0;
  125.             } else {
  126.                 rewind(f);
  127.                 mtime = st.st_mtime;
  128.                 beenhere = 0;
  129.             }
  130.         }
  131.     } else {
  132.         if ((dbname = getenv("RNPREJUDICE")) == NULL)
  133.             return 0;
  134.         if ((f = fopen(dbname, "r")) == NULL ||
  135.             fstat(fileno(f), &st) < 0) {
  136.             printf("[Could not open RNPREJUDICE=\"%s\"]\n", dbname);
  137.             f = NULL;
  138.             return 1;
  139.         }
  140.         mtime = st.st_mtime;
  141.     }
  142.     if (!beenhere) {
  143.         beenhere++;
  144.         if (read_file(f) < 0) {
  145.             printf("[Format error in $RNPREJUDICE]\n");
  146.             fclose(f); f = NULL;
  147.             return 1;
  148.         }
  149.     }
  150.     /* Isolate the address part of the from line.  Skip the initial
  151.      * "From:" as well as any trailing stuff (usually the personal
  152.      * name comment).
  153.      */
  154.     for ( ; *fromline && !isspace(*fromline); fromline++) ;
  155.     for ( ; isspace(*fromline); fromline++) ;
  156.     for (p = fromline; *p && !isspace(*p); p++) ;
  157.     if (p == fromline)
  158.         return 0;
  159.     *p = '\0';
  160.     if ((s = stb_lookup(db, fromline)) == NULL)
  161.         return 0;
  162.     fputs(s->datum, stdout);
  163.     for (lines = 0, p = s->datum; (p = index(p, '\n')) != NULL;
  164.          lines++, p++) ;
  165.     return lines;
  166. }
  167.