home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i068: ELM mail syste, release 2.3, Part09/26
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 6ea2f43a 59ab3060 4770da06 e5fc5cb9
- Supercedes: <2580@papaya.bbn.com>
-
- Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
- Posting-number: Volume 22, Issue 68
- Archive-name: elm2.3/part09
-
- #!/bin/sh
- # this is part 9 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file filter/filter.c continued
- #
- CurArch=9
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file filter/filter.c"
- sed 's/^X//' << 'SHAR_EOF' >> filter/filter.c
- X#include "defs.h"
- X#ifdef I_TIME
- X# include <time.h>
- X#endif
- X#ifdef I_SYSTIME
- X# include <sys/time.h>
- X#endif
- X#include <fcntl.h>
- X
- X#define MAIN_ROUTINE /* for the filter.h file, of course! */
- X#include "filter.h"
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X extern char *optarg;
- X FILE *fd; /* for output to temp file! */
- X struct passwd *passwd_entry;
- X#ifndef _POSIX_SOURCE
- X struct passwd *getpwuid(); /* for /etc/passwd */
- X#endif
- X char filename[SLEN], /* name of the temp file */
- X buffer[MAX_LINE_LEN]; /* input buffer space */
- X int in_header = TRUE, /* for header parsing */
- X in_to = FALSE, /* are we on 'n' line To: ? */
- X summary = FALSE, /* a summary is requested? */
- X c; /* var for getopt routine */
- X
- X /* first off, let's get the info from /etc/passwd */
- X
- X if ((passwd_entry = getpwuid(getuid())) == NULL)
- X leave("Cannot get password entry for this uid!");
- X
- X strcpy(home, passwd_entry->pw_dir);
- X strcpy(username, passwd_entry->pw_name);
- X outfname[0] = to[0] = '\0'; /* nothing read in yet, right? */
- X
- X#ifdef HOSTCOMPILED
- X strncpy(hostname, HOSTNAME, sizeof(hostname));
- X#else
- X gethostname(hostname, sizeof(hostname));
- X#endif
- X
- X /* now parse the starting arguments... */
- X
- X while ((c = getopt(argc, argv, "clno:rSsv")) != EOF) {
- X switch (c) {
- X case 'c' : clear_logs = TRUE; break;
- X case 'l' : log_actions_only = TRUE; break;
- X case 'o' : strcpy(outfname, optarg); break;
- X case 'r' : printing_rules = TRUE; break;
- X
- X case 's' : summary = TRUE; break;
- X case 'S' : long_summary = TRUE; break;
- X
- X case 'n' : show_only = TRUE; break;
- X case 'v' : verbose = TRUE; break;
- X case '?' : fprintf(stderr,
- X "Usage: | filter [-nrv]\n or: filter [-c] -[s|S]\n");
- X exit(1);
- X }
- X }
- X
- X if (c < 0) {
- X }
- X
- X /* let's open our outfd logfile as needed... */
- X
- X if (outfname[0] == '\0') /* default is stdout */
- X outfd = stdout;
- X else
- X if ((outfd = fopen(outfname, "a")) == NULL) {
- X if (isatty(fileno(stderr)))
- X fprintf(stderr,"filter (%s): couldn't open log file %s\n",
- X username, outfname);
- X }
- X
- X if (summary || long_summary) {
- X if (get_filter_rules() == -1) {
- X exit(1);
- X if (outfd != NULL) fclose(outfd);
- X }
- X show_summary();
- X if (outfd != NULL) fclose(outfd);
- X exit(0);
- X }
- X
- X if (printing_rules) {
- X if (get_filter_rules() == -1)
- X fprintf(outfd,"filter (%s): Couldn't get rules!\n", username);
- X else
- X print_rules();
- X if (outfd != NULL) fclose(outfd);
- X exit(0);
- X }
- X
- X /* next, create the tempfile and save the incoming message */
- X
- X sprintf(filename, "%s.%d", filter_temp, getpid());
- X
- X if ((fd = fopen(filename,"w")) == NULL)
- X leave("Cannot open temporary file!");
- X
- X while (fgets(buffer, MAX_LINE_LEN, stdin) != NULL) {
- X
- X remove_return(buffer);
- X
- X if (in_header) {
- X
- X if (! whitespace(buffer[0]))
- X in_to = FALSE;
- X
- X if (the_same(buffer, "From "))
- X save_from(buffer);
- X else if (the_same(buffer, "Subject:"))
- X save_subject(buffer);
- X else if (the_same(buffer, "To:") || the_same(buffer, "Cc:")) {
- X in_to++;
- X save_to(buffer);
- X }
- X else if (the_same(buffer, "X-Filtered-By:"))
- X already_been_forwarded++; /* could be a loop here! */
- X#ifdef USE_EMBEDDED_ADDRESSES
- X else if (the_same(buffer, "From:"))
- X save_embedded_address(buffer, "From:");
- X else if (the_same(buffer, "Reply-To:"))
- X save_embedded_address(buffer, "Reply-To:");
- X#endif
- X else if (strlen(buffer) < 2)
- X in_header = 0;
- X else if (whitespace(buffer[0]) && in_to)
- X strcat(to, buffer);
- X }
- X
- X fprintf(fd, "%s\n", buffer); /* and save it regardless! */
- X fflush(fd);
- X lines++;
- X }
- X
- X fclose(fd);
- X
- X /** next let's see if the user HAS a filter file, and if so what's in
- X it (and so on) **/
- X
- X if (get_filter_rules() == -1)
- X mail_message(username);
- X else {
- X switch (action_from_ruleset()) {
- X
- X case DELETE_MSG : if (verbose && outfd != NULL)
- X fprintf(outfd, "filter (%s): Message deleted\n",
- X username);
- X log(DELETE_MSG); break;
- X
- X case SAVE : if (save_message(rules[rule_choosen].argument2)) {
- X mail_message(username);
- X log(FAILED_SAVE);
- X }
- X else
- X log(SAVE); break;
- X
- X case SAVECC : if (save_message(rules[rule_choosen].argument2))
- X log(FAILED_SAVE);
- X else
- X log(SAVECC);
- X mail_message(username); break;
- X
- X case FORWARD: mail_message(rules[rule_choosen].argument2);
- X log(FORWARD); break;
- X
- X case EXEC : execute(rules[rule_choosen].argument2);
- X log(EXEC); break;
- X
- X case LEAVE : mail_message(username);
- X log(LEAVE); break;
- X }
- X }
- X
- X (void) unlink(filename); /* remove the temp file, please! */
- X if (outfd != NULL) fclose(outfd);
- X exit(0);
- X}
- X
- Xsave_from(buffer)
- Xchar *buffer;
- X{
- X /** save the SECOND word of this string as FROM **/
- X
- X register char *f = from;
- X
- X while (*buffer != ' ')
- X buffer++; /* get to word */
- X
- X for (buffer++; *buffer != ' ' && *buffer; buffer++, f++)
- X *f = *buffer; /* copy it and */
- X
- X *f = '\0'; /* Null terminate! */
- X}
- X
- Xsave_subject(buffer)
- Xchar *buffer;
- X{
- X /** save all but the word "Subject:" for the subject **/
- X
- X register int skip = 8; /* skip "Subject:" initially */
- X
- X while (buffer[skip] == ' ') skip++;
- X
- X strcpy(subject, (char *) buffer + skip);
- X}
- X
- Xsave_to(buffer)
- Xchar *buffer;
- X{
- X /** save all but the word "To:" or "Cc:" for the to list **/
- X
- X register int skip = 3; /* skip "To:" or "Cc:" initially */
- X
- X while (buffer[skip] == ' ') skip++;
- X
- X strcat(to, (char *) buffer + skip);
- X}
- X
- X#ifdef USE_EMBEDDED_ADDRESSES
- X
- Xsave_embedded_address(buffer, fieldname)
- Xchar *buffer, *fieldname;
- X{
- X /** this will replace the 'from' address with the one given,
- X unless the address is from a 'reply-to' field (which overrides
- X the From: field). The buffer given to this routine can have one
- X of three forms:
- X fieldname: username <address>
- X fieldname: address (username)
- X fieldname: address
- X **/
- X
- X static int processed_a_reply_to = 0;
- X char address[LONG_STRING];
- X register int i, j = 0;
- X
- X /** first let's extract the address from this line.. **/
- X
- X if (buffer[strlen(buffer)-1] == '>') { /* case #1 */
- X for (i=strlen(buffer)-1; buffer[i] != '<' && i > 0; i--)
- X /* nothing - just move backwards .. */ ;
- X i++; /* skip the leading '<' symbol */
- X while (buffer[i] != '>')
- X address[j++] = buffer[i++];
- X address[j] = '\0';
- X }
- X else { /* get past "from:" and copy until white space or paren hit */
- X for (i=strlen(fieldname); whitespace(buffer[i]); i++)
- X /* skip past that... */ ;
- X while (buffer[i] != '(' && ! whitespace(buffer[i]) && buffer[i]!='\0')
- X address[j++] = buffer[i++];
- X address[j] = '\0';
- X }
- X
- X /** now let's see if we should overwrite the existing from address
- X with this one or not.. **/
- X
- X if (processed_a_reply_to)
- X return; /* forget it! */
- X
- X strcpy(from, address); /* replaced!! */
- X
- X if (strcmp(fieldname, "Reply-To:") == 0)
- X processed_a_reply_to++;
- X}
- X#endif
- SHAR_EOF
- echo "File filter/filter.c is complete"
- chmod 0444 filter/filter.c || echo "restore of filter/filter.c fails"
- echo "x - extracting filter/lock.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > filter/lock.c &&
- X
- Xstatic char rcsid[] ="@(#)$Id: lock.c,v 4.1 90/04/28 22:41:57 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein - elm@DSI.COM
- X * dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: lock.c,v $
- X * Revision 4.1 90/04/28 22:41:57 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X
- X/** The lock() and unlock() routines herein duplicate exactly the
- X equivalent routines in the Elm Mail System, and should also be
- X compatible with sendmail, rmail, etc etc.
- X
- X
- X**/
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <errno.h>
- X#include "defs.h"
- X#include "filter.h"
- X
- Xstatic int we_locked_it;
- Xstatic char lockfile[SLEN];
- X
- X#ifdef LOCK_BY_FLOCK
- X#include <sys/types.h>
- X#include <sys/file.h>
- Xstatic flock_fd = -1;
- Xstatic char flock_name[SLEN];
- X#endif
- X
- Xextern int errno;
- X
- Xint
- Xlock()
- X{
- X /** This routine will return 1 if we could lock the mailfile,
- X zero otherwise.
- X **/
- X
- X int attempts = 0, ret;
- X
- X#ifndef LOCK_FLOCK_ONLY /* { !LOCK_FLOCK_ONLY */
- X sprintf(lockfile, "%s%s.lock", mailhome, username);
- X#ifdef PIDCHECK
- X /** first, try to read the lock file, and if possible, check the pid.
- X If we can validate that the pid is no longer active, then remove
- X the lock file.
- X **/
- X if((ret=open(lockfile,O_RDONLY)) != -1) {
- X char pid_buffer[SHORT];
- X if (read(ret, pid_buffer, SHORT) > 0) {
- X attempts = atoi(pid_buffer);
- X if (attempts) {
- X if (kill(attempts, 0)) {
- X close(ret);
- X if (unlink(lockfile) != 0)
- X return(1);
- X }
- X }
- X }
- X attempts = 0;
- X }
- X#endif
- X
- X while ((ret = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 0444)) < 0
- X && attempts++ < 10) {
- X sleep(3); /* wait three seconds each pass, okay?? */
- X }
- X
- X if (ret >= 0) {
- X we_locked_it++;
- X close(ret); /* no need to keep it open! */
- X ret = 1;
- X } else {
- X ret = 0;
- X }
- X
- X#endif /* } !LOCK_FLOCK_ONLY */
- X#ifdef LOCK_BY_FLOCK /* { LOCK_BY_FLOCK */
- X (void)sprintf(flock_name,"%s%s",mailhome,username);
- X flock_fd = open(flock_name,O_RDONLY);
- X if ( flock_fd >= 0 )
- X for (attempts = 0; attempts < 10; attempts++) {
- X if ( (ret = flock(flock_fd,LOCK_NB|LOCK_EX)) != -1 )
- X break;
- X if ( errno != EWOULDBLOCK && errno != EAGAIN )
- X break;
- X (void)sleep((unsigned)3);
- X }
- X if ( flock_fd >= 0 && ret == 0 ) {
- X we_locked_it++;
- X ret = 1;
- X } else {
- X we_locked_it = 0;
- X if ( lockfile[0] ) {
- X (void)unlink(lockfile);
- X lockfile[0] = 0;
- X }
- X if ( flock_fd >= 0 ) {
- X (void)close(flock_fd);
- X flock_fd = -1;
- X }
- X ret = 0;
- X }
- X#endif
- X return(ret);
- X}
- X
- Xunlock()
- X{
- X /** this routine will remove the lock file, but only if we were
- X the people that locked it in the first place... **/
- X
- X#ifndef LOCK_FLOCK_ONLY
- X if (we_locked_it && lockfile[0]) {
- X unlink(lockfile); /* blamo! */
- X lockfile[0] = 0;
- X }
- X#endif
- X#ifdef LOCK_BY_FLOCK
- X if (we_locked_it && flock_fd >= 0) {
- X (void)close(flock_fd);
- X flock_fd = -1;
- X }
- X#endif
- X we_locked_it = 0;
- X}
- SHAR_EOF
- chmod 0444 filter/lock.c || echo "restore of filter/lock.c fails"
- echo "x - extracting filter/parse.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > filter/parse.c &&
- X
- Xstatic char rcsid[] ="@(#)$Id: parse.c,v 4.1 90/04/28 22:41:58 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein - elm@DSI.COM
- X * dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: parse.c,v $
- X * Revision 4.1 90/04/28 22:41:58 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X
- X/** This is the parser for the filter program. It accepts a wide variety of
- X constructs, building the ruleset table as it goes along. Check the
- X data structure in filter.h for more information on how the rules are
- X stored. The parser is a cunning state-table based program.
- X
- X**/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include "defs.h"
- X#include "filter.h"
- X
- X#define NONE 0
- X#define AND 10
- X
- X#define NEXT_CONDITION 0
- X#define GETTING_OP 1
- X#define READING_ARGUMENT 2
- X#define READING_ACTION 3
- X#define ACTION_ARGUMENT 4
- X
- Xchar *strtok(), *whatname(), *actionname();
- X
- Xint
- Xget_filter_rules()
- X{
- X /** Given the users home directory, open and parse their rules table,
- X building the data structure as we go along.
- X returns -1 if we hit an error of any sort...
- X **/
- X
- X FILE *fd; /* the file descriptor */
- X char buffer[SLEN], /* fd reading buffer */
- X *str, /* ptr to read string */
- X *word, /* ptr to 'token' */
- X filename[SLEN], /* the name of the ruleset */
- X action_argument[SLEN], /* action arg, per rule */
- X cond_argument[SLEN]; /* cond arg, per condition */
- X int not_condition = FALSE, /* are we in a "not" ?? */
- X type=NONE, /* what TYPE of condition? */
- X lasttype, /* and the previous TYPE? */
- X state = NEXT_CONDITION, /* the current state */
- X in_single, in_double, /* for handling spaces. */
- X i, /* misc integer for loops */
- X relop = NONE, /* relational operator */
- X action, /* the current action type */
- X buflen, /* the length of buffer */
- X line = 0; /* line number we're on */
- X
- X struct condition_rec *cond, *newcond;
- X
- X sprintf(filename,"%s/%s", home, filterfile);
- X
- X if ((fd = fopen(filename,"r")) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,"filter (%s): Couldn't read user filter rules file!\n",
- X username);
- X return(-1);
- X }
- X
- X cond_argument[0] = action_argument[0] = '\0';
- X
- X /* Now, for each line... **/
- X
- X if ((cond = (struct condition_rec *)
- X malloc(sizeof(struct condition_rec))) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,"filter (%s): couldn't malloc first condition rec!\n",
- X username);
- X return(-1);
- X }
- X
- X rules[total_rules].condition = cond; /* hooked in! */
- X
- X while (fgets(buffer, SLEN, fd) != NULL) {
- X line++;
- X
- X if (buffer[0] == '#' || (buflen = strlen(buffer)) < 2)
- X continue; /* nothing to look at! */
- X
- X in_single = in_double = 0;
- X
- X for (i=0; i < buflen; i++) {
- X if (buffer[i] == '"')
- X in_double = ! in_double;
- X else if (buffer[i] == '\'')
- X in_single = ! in_single;
- X if ((in_double || in_single) && buffer[i] == ' ')
- X buffer[i] = '_';
- X }
- X
- X lasttype = type;
- X type = NONE;
- X str = (char *) buffer;
- X
- X /** Three pieces to this loop - get the `field', the 'relop' (if
- X there) then, if needed, get the argument to check against (not
- X needed for errors or the AND, of course)
- X **/
- X
- X while ((word = strtok(str, " ()[]:\t\n")) != NULL) {
- X
- X str = (char *) NULL; /* we can start stomping! */
- X
- X lowercase(word);
- X
- X if (strcmp(word, "if") == 0) { /* only ONE 'if' allowed */
- X if ((word = strtok(str, " ()[]:\t\n")) == NULL) /* NEXT! */
- X continue;
- X lowercase(word);
- X }
- X
- X if (state == NEXT_CONDITION) {
- X lasttype = type;
- X type = NONE;
- X
- X if (the_same(word, "not") || the_same(word, "!")) {
- X not_condition = TRUE;
- X if ((word = strtok(str, " ()[]'\"\t\n")) == NULL)
- X continue;
- X }
- X
- X if (the_same(word, "from")) type = FROM;
- X else if (the_same(word, "to")) type = TO;
- X else if (the_same(word, "subject")) type = SUBJECT;
- X else if (the_same(word, "lines")) type = LINES;
- X else if (the_same(word, "contains")) type = CONTAINS;
- X else if (the_same(word, "and") ||
- X the_same(word, "&&")) type = AND;
- X
- X else if (the_same(word,"?") || the_same(word, "then") ||
- X the_same(word, "always")) {
- X
- X /** shove THIS puppy into the structure and let's continue! **/
- X
- X if (lasttype == AND) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): Error reading line %d of rules - badly placed \"and\"\n",
- X username, line);
- X return(-1);
- X }
- X
- X if (the_same(word, "always"))
- X cond->matchwhat = ALWAYS; /* so it's a hack... */
- X else
- X cond->matchwhat = lasttype;
- X
- X if (relop == NONE) relop = EQ; /* otherwise can't do -relop */
- X cond->relation = (not_condition? - (relop) : relop);
- X
- X for (i=strlen(cond_argument); --i >= 0;)
- X if (cond_argument[i] == '_') cond_argument[i] = ' ';
- X
- X strcpy(cond->argument1, cond_argument);
- X if ((newcond = (struct condition_rec *)
- X malloc(sizeof(struct condition_rec))) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): Couldn't malloc new cond rec!!\n",
- X username);
- X return(-1);
- X }
- X cond->next = NULL;
- X
- X relop = EQ; /* default relational condition */
- X
- X state = READING_ACTION;
- X if ((word = strtok(str, " ()[]'\"\t\n")) == NULL)
- X continue;
- X goto get_outta_loop;
- X }
- X
- X if (type == NONE) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): Error reading line %d of rules - field \"%s\" unknown!\n",
- X username, line, word);
- X return(-1);
- X }
- X
- X if (type == AND) {
- X
- X /** shove THIS puppy into the structure and let's continue! **/
- X
- X cond->matchwhat = lasttype;
- X cond->relation = (not_condition? - (relop) : relop);
- X strcpy(cond->argument1, cond_argument);
- X if ((newcond = (struct condition_rec *)
- X malloc(sizeof(struct condition_rec))) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): Couldn't malloc new cond rec!!\n",
- X username);
- X return(-1);
- X }
- X cond->next = newcond;
- X cond = newcond;
- X cond->next = NULL;
- X
- X not_condition = FALSE;
- X state = NEXT_CONDITION;
- X }
- X else {
- X state = GETTING_OP;
- X }
- X }
- X
- Xget_outta_loop: /* jump out when we change state, if needed */
- X
- X if (state == GETTING_OP) {
- X
- X if ((word = strtok(str, " ()[]'\"\t\n")) == NULL)
- X continue;
- X
- X lowercase(word);
- X
- X relop = NONE;
- X
- X if (the_same(word, "=") || the_same(word, "in") ||
- X the_same(word, "contains")) {
- X state = READING_ARGUMENT;
- X relop = EQ;
- X }
- X else {
- X if (the_same(word, "<=")) relop = LE;
- X else if (the_same(word, ">=")) relop = GE;
- X else if (the_same(word, ">")) relop = GT;
- X else if (the_same(word, "<>")||
- X the_same(word, "!=")) relop = NE;
- X else if (the_same(word, "<")) relop = LT;
- X
- X /* maybe there isn't a relop at all!! */
- X
- X state=READING_ARGUMENT;
- X
- X }
- X }
- X
- X if (state == READING_ARGUMENT) {
- X if (relop != NONE) {
- X if ((word = strtok(str, " ()[]'\"\t\n")) == NULL)
- X continue;
- X }
- X for (i=strlen(word); --i>=0;)
- X if (word[i] == '_') word[i] = ' ';
- X
- X strcpy(cond_argument, word);
- X state = NEXT_CONDITION;
- X }
- X
- X if (state == READING_ACTION) {
- X action = NONE;
- X
- X not_condition = FALSE;
- X
- X if (the_same(word, "delete")) action = DELETE_MSG;
- X else if (the_same(word, "savec")) action = SAVECC;
- X else if (the_same(word, "save")) action = SAVE;
- X else if (the_same(word, "forward")) action = FORWARD;
- X else if (the_same(word, "exec")) action = EXEC;
- X else if (the_same(word, "leave")) action = LEAVE;
- X else {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): Error on line %d of rules - action \"%s\" unknown\n",
- X username, line, word);
- X }
- X
- X if (action == DELETE_MSG || action == LEAVE) {
- X /** add this to the rules section and alloc next... **/
- X
- X rules[total_rules].action = action;
- X rules[total_rules].argument2[0] = '\0'; /* nothing! */
- X total_rules++;
- X
- X if ((cond = (struct condition_rec *)
- X malloc(sizeof(struct condition_rec))) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): couldn't malloc first condition rec!\n",
- X username);
- X return(-1);
- X }
- X
- X rules[total_rules].condition = cond; /* hooked in! */
- X state = NEXT_CONDITION;
- X }
- X else {
- X state = ACTION_ARGUMENT;
- X }
- X
- X if ((word = strtok(str, " ()[]'\"\t\n")) == NULL)
- X continue;
- X
- X }
- X
- X if (state == ACTION_ARGUMENT) {
- X strcpy(action_argument, word);
- X
- X /** add this to the rules section and alloc next... **/
- X
- X rules[total_rules].action = action;
- X expand_macros(action_argument, rules[total_rules].argument2,line,
- X printing_rules);
- X total_rules++;
- X
- X if ((cond = (struct condition_rec *)
- X malloc(sizeof(struct condition_rec))) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): couldn't malloc first condition rec!\n",
- X username);
- X return(-1);
- X }
- X
- X rules[total_rules].condition = cond; /* hooked in! */
- X
- X state = NEXT_CONDITION;
- X if ((word = strtok(str, " ()[]'\"\t\n")) == NULL)
- X continue;
- X }
- X }
- X }
- X
- X return(0);
- X}
- SHAR_EOF
- chmod 0444 filter/parse.c || echo "restore of filter/parse.c fails"
- echo "x - extracting filter/rules.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > filter/rules.c &&
- X
- Xstatic char rcsid[] ="@(#)$Id: rules.c,v 4.1 90/04/28 22:42:00 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein - elm@DSI.COM
- X * dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: rules.c,v $
- X * Revision 4.1 90/04/28 22:42:00 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This file contains all the rule routines, including those that apply the
- X specified rules and the routine to print the rules out.
- X
- X**/
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <ctype.h>
- X#include "defs.h"
- X#ifdef I_TIME
- X# include <time.h>
- X#endif
- X#ifdef I_SYSTIME
- X# include <sys/time.h>
- X#endif
- X#include <fcntl.h>
- X
- X#include "filter.h"
- X
- Xchar *listrule();
- X
- Xint
- Xaction_from_ruleset()
- X{
- X /** Given the set of rules we've read in and the current to, from,
- X and subject, try to match one. Return the ACTION of the match
- X or LEAVE if none found that apply.
- X **/
- X
- X register int iindex = 0, not, relation, try_next_rule, x;
- X struct condition_rec *cond;
- X
- X while (iindex < total_rules) {
- X cond = rules[iindex].condition;
- X try_next_rule = 0;
- X
- X while (cond != NULL && ! try_next_rule) {
- X
- X not = (cond->relation < 0);
- X relation = abs(cond->relation);
- X
- X switch (cond->matchwhat) {
- X
- X case TO : x = contains(to, cond->argument1); break;
- X case FROM : x = contains(from, cond->argument1); break;
- X case SUBJECT: x = contains(subject, cond->argument1); break;
- X case LINES : x = compare(lines, relation, cond->argument1);break;
- X
- X case CONTAINS: if (outfd != NULL) fprintf(outfd,
- X "filter (%s): Error: rules based on 'contains' are not implemented!\n",
- X username);
- X if (outfd != NULL) fclose(outfd);
- X exit(0);
- X
- X case ALWAYS: not = FALSE; x = TRUE; break;
- X }
- X
- X if ((not && x) || ((! not) && (! x))) /* this test failed (LISP?) */
- X try_next_rule++;
- X else
- X cond = cond->next; /* next condition, if any? */
- X }
- X
- X if (! try_next_rule) {
- X rule_choosen = iindex;
- X return(rules[rule_choosen].action);
- X }
- X iindex++;
- X }
- X
- X rule_choosen = -1;
- X return(LEAVE);
- X}
- X
- X#define get_the_time() if (!gotten_time) { \
- X thetime = time( (long *) 0); \
- X timerec = localtime(&thetime); \
- X gotten_time++; \
- X }
- X
- Xexpand_macros(word, buffer, line, display)
- Xchar *word, *buffer;
- Xint line, display;
- X{
- X /** expand the allowable macros in the word;
- X %d = day of the month
- X %D = day of the week
- X %h = hour (0-23)
- X %m = month of the year
- X %r = return address of sender
- X %s = subject of message
- X %S = "Re: subject of message" (only add Re: if not there)
- X %t = hour:minute
- X %y = year
- X or simply copies word into buffer. If "display" is set then
- X instead it puts "<day-of-month>" etc. etc. in the output.
- X **/
- X
- X#ifndef _POSIX_SOURCE
- X struct tm *localtime();
- X long time();
- X#endif
- X struct tm *timerec;
- X long thetime;
- X register int i, j=0, gotten_time = 0, reading_a_percent_sign = 0, len;
- X
- X for (i = 0, len = strlen(word); i < len; i++) {
- X if (reading_a_percent_sign) {
- X reading_a_percent_sign = 0;
- X switch (word[i]) {
- X
- X case 'r' : buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<return-address>");
- X else
- X strcat(buffer, from);
- X j = strlen(buffer);
- X break;
- X
- X case 's' : buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<subject>");
- X else {
- X strcat(buffer, "\"");
- X strcat(buffer, subject);
- X strcat(buffer, "\"");
- X }
- X j = strlen(buffer);
- X break;
- X
- X case 'S' : buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<Re: subject>");
- X else {
- X if (! the_same(subject, "Re:"))
- X strcat(buffer, "\"Re: ");
- X strcat(buffer, subject);
- X strcat(buffer, "\"");
- X }
- X j = strlen(buffer);
- X break;
- X
- X case 'd' : get_the_time(); buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<day-of-month>");
- X else
- X strcat(buffer, itoa(timerec->tm_mday,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 'D' : get_the_time(); buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<day-of-week>");
- X else
- X strcat(buffer, itoa(timerec->tm_wday,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 'm' : get_the_time(); buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<month>");
- X else
- X strcat(buffer, itoa(timerec->tm_mon+1,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 'y' : get_the_time(); buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<year>");
- X else
- X strcat(buffer, itoa(timerec->tm_year,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 'h' : get_the_time(); buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<hour>");
- X else
- X strcat(buffer, itoa(timerec->tm_hour,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 't' : get_the_time(); buffer[j] = '\0';
- X if (display)
- X strcat(buffer, "<time>");
- X else {
- X strcat(buffer, itoa(timerec->tm_hour,FALSE));
- X strcat(buffer, ":");
- X strcat(buffer, itoa(timerec->tm_min,TRUE));
- X }
- X j = strlen(buffer);
- X break;
- X
- X default : if (outfd != NULL) fprintf(outfd,
- X "filter (%s): Error on line %d translating %%%c macro in word \"%s\"!\n",
- X username, line, word[i], word);
- X if (outfd != NULL) fclose(outfd);
- X exit(1);
- X }
- X }
- X else if (word[i] == '%')
- X reading_a_percent_sign++;
- X else
- X buffer[j++] = (word[i] == '_' ? ' ' : word[i]);
- X }
- X buffer[j] = '\0';
- X}
- X
- Xprint_rules()
- X{
- X /** print the rules out. A double check, of course! **/
- X
- X register int i = -1;
- X char *whatname(), *actionname();
- X struct condition_rec *cond;
- X
- X if (outfd == NULL) return; /* why are we here, then? */
- X
- X while (++i < total_rules) {
- X if (rules[i].condition->matchwhat == ALWAYS) {
- X fprintf(outfd, "\nRule %d: ** always ** \n\t%s %s\n", i+1,
- X actionname(rules[i].action), listrule(rules[i].argument2));
- X continue;
- X }
- X
- X fprintf(outfd, "\nRule %d: if (", i+1);
- X
- X cond = rules[i].condition;
- X
- X while (cond != NULL) {
- X if (cond->relation < 0)
- X fprintf(outfd, "not %s %s %s%s%s",
- X whatname(cond->matchwhat),
- X relationname(- (cond->relation)),
- X quoteit(cond->matchwhat),
- X cond->argument1,
- X quoteit(cond->matchwhat));
- X else
- X fprintf(outfd, "%s %s %s%s%s",
- X whatname(cond->matchwhat),
- X relationname(cond->relation),
- X quoteit(cond->matchwhat),
- X cond->argument1,
- X quoteit(cond->matchwhat));
- X
- X cond = cond->next;
- X
- X if (cond != NULL) fprintf(outfd, " and ");
- X }
- X
- X fprintf(outfd, ") then\n\t %s %s\n",
- X actionname(rules[i].action),
- X listrule(rules[i].argument2));
- X }
- X fprintf(outfd, "\n");
- X}
- X
- Xchar *whatname(n)
- Xint n;
- X{
- X static char buffer[10];
- X
- X switch(n) {
- X case FROM : return("from");
- X case TO : return("to");
- X case SUBJECT: return("subject");
- X case LINES : return ("lines");
- X case CONTAINS: return("contains");
- X default : sprintf(buffer, "?%d?", n); return((char *)buffer);
- X }
- X}
- X
- Xchar *actionname(n)
- Xint n;
- X{
- X switch(n) {
- X case DELETE_MSG : return("Delete");
- X case SAVE : return("Save");
- X case SAVECC : return("Copy and Save");
- X case FORWARD : return("Forward");
- X case LEAVE : return("Leave");
- X case EXEC : return("Execute");
- X default : return("?action?");
- X }
- X}
- X
- Xint
- Xcompare(line, relop, arg)
- Xint line, relop;
- Xchar *arg;
- X{
- X /** Given the actual number of lines in the message, the relop
- X relation, and the number of lines in the rule, as a string (!),
- X return TRUE or FALSE according to which is correct.
- X **/
- X
- X int rule_lines;
- X
- X rule_lines = atoi(arg);
- X
- X switch (relop) {
- X case LE: return(line <= rule_lines);
- X case LT: return(line < rule_lines);
- X case GE: return(line >= rule_lines);
- X case GT: return(line > rule_lines);
- X case NE: return(line != rule_lines);
- X case EQ: return(line == rule_lines);
- X }
- X return(-1);
- X}
- X
- Xchar *listrule(rule)
- Xchar *rule;
- X{
- X /** simply translates all underscores into spaces again on the
- X way past... **/
- X
- X static char buffer[SLEN];
- X register int i;
- X
- X i = strlen(rule);
- X buffer[i] = '\0';
- X while (--i >= 0)
- X buffer[i] = (rule[i] == '_' ? ' ' : rule[i]);
- X
- X return( (char *) buffer);
- X}
- SHAR_EOF
- chmod 0444 filter/rules.c || echo "restore of filter/rules.c fails"
- echo "x - extracting filter/summarize.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > filter/summarize.c &&
- X
- Xstatic char rcsid[] ="@(#)$Id: summarize.c,v 4.1 90/04/28 22:42:02 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein - elm@DSI.COM
- X * dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: summarize.c,v $
- X * Revision 4.1 90/04/28 22:42:02 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** This routine is called from the filter program (or can be called
- X directly with the correct arguments) and summarizes the users filterlog
- X file. To be honest, there are two sorts of summaries that are
- X available - either the '.filterlog' file can be output (filter -S)
- X or a summary by rule and times acted upon can be output (filter -s).
- X Either way, this program will delete the two associated files each
- X time ($HOME/.filterlog and $HOME/.filtersum) *if* the -c option is
- X used to the program (e.g. clear_logs is set to TRUE).
- X
- X**/
- X
- X#include <stdio.h>
- X
- X#include "defs.h"
- X
- X#include "filter.h"
- X
- Xshow_summary()
- X{
- X /* Summarize usage of the program... */
- X
- X FILE *fd; /* for output to temp file! */
- X char filename[SLEN], /* name of the temp file */
- X buffer[SLEN]; /* input buffer space */
- X int erroneous_rules = 0,
- X default_rules = 0,
- X messages_filtered = 0, /* how many have we touched? */
- X rule,
- X applied[MAXRULES];
- X
- X sprintf(filename, "%s/%s", home, filtersum);
- X
- X if ((fd = fopen(filename, "r")) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd,"filter (%s): Can't open filtersum file %s!\n",
- X
- X username, filename);
- X if (outfd != NULL) fclose(outfd);
- X exit(1);
- X }
- X
- X for (rule=0;rule < MAXRULES; rule++)
- X applied[rule] = 0; /* initialize it all! */
- X
- X /** Next we need to read it all in, incrementing by which rule
- X was used. The format is simple - each line represents a
- X single application of a rule, or '-1' if the default action
- X was taken. Simple stuff, eh? But oftentimes the best.
- X **/
- X
- X while (fgets(buffer, SLEN, fd) != NULL) {
- X if ((rule = atoi(buffer)) > total_rules || rule < -1) {
- X if (outfd != NULL)
- X fprintf(outfd,
- X "filter (%s): Warning - rule #%d is invalid data for short summary!!\n",
- X username, rule);
- X erroneous_rules++;
- X }
- X else if (rule == -1)
- X default_rules++;
- X else
- X applied[rule]++;
- X messages_filtered++;
- X }
- X
- X fclose(fd);
- X
- X /** now let's summarize the data... **/
- X
- X if (outfd == NULL) return; /* no reason to go further */
- X
- X fprintf(outfd,
- X "\n\t\t\tA Summary of Filter Activity\n");
- X fprintf(outfd,
- X "\t\t\t----------------------------\n\n");
- X
- X fprintf(outfd,"A total of %d message%s %s filtered:\n\n",
- X messages_filtered, plural(messages_filtered),
- X messages_filtered > 1 ? "were" : "was");
- X
- X if (erroneous_rules)
- X fprintf(outfd,
- X "[Warning: %d erroneous rule%s logged and ignored!]\n\n",
- X erroneous_rules, erroneous_rules > 1? "s were" : " was");
- X
- X if (default_rules) {
- X fprintf(outfd,
- X "The default rule of putting mail into your mailbox\n");
- X fprintf(outfd, "\tapplied %d time%s (%d%%)\n\n",
- X default_rules, plural(default_rules),
- X (default_rules*100+(messages_filtered>>1))/messages_filtered
- X );
- X }
- X
- X /** and now for each rule we used... **/
- X
- X for (rule = 0; rule < total_rules; rule++) {
- X if (applied[rule]) {
- X fprintf(outfd, "Rule #%d: ", rule+1);
- X switch (rules[rule].action) {
- X case LEAVE: fprintf(outfd, "(leave mail in mailbox)");
- X break;
- X case DELETE_MSG: fprintf(outfd, "(delete message)");
- X break;
- X case SAVE : fprintf(outfd, "(save in \"%s\")",
- X rules[rule].argument2); break;
- X case SAVECC: fprintf(outfd,
- X "(left in mailbox and saved in \"%s\")",
- X rules[rule].argument2); break;
- X case FORWARD: fprintf(outfd, "(forwarded to \"%s\")",
- X rules[rule].argument2); break;
- X case EXEC : fprintf(outfd, "(given to command \"%s\")",
- X rules[rule].argument2); break;
- X }
- X fprintf(outfd, "\n\tapplied %d time%s (%d%%)\n\n",
- X applied[rule], plural(applied[rule]),
- X (applied[rule]*100+(messages_filtered>>1))/messages_filtered
- X );
- X }
- X }
- X
- X if (long_summary) {
- X
- X /* next, after a ^L, include the actual log file... */
- X
- X sprintf(filename, "%s/%s", home, filterlog);
- X
- X if ((fd = fopen(filename, "r")) == NULL) {
- X fprintf(outfd,"filter (%s): Can't open filterlog file %s!\n",
- X username, filename);
- X }
- X else {
- X fprintf(outfd, "\n\n\n%c\n\nExplicit log of each action;\n\n",
- X (char) 12);
- X while (fgets(buffer, SLEN, fd) != NULL)
- X fprintf(outfd, "%s", buffer);
- X fprintf(outfd, "\n-----\n");
- X fclose(fd);
- X }
- X }
- X
- X /* now remove the log files, please! */
- X
- X if (clear_logs) {
- X sprintf(filename, "%s/%s", home, filterlog);
- X unlink(filename);
- X sprintf(filename, "%s/%s", home, filtersum);
- X unlink(filename);
- X }
- X
- X return;
- X}
- SHAR_EOF
- chmod 0444 filter/summarize.c || echo "restore of filter/summarize.c fails"
- echo "x - extracting filter/utils.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > filter/utils.c &&
- X
- Xstatic char rcsid[] ="@(#)$Id: utils.c,v 4.1 90/04/28 22:42:03 syd Exp $";
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein - elm@DSI.COM
- X * dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: utils.c,v $
- X * Revision 4.1 90/04/28 22:42:03 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** Utility routines for the filter program...
- X
- X**/
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <ctype.h>
- X#include <fcntl.h>
- X
- X#include "defs.h"
- X#include "filter.h"
- X
- Xleave(reason)
- Xchar *reason;
- X{
- X if (outfd != NULL)
- X fprintf(outfd,"filter (%s): LEAVE %s\n", username, reason);
- X if (outfd != NULL) fclose(outfd);
- X exit(1);
- X}
- X
- Xlog(what)
- Xint what;
- X{
- X /** make an entry in the log files for the specified entry **/
- X
- X FILE *fd;
- X char filename[SLEN];
- X
- X if (! show_only) {
- X sprintf(filename, "%s/%s", home, filtersum); /* log action once! */
- X if ((fd = fopen(filename, "a")) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd, "filter (%s): Couldn't open log file %s\n",
- X filename);
- X fd = stdout;
- X }
- X fprintf(fd, "%d\n", rule_choosen);
- X fclose(fd);
- X }
- X
- X sprintf(filename, "%s/%s", home, filterlog);
- X
- X if (show_only)
- X fd = stdout;
- X else if ((fd = fopen(filename, "a")) == NULL) {
- X if (outfd != NULL)
- X fprintf(outfd, "filter (%s): Couldn't open log file %s\n",
- X filename);
- X fd = stdout;
- X }
- X
- X#ifdef _IOFBF
- X setvbuf(fd, NULL, _IOFBF, BUFSIZ);
- X#endif
- X
- X if (strlen(from) + strlen(subject) > 60)
- X fprintf(fd, "\nMail from %s\n\tabout %s\n", from, subject);
- X else
- X fprintf(fd, "\nMail from %s about %s\n", from, subject);
- X
- X if (rule_choosen != -1)
- X if (rules[rule_choosen].condition->matchwhat == TO)
- X fprintf(fd, "\t(addressed to %s)\n", to);
- X
- X switch (what) {
- X case DELETE_MSG : fprintf(fd, "\tDELETED"); break;
- X case SAVE : fprintf(fd, "\tSAVED in file \"%s\"",
- X rules[rule_choosen].argument2); break;
- X case SAVECC : fprintf(fd,"\tSAVED in file \"%s\" AND PUT in mailbox",
- X rules[rule_choosen].argument2); break;
- X case FORWARD : fprintf(fd, "\tFORWARDED to \"%s\"",
- X rules[rule_choosen].argument2); break;
- X case EXEC : fprintf(fd, "\tEXECUTED \"%s\"",
- X rules[rule_choosen].argument2); break;
- X case LEAVE : fprintf(fd, "\tPUT in mailbox"); break;
- X }
- X
- X if (rule_choosen != -1)
- X fprintf(fd, " by rule #%d\n", rule_choosen+1);
- X else
- X fprintf(fd, ": the default action\n");
- X
- X fflush(fd);
- X fclose(fd);
- X}
- X
- Xint
- Xcontains(string, pattern)
- Xchar *string, *pattern;
- X{
- X /** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/
- X
- X register int i = 0, j = 0;
- X
- X while (string[i] != '\0') {
- X while (tolower(string[i++]) == tolower(pattern[j++]))
- X if (pattern[j] == '\0')
- X return(TRUE);
- X i = i - j + 1;
- X j = 0;
- X }
- X return(FALSE);
- X}
- X
- Xchar *itoa(i, two_digit)
- Xint i, two_digit;
- X{
- X /** return 'i' as a null-terminated string. If two-digit use that
- X size field explicitly! **/
- X
- X static char value[10];
- X
- X if (two_digit)
- X sprintf(value, "%02d", i);
- X else
- X sprintf(value, "%d", i);
- X
- X return( (char *) value);
- X}
- X
- Xlowercase(string)
- Xchar *string;
- X{
- X /** translate string into all lower case **/
- X
- X register int i;
- X
- X for (i= strlen(string); --i >= 0; )
- X if (isupper(string[i]))
- X string[i] = tolower(string[i]);
- X}
- SHAR_EOF
- chmod 0444 filter/utils.c || echo "restore of filter/utils.c fails"
- echo "x - extracting hdrs/curses.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > hdrs/curses.h &&
- X
- X/* $Id: curses.h,v 4.1 90/04/28 22:42:05 syd Exp $ */
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: curses.h,v $
- X * Revision 4.1 90/04/28 22:42:05 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X /*** Include file for seperate compilation. ***/
- X
- X#define OFF 0
- X#define ON 1
- X
- Xint InitScreen(), /* This must be called before anything else!! */
- X
- X ClearScreen(), CleartoEOLN(),
- X
- X MoveCursor(),
- X
- X StartBold(), EndBold(),
- X StartUnderline(), EndUnderline(),
- X StartHalfbright(), EndHalfbright(),
- X StartInverse(), EndInverse(),
- X
- X transmit_functions(),
- X
- X Raw(), RawState(),
- X ReadCh();
- X
- Xchar *return_value_of();
- SHAR_EOF
- chmod 0444 hdrs/curses.h || echo "restore of hdrs/curses.h fails"
- echo "x - extracting hdrs/defs.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > hdrs/defs.h &&
- X
- X/* $Id: defs.h,v 4.1 90/04/28 22:42:06 syd Exp $ */
- X
- X/*******************************************************************************
- X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
- X *
- X * Copyright (c) 1986, 1987 Dave Taylor
- X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
- X *******************************************************************************
- X * Bug reports, patches, comments, suggestions should be sent to:
- X *
- X * Syd Weinstein, Elm Coordinator
- X * elm@DSI.COM dsinc!elm
- X *
- X *******************************************************************************
- X * $Log: defs.h,v $
- X * Revision 4.1 90/04/28 22:42:06 syd
- X * checkin of Elm 2.3 as of Release PL0
- X *
- X *
- X ******************************************************************************/
- X
- X/** define file for ELM mail system. **/
- X
- X
- X#include "../config.h"
- X#include "sysdefs.h" /* system/configurable defines */
- X
- X
- X# define VERSION "2.3" /* Version number... */
- X# define VERS_DATE "May 1, 1990" /* for elm -v option */
- X# define WHAT_STRING \
- X "@(#) Version 2.3, USENET supported version, released May 1990"
- X
- X#define KLICK 25
- X
- X#define SLEN 256 /* long for ensuring no overwrites... */
- X#define SHORT 10 /* super short strings! */
- X#define NLEN 48 /* name length for aliases */
- X#define WLEN 20
- X#define STRING 128 /* reasonable string length for most.. */
- X#define LONG_STRING 512 /* even longer string for group expansion */
- X#define VERY_LONG_STRING 2560 /* huge string for group alias expansion */
- X#define MAX_LINE_LEN 5120 /* even bigger string for "filter" prog.. */
- X
- X#define BREAK '\0' /* default interrupt */
- X#define BACKSPACE '\b' /* backspace character */
- X#define TAB '\t' /* tab character */
- X#define RETURN '\r' /* carriage return char */
- X#define LINE_FEED '\n' /* line feed character */
- X#define FORMFEED '\f' /* form feed (^L) char */
- X#define COMMA ',' /* comma character */
- X#define SPACE ' ' /* space character */
- X#define DOT '.' /* period/dot character */
- X#define BANG '!' /* exclaimation mark! */
- X#define AT_SIGN '@' /* at-sign character */
- X#define PERCENT '%' /* percent sign char. */
- X#define COLON ':' /* the colon .. */
- X#define BACKQUOTE '`' /* backquote character */
- X#define TILDE_ESCAPE '~' /* escape character~ */
- X#define ESCAPE '\033' /* the escape */
- X
- X#define NO_OP_COMMAND '\0' /* no-op for timeouts */
- X
- X#define STANDARD_INPUT 0 /* file number of stdin */
- X
- X#ifndef TRUE
- X#define TRUE 1
- X#define FALSE 0
- X#endif
- X
- X#define NO 0
- X#define YES 1
- X#define MAYBE 2 /* a definite define, eh? */
- X#define FORM 3 /* <nevermind> */
- X#define PREFORMATTED 4 /* forwarded form... */
- X
- X#define SAME_PAGE 1 /* redraw current only */
- X#define NEW_PAGE 2 /* redraw message list */
- X#define ILLEGAL_PAGE 0 /* error in page list, punt */
- X
- X#define PAD 0 /* for printing name of */
- X#define FULL 1 /* the sort we're using */
- X
- X#define OUTGOING 0 /* defines for lock file */
- X#define INCOMING 1 /* creation..see lock() */
- X
- X#define SH 0 /* defines for system_call */
- X#define USER_SHELL 1 /* to work correctly! */
- X
- X#define EXECUTE_ACCESS 01 /* These five are */
- X#define WRITE_ACCESS 02 /* for the calls */
- X#define READ_ACCESS 04 /* to access() */
- X#define ACCESS_EXISTS 00 /* <etc> */
- X#define EDIT_ACCESS 06 /* (this is r+w access) */
- X
- X#define BIG_NUM 999999 /* big number! */
- X#define BIGGER_NUM 9999999 /* bigger number! */
- X
- X#define START_ENCODE "[encode]"
- X#define END_ENCODE "[clear]"
- X
- X#define DONT_SAVE "[no save]"
- X#define DONT_SAVE2 "[nosave]"
- X
- X#define alias_file ".aliases"
- X#define group_file ".groups"
- X#define system_file ".systems"
- X
- X#define default_folders "Mail"
- X#define default_recvdmail "=received"
- X#define default_sentmail "=sent"
- X
- X/** some defines for the 'userlevel' variable... **/
- X
- X#define RANK_AMATEUR 0
- X#define AMATEUR 1
- X#define OKAY_AT_IT 2
- X#define GOOD_AT_IT 3
- X#define EXPERT 4
- X#define SUPER_AT_IT 5
- X
- X/** some defines for the "status" field of the header record **/
- X
- X#define ACTION 1 /* bit masks, of course */
- X#define CONFIDENTIAL 2
- X#define DELETED 4
- X#define EXPIRED 8
- X#define FORM_LETTER 16
- X#define NEW 32
- X#define PRIVATE 64
- X#define TAGGED 128
- X#define URGENT 256
- X#define VISIBLE 512
- X#define UNREAD 1024
- X#define STATUS_CHANGED 2048
- X
- X#define UNDELETE 0 /* purely for ^U function... */
- X
- X/** values for headers exit_disposition field */
- X#define UNSET 0
- X#define KEEP 1
- X#define STORE 2
- X#define DELETE 3
- X
- X/** some months... **/
- X
- X#define JANUARY 0 /* months of the year */
- X#define FEBRUARY 1
- X#define MARCH 2
- X#define APRIL 3
- X#define MAY 4
- X#define JUNE 5
- X#define JULY 6
- X#define AUGUST 7
- X#define SEPTEMBER 8
- X#define OCTOBER 9
- X#define NOVEMBER 10
- X#define DECEMBER 11
- X
- X#define equal(s,w) (strcmp(s,w) == 0)
- X#define min(a,b) a < b? a : b
- X#define ctrl(c) c - 'A' + 1 /* control character mapping */
- X#define plural(n) n == 1 ? "" : "s"
- X#define lastch(s) s[strlen(s)-1]
- X
- X/* find tab stops preceding or following a given column position 'a', where
- X * the column position starts counting from 1, NOT 0!
- X * The external integer "tabspacing" must be declared to use this. */
- X#define prev_tab(a) (((((a-1)/tabspacing))*tabspacing)+1)
- X#define next_tab(a) (((((a-1)/tabspacing)+1)*tabspacing)+1)
- X
- X#define movement_command(c) (c == 'j' || c == 'k' || c == ' ' || \
- X c == BACKSPACE || c == ESCAPE || c == '*' || \
- X c == '-' || c == '+' || c == '=' || \
- X c == '#' || c == '@' || c == 'x' || \
- X c == 'a' || c == 'q')
- X
- X#define no_ret(s) { register int xyz; /* varname is for lint */ \
- X for (xyz=strlen(s)-1; xyz >= 0 && \
- X (s[xyz] == '\r' || s[xyz] == '\n'); ) \
- X s[xyz--] = '\0'; \
- X }
- X
- X#define first_word(s,w) (strncmp(s,w, strlen(w)) == 0)
- X#define ClearLine(n) MoveCursor(n,0); CleartoEOLN()
- X#define whitespace(c) (c == ' ' || c == '\t')
- X#define ok_rc_char(c) (isalnum(c) || c == '-' || c == '_')
- X#define ok_alias_char(c) (isalnum(c) || c == '-' || c == '_' || c == '.')
- X#define quote(c) (c == '"' || c == '\'')
- X#define onoff(n) (n == 0 ? "OFF" : "ON")
- X
- X/** The next function is so certain commands can be processed from the showmsg
- X routine without rewriting the main menu in between... **/
- X
- X#define special(c) (c == 'j' || c == 'k')
- X
- X/** and a couple for dealing with status flags... **/
- X
- X#define ison(n,mask) (n & mask)
- X#define isoff(n,mask) (!ison(n, mask))
- X
- X#define setit(n,mask) n |= mask
- X#define clearit(n, mask) n &= ~mask
- X
- SHAR_EOF
- echo "End of part 9"
- echo "File hdrs/defs.h is continued in part 10"
- echo "10" > s2_seq_.tmp
- exit 0
-