1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
/*
** SIGNOFF
** Quickie hack to see of a mail message is a "please drop me" request.
** Exit's with status 0 if it is a regular message, or 1 if it appears to
** be a one of this administrative requests that annoy everyone when
** they're sent to the whole list. Optional first argument is the name
** of the input file, or stdin is read if none is given.
**
** Original program written by Russ Nelson, <nelson@clutx.clarkson.edu>.
** Severely hacked on by Rich $alz, <rsalz@bbn.com>. This program is
** basically incorporated into mail2news; it's pulled out here for
** demonstration.
**
** For example, here is a script that could be used as a wrapper around
** the mail2news program:
** #! /bin/sh
** cat >/tmp/signoff$$
** if /usr/bin/signoff </tmp/signoff$$ ; then
** /usr/bin/Mail -s "Sign on/off request" usenet </tmp/signoff$$
** else
** /usr/bin/mail2news </tmp/signoff$$
** fi
** exec rm /tmp/signoff$$
**
** Russ ran the following test for a month and got only one real message
** (a gnu.gcc bug report) treated as a subscription request. He doesn't
** know how many subs made it out to the net, tho: that would entail
** reading ALL netnews articles -- yuck!
**
** Put the following line in your news sys file:
** allmail:all::/usr/local/bin/ts
** here is the "ts" script:
** #! /bin/sh
** cat >/tmp/ts.$$
** /usr/bin/signoff </tmp/ts.$$ || mail usenet </tmp/ts.$$
** exec rm /tmp/ts.$$
**
** Perhaps a better way to test is to make the test less conservative,
** and see what "real" articles get caught, and make adjustments then?
** Comments solicited.
*/
#include <stdio.h>
#include <ctype.h>
#define EQ(a, b) (strcmp((a), (b)) == 0)
int
main(ac, av)
int ac;
char *av[];
{
register FILE *F;
register char *p;
register int c;
register int AddDrop;
register int FromTo;
register int MailWord;
register int count;
char word[128];
/* Get input. */
if (ac < 2)
F = stdin;
else if ((F = fopen(av[1], "r")) == NULL) {
(void)fprintf(stderr, "%s: cannot open %s\n", av[0], av[1]);
exit(1);
}
/* Skip headers by waiting for the first blank line. */
while (fgets(word, sizeof word, F) && *word != '\n')
continue;
/* Clear counts. */
AddDrop = 0;
FromTo = 0;
MailWord = 0;
count = 0;
/* Read input a word at a time. */
for (p = word; (c = getc(F)) != EOF; ) {
if (!isalpha(c)) {
*p = '\0';
if (p > word)
count++;
p = word;
if (EQ(word, "remove") || EQ(word, "drop") || EQ(word, "off")
|| EQ(word, "subscribe") || EQ(word, "get") || EQ(word, "add"))
AddDrop++;
else if (EQ(word, "from") || EQ(word, "to"))
FromTo++;
else if (EQ(word, "mail") || EQ(word, "mailing")
|| EQ(word, "list") || EQ(word, "dl"))
MailWord++;
}
else if (p < &word[sizeof word - 1])
*p++ = isupper(c) ? tolower(c) : c;
}
(void)fclose(F);
/* Use fancy-shmancy AI techniques to determine what the message is. */
c = count < 25 && AddDrop && FromTo && MailWord;
#if defined(DEBUG)
printf("%s: %d words, %d drop, %d mail --> %s\n",
av[1] ? av[1] : "<stdin>",
count, AddDrop, MailWord,
c ? "yes" : "no");
#endif /* defined(DEBUG) */
/* Exit appropriately. */
exit(c ? 0 : 1);
return c ? 0 : 1;
}
|