home *** CD-ROM | disk | FTP | other *** search
- /* checkfrom.c - print information about news article originator. */
-
- /* By Eamonn McManus, <em@dce.ie>. This file is not copyrighted.
- * $Id: checkfrom.c,v 1.2 90/09/11 23:37:39 em Exp $
- *
- * This file contains the checkfrom() function, invoked from (modified) rn
- * after a From: header line to see if the person named is mentioned in the
- * RNPREJUDICE file. If so, the text for that person is printed, and the
- * number of lines that were printed is returned. If not, 0 is returned.
- *
- * Each key in the file is on a line of its own,
- * followed by zero or more data lines starting with whitespace. Lines
- * beginning with # are comments, as are leading indented lines.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "config.h"
- #ifdef __STDC__
- #include <stdlib.h>
- #include <string.h>
- #undef index
- #define index strchr
- #else
- extern char *malloc();
- extern void free();
- extern char *getenv();
- extern char *index();
- #endif
-
- typedef char *datum;
- #include "stb.h"
-
-
- extern char *savestr ARGS((char *str));
-
- static stb *db;
-
-
- /* Read the file into memory. Return the number of keys read, or -1 on error.
- */
- static int read_file(f)
- register FILE *f;
- {
- register int c, i;
- int nkeys;
- char key[1024]; /* Hardcoded limits; tough. */
- char data[4096], *datacopy;
- if (db == NULL && (db = stb_new_table()) == NULL)
- return -1;
- nkeys = 0;
- /* Each iteration reads a key and following data. */
- while ((c = getc(f)) != EOF) {
- /* Get the key. */
- for (i = 0; i < sizeof key - 1 && c != '\n'; c = getc(f)) {
- if (c == EOF)
- return nkeys;
- key[i++] = c;
- }
- if (i == 0 || key[0] == '#' || isspace(key[0]))
- continue;
- key[i] = '\0';
- /* Get the data. */
- i = 0;
- /* Read the indented lines. */
- while (isspace(c = getc(f))) {
- /* Read a line. */
- while (1) {
- if (c == EOF)
- return nkeys;
- if (i < sizeof data - 1)
- data[i++] = c;
- if (c == '\n')
- break;
- c = getc(f);
- }
- }
- (void) ungetc(c, f);
- data[i] = '\0';
- datacopy = savestr(data);
- if (stb_insert(db, key, &datacopy) == NULL) {
- free(datacopy);
- } else nkeys++;
- }
- return nkeys;
- }
-
-
- /* Action function for stb_free_tree. */
- static int sfree(p)
- char *p;
- {
- free(p);
- return 0;
- }
-
-
- /* See if the electronic address in the fromline appears in the prejudice
- * database. If so, print the indented lines that follow. Return the
- * number of lines printed. The string pointed to by fromline is modified.
- */
- int checkfrom(fromline)
- register char *fromline;
- {
- register char *p, *dbname;
- register stb_node *s;
- int lines, t;
- static char beenhere;
- static FILE *f;
- static time_t mtime;
- struct stat st;
- /* Slurp in the database if we haven't already, or if it has been
- * modified since we read it.
- */
- if (beenhere) {
- if (f == NULL)
- return 0;
- if ((t = fstat(fileno(f), &st)) < 0 || st.st_mtime > mtime) {
- (void) stb_free_table(db, sfree); db = NULL;
- if (t < 0) {
- fclose(f); f = NULL;
- return 0;
- } else {
- rewind(f);
- mtime = st.st_mtime;
- beenhere = 0;
- }
- }
- } else {
- if ((dbname = getenv("RNPREJUDICE")) == NULL)
- return 0;
- if ((f = fopen(dbname, "r")) == NULL ||
- fstat(fileno(f), &st) < 0) {
- printf("[Could not open RNPREJUDICE=\"%s\"]\n", dbname);
- f = NULL;
- return 1;
- }
- mtime = st.st_mtime;
- }
- if (!beenhere) {
- beenhere++;
- if (read_file(f) < 0) {
- printf("[Format error in $RNPREJUDICE]\n");
- fclose(f); f = NULL;
- return 1;
- }
- }
- /* Isolate the address part of the from line. Skip the initial
- * "From:" as well as any trailing stuff (usually the personal
- * name comment).
- */
- for ( ; *fromline && !isspace(*fromline); fromline++) ;
- for ( ; isspace(*fromline); fromline++) ;
- for (p = fromline; *p && !isspace(*p); p++) ;
- if (p == fromline)
- return 0;
- *p = '\0';
- if ((s = stb_lookup(db, fromline)) == NULL)
- return 0;
- fputs(s->datum, stdout);
- for (lines = 0, p = s->datum; (p = index(p, '\n')) != NULL;
- lines++, p++) ;
- return lines;
- }
-