home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i005: ELM Mail System, Part05/19
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: Dave Taylor <hplabs!taylor>
- Mod.sources: Volume 9, Issue 5
- Archive-name: elm2/Part05
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If this archive is complete, you will see the message:
- # "End of archive 5 (of 19)."
- # Contents: filter/actions.c filter/rules.c hdrs/elm.h hdrs/headers.h
- # src/calendar.c src/hdrconfg.c src/help.c src/pattern.c src/utils.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo shar: Extracting \"filter/actions.c\" \(5857 characters\)
- if test -f filter/actions.c ; then
- echo shar: Will not over-write existing file \"filter/actions.c\"
- else
- sed "s/^X//" >filter/actions.c <<'END_OF_filter/actions.c'
- X/** actions.c **/
- X
- X/** RESULT oriented routines *chuckle*. These routines implement the
- X actions that result from either a specified rule being true or from
- X the default action being taken.
- X
- X (C) Copyright 1986, Dave Taylor
- 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
- Xmail_message(address)
- Xchar *address;
- X{
- X /** Called with an address to send mail to. For various reasons
- X that are too disgusting to go into herein, we're going to actually
- X open the users mailbox and by hand add this message. Yech.
- X NOTE, of course, that if we're going to MAIL the message to someone
- X else, that we'll try to do nice things with it on the fly...
- X **/
- X
- X FILE *pipefd, *tempfd, *mailfd;
- X int attempts = 0, ret, in_header = TRUE, line_count = 0;
- X char tempfile[SLEN], mailbox[SLEN], lockfile[SLEN],
- X buffer[VERY_LONG_STRING];
- X
- X if (verbose && ! log_actions_only)
- X printf("%sfilter (%s): Mailing message to %s\n",
- X BEEP, username, address);
- X
- X if (! show_only) {
- X sprintf(tempfile, "%s.%d", filter_temp, getpid());
- X
- X if ((tempfd = fopen(tempfile, "r")) < 0) {
- X fprintf(stderr, "%sfilter (%s): Can't open temp file %s!!\n",
- X BEEP, username, tempfile);
- X exit(1);
- X }
- X
- X if (strcmp(address, username) != 0) { /* mailing to someone else */
- X
- X if (already_been_forwarded) { /* potential looping! */
- X if (contains(from, username)) {
- X fprintf(stderr,
- X "%sfilter (%s): Filter loop detected! Message left in file %s.%d\n",
- X BEEP, username, filter_temp, getpid());
- X exit(0);
- X }
- X }
- X
- X sprintf(buffer, "%s %s %s", sendmail, smflags, address);
- X
- X if ((pipefd = popen(buffer, "w")) == NULL) {
- X fprintf(stderr, "%sfilter (%s): popen %s failed!\n",
- X BEEP, buffer);
- X sprintf(buffer, "((%s %s %s ; %s %s) & ) < %s &",
- X sendmail , smflags, address, remove, tempfile, tempfile);
- X system(buffer);
- X return;
- X }
- X
- X fprintf(pipefd, "Subject: \"%s\"\n", subject);
- X fprintf(pipefd, "From: The Filter of %s@%s <%s>\n",
- X username, hostname, username);
- X fprintf(pipefd, "To: %s\n", address);
- X fprintf(pipefd, "X-Filtered-By: filter, version %s\n\n", VERSION);
- X
- X fprintf(pipefd, "-- Begin filtered message --\n\n");
- X
- X while (fgets(buffer, LONG_SLEN, tempfd) != NULL)
- X if (already_been_forwarded && in_header)
- X in_header = (strlen(buffer) == 1? 0 : in_header);
- X else
- X fprintf(pipefd," %s", buffer);
- X
- X fprintf(pipefd, "\n-- End of filtered message --\n");
- X fclose(pipefd);
- X fclose(tempfd);
- X
- X return; /* YEAH! Wot a slick program, eh? */
- X
- X }
- X
- X /** else it is to the current user... **/
- X
- X sprintf(mailbox, "%s%s", mailhome, username);
- X sprintf(lockfile, "%s%s.lock", mailhome, username);
- X
- X while ((ret=creat(lockfile, 0777)) < 0 && attempts++ < 10)
- X sleep(2); /* wait two seconds, okay?? */
- X
- X if (ret < 0) {
- X fprintf(stderr, "%sfilter (%s): Couldn't create lockfile %s\n",
- X BEEP, username, lockfile);
- X strcpy(mailbox,"[due to lock not being allowed]");
- X /* doing that copy will make sure the next 'open' fails... */
- X }
- X
- X if (mailbox[0] == '[' || (mailfd=fopen(mailbox,"a")) == NULL) {
- X
- X fprintf(stderr, "%sfilter (%s): Can't open mailbox %s!\n",
- X BEEP, username, mailbox);
- X
- X sprintf(mailbox, "%s/%s", home, EMERGENCY_MAILBOX);
- X if ((mailfd=fopen(mailbox, "a")) == NULL) {
- X fprintf(stderr,"%sfilter (%s): Can't open %s either!!\n",
- X BEEP, username, mailbox);
- X
- X sprintf(mailbox,"%s/%s", home, EMERG_MBOX);
- X if ((mailfd = fopen(mailbox, "a")) == NULL) {
- X fprintf(stderr,"%sfilter (%s): Can't open %s either!!!!\n",
- X BEEP, username, mailbox);
- X fprintf(stderr,
- X "%sfilter (%s): I can't open ANY mailboxes! Augh!!\n",
- X BEEP, username);
- X fclose(tempfd);
- X unlink(lockfile);
- X leave("Cannot open any mailbox"); /* DIE DIE DIE DIE!! */
- X }
- X else
- X fprintf(stderr,"%sfilter (%s): Using %s as emergency mailbox\n",
- X BEEP, username, mailbox);
- X }
- X else
- X fprintf(stderr,"%sfilter (%s): Using %s as emergency mailbox\n",
- X BEEP, username, mailbox);
- X }
- X
- X while (fgets(buffer, sizeof(buffer), tempfd) != NULL) {
- X line_count++;
- X if (the_same(buffer, "From ") && line_count > 1)
- X fprintf(mailfd, ">%s", buffer);
- X else
- X fputs(buffer, mailfd);
- X }
- X
- X fclose(mailfd);
- X unlink(lockfile); /* blamo! */
- X fclose(tempfd);
- X }
- X}
- X
- Xsave_message(foldername)
- Xchar *foldername;
- X{
- X /** Save the message in a folder. Use full file buffering to
- X make this work without contention problems **/
- X
- X FILE *fd, *tempfd;
- X char filename[SLEN], buffer[LONG_SLEN];
- X
- X if (verbose)
- X printf("%sfilter (%s): Message saved in folder %s\n",
- X BEEP, username, foldername);
- X
- X if (!show_only) {
- X sprintf(filename, "%s.%d", filter_temp, getpid());
- X
- X if ((fd = fopen(foldername, "a")) == NULL) {
- X fprintf(stderr,
- X "%sfilter (%s): can't save message to requested folder %s!\n",
- X BEEP, username, foldername);
- X return(1);
- X }
- X
- X if ((tempfd = fopen(filename, "r")) == NULL) {
- X fprintf(stderr,
- X "%sfilter (%s): can't open temp file for reading!\n",
- X BEEP, username);
- X return(1);
- X }
- X
- X while (fgets(buffer, sizeof(buffer), tempfd) != NULL)
- X fputs(buffer, fd);
- X
- X fclose(fd);
- X fclose(tempfd);
- X }
- X
- X return(0);
- X}
- X
- Xexecute(command)
- Xchar *command;
- X{
- X /** execute the indicated command, feeding as standard input the
- X message we have.
- X **/
- X
- X char buffer[LONG_SLEN];
- X
- X if (verbose)
- X printf("%sfilter (%s): Executing %s\n",
- X BEEP, username, command);
- X
- X if (! show_only) {
- X sprintf(buffer, "%s %s.%d | %s", cat, filter_temp, getpid(), command);
- X system(buffer);
- X }
- X}
- END_OF_filter/actions.c
- if test 5857 -ne `wc -c <filter/actions.c`; then
- echo shar: \"filter/actions.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"filter/rules.c\" \(6383 characters\)
- if test -f filter/rules.c ; then
- echo shar: Will not over-write existing file \"filter/rules.c\"
- else
- sed "s/^X//" >filter/rules.c <<'END_OF_filter/rules.c'
- X/** rules.c **/
- 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 (C) Copyright 1986, Dave Taylor
- X**/
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <ctype.h>
- X#ifdef BSD
- X# include <sys/time.h>
- X#else
- X# include <time.h>
- X#endif
- X#include <fcntl.h>
- X
- X#include "defs.h"
- X#include "filter.h"
- 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 index = 0, not, relation, try_next_rule, x;
- X struct condition_rec *cond;
- X
- X while (index < total_rules) {
- X cond = rules[index].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: fprintf(stderr,
- X "%sfilter (%s): Error: rules based on 'contains' are not implemented!\n",
- X BEEP, username);
- X exit(0);
- 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 = index;
- X return(rules[rule_choosen].action);
- X }
- X index++;
- 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)
- Xchar *word, *buffer;
- Xint line;
- 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.
- X **/
- X
- X struct tm *localtime(), *timerec;
- X long time(), thetime;
- X register int i, j=0, gotten_time = 0, reading_a_percent_sign = 0;
- X
- X for (i = 0; i < strlen(word); 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 strcat(buffer, from);
- X j = strlen(buffer);
- X break;
- X
- X case 's' : buffer[j] = '\0';
- X strcat(buffer, subject);
- X j = strlen(buffer);
- X break;
- X
- X case 'S' : buffer[j] = '\0';
- X if (! the_same(subject, "Re:"))
- X strcat(buffer, subject);
- X strcat(buffer, subject);
- X j = strlen(buffer);
- X break;
- X
- X case 'd' : get_the_time(); buffer[j] = '\0';
- 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 strcat(buffer, itoa(timerec->tm_wday,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 'm' : get_the_time(); buffer[j] = '\0';
- X strcat(buffer, itoa(timerec->tm_mon,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 'y' : get_the_time(); buffer[j] = '\0';
- 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 strcat(buffer, itoa(timerec->tm_hour,FALSE));
- X j = strlen(buffer);
- X break;
- X
- X case 't' : get_the_time(); buffer[j] = '\0';
- X strcat(buffer, itoa(timerec->tm_hour,FALSE));
- X strcat(buffer, ":");
- X strcat(buffer, itoa(timerec->tm_min,TRUE));
- X j = strlen(buffer);
- X break;
- X
- X default : fprintf(stderr,
- X "%sfilter (%s): Error on line %d translating %%%c macro in word \"%s\"!\n",
- X BEEP, username, line, word[i], word);
- X exit(1);
- X }
- X }
- X else if (word[i] == '%')
- X reading_a_percent_sign++;
- X else
- X buffer[j++] = 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 while (++i < total_rules) {
- X printf("\nRule %d: if (", i+1);
- X
- X cond = rules[i].condition;
- X
- X while (cond != NULL) {
- X if (cond->relation < 0)
- X printf("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 printf("%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) printf(" and ");
- X }
- X
- X printf(") then\n\t %s %s\n",
- X actionname(rules[i].action),
- X rules[i].argument2);
- X }
- X printf("\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 : 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}
- END_OF_filter/rules.c
- if test 6383 -ne `wc -c <filter/rules.c`; then
- echo shar: \"filter/rules.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"hdrs/elm.h\" \(5581 characters\)
- if test -f hdrs/elm.h ; then
- echo shar: Will not over-write existing file \"hdrs/elm.h\"
- else
- sed "s/^X//" >hdrs/elm.h <<'END_OF_hdrs/elm.h'
- X/** elm.h **/
- X
- X/** Main header file for ELM mail system. **/
- X
- X/** (C) Copyright 1986, Dave Taylor **/
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X
- X#include "../hdrs/curses.h"
- X#include "../hdrs/defs.h"
- X
- X/******** static character string containing the version number *******/
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X/******** and another string for the copyright notice ********/
- X
- Xstatic char copyright[] = { "@(#) (C) Copyright 1986, Dave Taylor" };
- X
- X/******** global variables accessable by all pieces of the program *******/
- X
- Xint current = 0; /* current message number */
- Xint header_page = 0; /* current header page */
- Xint last_header_page = -1; /* last header page */
- Xint message_count = 0; /* max message number */
- Xint headers_per_page; /* number of headers/page */
- Xchar infile[SLEN]; /* name of current mailbox */
- Xchar hostname[SLEN]; /* name of machine we're on*/
- Xchar username[SLEN]; /* return address name! */
- Xchar full_username[SLEN]; /* Full username - gecos */
- Xchar home[SLEN]; /* home directory of user */
- Xchar folders[SLEN]; /* folder home directory */
- Xchar mailbox[SLEN]; /* mailbox name if defined */
- Xchar editor[SLEN]; /* editor for outgoing mail*/
- Xchar alternative_editor[SLEN]; /* alternative editor... */
- Xchar printout[SLEN]; /* how to print messages */
- Xchar savefile[SLEN]; /* name of file to save to */
- Xchar calendar_file[SLEN]; /* name of file for clndr */
- Xchar prefixchars[SLEN]; /* prefix char(s) for msgs */
- Xchar shell[SLEN]; /* current system shell */
- Xchar pager[SLEN]; /* what pager to use */
- Xchar batch_subject[SLEN]; /* subject buffer for batchmail */
- Xchar local_signature[SLEN]; /* local msg signature file */
- Xchar remote_signature[SLEN]; /* remote msg signature file */
- X
- Xchar backspace, /* the current backspace char */
- X kill_line; /* the current kill-line char */
- X
- Xchar up[SHORT], down[SHORT]; /* cursor control seq's */
- Xint cursor_control = FALSE; /* cursor control avail? */
- X
- Xchar start_highlight[SHORT],
- X end_highlight[SHORT]; /* stand out mode... */
- X
- Xint has_highlighting = FALSE; /* highlighting available? */
- X
- Xchar *weedlist[MAX_IN_WEEDLIST];
- Xint weedcount;
- X
- Xint allow_forms = NO; /* flag: are AT&T Mail forms okay? */
- Xint file_changed = 0; /* flag: true if infile changed */
- Xint mini_menu = 1; /* flag: menu specified? */
- Xint mbox_specified = 0; /* flag: specified alternate mbox? */
- Xint check_first = 1; /* flag: verify mail to be sent! */
- Xint auto_copy = 0; /* flag: automatically copy source? */
- Xint filter = 1; /* flag: weed out header lines? */
- Xint resolve_mode = 1; /* flag: delete saved mail? */
- Xint auto_cc = 0; /* flag: mail copy to user? */
- Xint noheader = 1; /* flag: copy + header to file? */
- Xint title_messages = 1; /* flag: title message display? */
- Xint edit_outbound = 0; /* flag: edit outbound headers? */
- Xint hp_terminal = 0; /* flag: are we on HP term? */
- Xint hp_softkeys = 0; /* flag: are there softkeys? */
- Xint save_by_name = 1; /* flag: save mail by login name? */
- Xint mail_only = 0; /* flag: send mail then leave? */
- Xint check_only = 0; /* flag: check aliases then leave? */
- Xint move_when_paged = 0; /* flag: move when '+' or '-' used? */
- Xint point_to_new = 1; /* flag: start pointing at new msg? */
- Xint bounceback = 0; /* flag: bounce copy off remote? */
- Xint signature = 0; /* flag: include $home/.signature? */
- Xint always_leave = 0; /* flag: always leave msgs pending? */
- Xint always_del = 0; /* flag: always delete marked msgs? */
- Xint arrow_cursor = 0; /* flag: use "->" cursor regardless?*/
- Xint debug = 0; /* flag: default is no debug! */
- Xint read_in_aliases = 0; /* flag: have we read in aliases?? */
- Xint warnings = 1; /* flag: output connection warnings?*/
- Xint user_level = 0; /* flag: how good is the user? */
- Xint selected = 0; /* flag: used for select stuff */
- Xint names_only = 1; /* flag: display user names only? */
- Xint question_me = 1; /* flag: ask questions as we leave? */
- Xint keep_empty_files = 0; /* flag: leave empty mailbox files? */
- X
- X#ifdef UTS
- X int isatube = 0; /* flag: are we on an IBM 3270? */
- X#endif
- X
- Xint sortby = REVERSE SENT_DATE; /* how to sort incoming mail... */
- X
- Xlong timeout = 600L; /* timeout (secs) on main prompt */
- X
- Xint mailbox_defined = 0; /** mailbox specified? **/
- X
- X/** set up some default values for a 'typical' terminal *snicker* **/
- X
- Xint LINES=23; /** lines per screen **/
- Xint COLUMNS=80; /** columns per page **/
- X
- Xlong size_of_pathfd; /** size of pathfile, 0 if none **/
- X
- XFILE *mailfile; /* current mailbox file */
- XFILE *debugfile; /* file for debug output */
- XFILE *pathfd; /* path alias file */
- XFILE *domainfd; /* domain file */
- X
- Xlong mailfile_size; /* size of current mailfile */
- X
- Xint max_headers; /* number of headers allocated */
- X
- Xstruct header_rec *header_table;
- X
- Xstruct alias_rec user_hash_table[MAX_UALIASES];
- Xstruct alias_rec system_hash_table[MAX_SALIASES];
- X
- Xstruct date_rec last_read_mail; /* last time we read mailbox */
- X
- Xstruct lsys_rec *talk_to_sys; /* what machines do we talk to? */
- X
- Xstruct addr_rec *alternative_addresses; /* how else do we get mail? */
- X
- Xint system_files = 0; /* do we have system aliases? */
- Xint user_files = 0; /* do we have user aliases? */
- X
- Xint system_data; /* fileno of system data file */
- Xint user_data; /* fileno of user data file */
- X
- Xint userid; /* uid for current user */
- Xint groupid; /* groupid for current user */
- END_OF_hdrs/elm.h
- if test 5581 -ne `wc -c <hdrs/elm.h`; then
- echo shar: \"hdrs/elm.h\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"hdrs/headers.h\" \(5735 characters\)
- if test -f hdrs/headers.h ; then
- echo shar: Will not over-write existing file \"hdrs/headers.h\"
- else
- sed "s/^X//" >hdrs/headers.h <<'END_OF_hdrs/headers.h'
- X/** headers.h **/
- X
- X/** header file for ELM mail system. **/
- X
- X/** (C) Copyright 1985, Dave Taylor **/
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X
- X#include "curses.h"
- X#include "defs.h"
- X
- X/******** global variables accessable by all pieces of the program *******/
- X
- Xextern int current; /* current message number */
- Xextern int header_page; /* current header page */
- Xextern int last_header_page; /* last header page */
- Xextern int message_count; /* max message number */
- Xextern int headers_per_page; /* number of headers/page */
- Xextern char infile[SLEN]; /* name of current mailbox */
- Xextern char hostname[SLEN]; /* name of machine we're on*/
- Xextern char username[SLEN]; /* return address name! */
- Xextern char full_username[SLEN];/* Full username - gecos */
- Xextern char home[SLEN]; /* home directory of user */
- Xextern char folders[SLEN]; /* folder home directory */
- Xextern char mailbox[SLEN]; /* mailbox name if defined */
- Xextern char editor[SLEN]; /* default editor for mail */
- Xextern char alternative_editor[SLEN];/* the 'other' editor */
- Xextern char printout[SLEN]; /* how to print messages */
- Xextern char savefile[SLEN]; /* name of file to save to */
- Xextern char calendar_file[SLEN];/* name of file for clndr */
- Xextern char prefixchars[SLEN]; /* prefix char(s) for msgs */
- Xextern char shell[SLEN]; /* default system shell */
- Xextern char pager[SLEN]; /* what pager to use... */
- Xextern char batch_subject[SLEN];/* subject buffer for batchmail */
- Xextern char local_signature[SLEN];/* local msg signature file */
- Xextern char remote_signature[SLEN];/* remote msg signature file */
- X
- Xextern char backspace, /* the current backspace char */
- X kill_line; /* the current kill_line char */
- X
- Xextern char up[SHORT],
- X down[SHORT]; /* cursor control seq's */
- Xextern int cursor_control; /* cursor control avail? */
- X
- Xextern char start_highlight[SHORT],
- X end_highlight[SHORT]; /* standout mode... */
- X
- Xextern int has_highlighting; /* highlighting available? */
- X
- X/** the following two are for arbitrary weedout lists.. **/
- X
- Xextern char *weedlist[MAX_IN_WEEDLIST];
- Xextern int weedcount; /* how many headers to check? */
- X
- Xextern int allow_forms; /* flag: are AT&T Mail forms okay? */
- Xextern int file_changed; /* flag: true iff infile changed */
- Xextern int mini_menu; /* flag: display menu? */
- Xextern int mbox_specified; /* flag: specified alternate mailbox? */
- Xextern int check_first; /* flag: verify mail to be sent! */
- Xextern int auto_copy; /* flag: auto copy source into reply? */
- Xextern int filter; /* flag: weed out header lines? */
- Xextern int resolve_mode; /* flag: resolve before moving mode? */
- Xextern int auto_cc; /* flag: mail copy to yourself? */
- Xextern int noheader; /* flag: copy + header to file? */
- Xextern int title_messages; /* flag: title message display? */
- Xextern int edit_outbound; /* flag: edit outbound headers? */
- Xextern int hp_terminal; /* flag: are we on an hp terminal? */
- Xextern int hp_softkeys; /* flag: are there softkeys? */
- Xextern int save_by_name; /* flag: save mail by login name? */
- Xextern int mail_only; /* flag: send mail then leave? */
- Xextern int check_only; /* flag: check aliases and leave? */
- Xextern int move_when_paged; /* flag: move when '+' or '-' used? */
- Xextern int point_to_new; /* flag: start pointing at new msgs? */
- Xextern int bounceback; /* flag: bounce copy off remote? */
- Xextern int signature; /* flag: include $home/.signature? */
- Xextern int always_leave; /* flag: always leave mail pending? */
- Xextern int always_del; /* flag: always delete marked msgs? */
- Xextern int arrow_cursor; /* flag: use "->" regardless? */
- Xextern int debug; /* flag: debugging mode on? */
- Xextern int read_in_aliases; /* flag: have we read in aliases yet? */
- Xextern int warnings; /* flag: output connection warnings? */
- Xextern int user_level; /* flag: how knowledgable is user? */
- Xextern int selected; /* flag: used for select stuff */
- Xextern int names_only; /* flag: display names but no addrs? */
- Xextern int question_me; /* flag: ask questions as we leave? */
- Xextern int keep_empty_files; /* flag: keep empty files?? */
- X
- X#ifdef UTS
- Xextern int isatube; /* flag: are we on an IBM 3270 tube? */
- X#endif
- X
- Xextern int sortby; /* how to sort mailboxes */
- X
- Xextern long timeout; /* seconds for main level timeout */
- X
- Xextern int mailbox_defined; /** specified mailbox? **/
- X
- Xextern int LINES; /** lines per screen **/
- Xextern int COLUMNS; /** columns per line **/
- X
- Xextern long size_of_pathfd; /** size of pathfile, 0 if none **/
- X
- Xextern FILE *mailfile; /* current mailbox file */
- Xextern FILE *debugfile; /* file for debut output */
- Xextern FILE *pathfd; /* path alias file */
- Xextern FILE *domainfd; /* domains file */
- X
- Xextern long mailfile_size; /* size of current mailfile */
- X
- Xextern int max_headers; /* number of headers currently allocated */
- X
- Xextern struct header_rec *header_table;
- X
- Xextern struct alias_rec user_hash_table [MAX_UALIASES];
- Xextern struct alias_rec system_hash_table[MAX_SALIASES];
- X
- Xextern struct date_rec last_read_mail;
- X
- Xextern struct lsys_rec *talk_to_sys; /* who do we talk to? */
- X
- Xextern struct addr_rec *alternative_addresses; /* how else do we get mail? */
- X
- Xextern int system_files; /* do we have system aliases? */
- Xextern int user_files; /* do we have user aliases? */
- X
- Xextern int system_data; /* fileno of system data file */
- Xextern int user_data; /* fileno of user data file */
- X
- Xextern int userid; /* uid for current user */
- Xextern int groupid; /* groupid for current user */
- END_OF_hdrs/headers.h
- if test 5735 -ne `wc -c <hdrs/headers.h`; then
- echo shar: \"hdrs/headers.h\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/calendar.c\" \(5495 characters\)
- if test -f src/calendar.c ; then
- echo shar: Will not over-write existing file \"src/calendar.c\"
- else
- sed "s/^X//" >src/calendar.c <<'END_OF_src/calendar.c'
- X/** calendar.c **/
- X
- X/** This routine implements a rather snazzy idea suggested by Warren
- X Carithers of the Rochester Institute of Technology that allows
- X mail to contain entries formatted in a manner that will allow direct
- X copying into a users calendar program.
- X
- X Never able to leave good-enough alone, I've extended this idea to a
- X further one - the knowledge of a different type of calendar program
- X too. Specifically, the current message can contain either of;
- X
- X -> Mon 04/21 1:00p meet with chairman candidate
- X
- X or
- X
- X - >April 21
- X -
- X - 1:00 pm: Meet with Chairman Candidate
- X -
- X
- X The first type will have the leading '->' removed and all subsequent
- X white space, creating a simple one-line entry in the users calendar
- X file. The second type will remove the '-' and the leading white
- X spaces and leave everything else intact (that is, the file in the
- X second example would be appended with ">April 21" followed by a
- X blank line, the 1:00 pm meeting info, and another blank line.
- X
- X The file to include this in is either the default as defined in the
- X sysdefs.h file (see CALENDAR_FILE) or a filename contained in the
- X users ".elmrc" file, "calendar= <filename>".
- X
- X (C) Copyright 1986 Dave Taylor
- X**/
- X
- X#include "headers.h"
- X
- X#ifdef ENABLE_CALENDAR /* if not defined, this will be an empty file */
- X
- X#include <errno.h>
- X
- Xextern int errno;
- X
- Xchar *error_name(), *error_description(), *strcpy();
- X
- Xscan_calendar()
- X{
- X FILE *calendar;
- X int count;
- X
- X /* First step is to open the celendar file for appending... **/
- X
- X if (can_open(calendar_file, "a") != 0) {
- X dprint1(2, "Error: wrong permissions to append to calendar %s\n",
- X calendar_file);
- X dprint2(2, "** %s - %s **\n",
- X error_name(errno), error_description(errno));
- X error1("Not able to append to file %s!", calendar_file);
- X return;
- X }
- X
- X if ((calendar = fopen(calendar_file,"a")) == NULL) {
- X dprint1(2, "Error: couldn't append to calendar file %s (save)\n",
- X calendar_file);
- X dprint2(2, "** %s - %s **\n",
- X error_name(errno), error_description(errno));
- X error1("Couldn't append to file %s!", calendar_file);
- X return;
- X }
- X
- X count = extract_info(calendar);
- X
- X fclose(calendar);
- X
- X chown(calendar_file, userid, groupid); /* ensure owned by user */
- X
- X if (count > 0)
- X error2("%d entr%s saved in calendar file",
- X count, count > 1 ? "ies" : "y");
- X else
- X error("No calendar entries found in that message");
- X
- X return;
- X}
- X
- Xint
- Xextract_info(save_to_fd)
- XFILE *save_to_fd;
- X{
- X /** Save the relevant parts of the current message to the given
- X calendar file. The only parameter is an opened file
- X descriptor, positioned at the end of the existing file **/
- X
- X register int entries = 0, ok = 1, lines, index, in_entry = FALSE;
- X char buffer[SLEN];
- X
- X /** get to the first line of the message desired **/
- X
- X if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- X dprint2(1,"ERROR: Attempt to seek %d bytes into file failed (%s)",
- X header_table[current-1].offset, "extract_info");
- X error1("ELM [seek] failed trying to read %d bytes into file",
- X header_table[current-1].offset);
- X return(0);
- X }
- X
- X /* how many lines in message? */
- X
- X lines = header_table[current-1].lines;
- X
- X /* now while not EOF & still in message... scan it! */
- X
- X while (ok && lines--) {
- X ok = (int) (fgets(buffer, LONG_SLEN, mailfile) != NULL);
- X
- X /* now let's see if it matches the basic pattern... */
- X
- X if ((index = calendar_line(buffer)) > -1) {
- X
- X if (buffer[index] == '>') { /* single line entry */
- X if (remove_through_ch(buffer, '>')) {
- X fprintf(save_to_fd,"%s", buffer);
- X entries++;
- X }
- X }
- X else { /* multi-line entry */
- X fprintf(save_to_fd, "%s", (char *) (buffer + index + 1));
- X in_entry = TRUE;
- X }
- X }
- X else if (in_entry) {
- X in_entry = FALSE;
- X entries++;
- X }
- X }
- X
- X dprint2(4,"Got %d calender entr%s.\n", entries, entries > 1? "ies":"y");
- X
- X return(entries);
- X}
- X
- Xint
- Xcalendar_line(string)
- Xchar *string;
- X{
- X /** Iff the input line is of the form;
- X
- X {white space} <one or more '-'>
- X
- X this routine will return the index of the NEXT character
- X after the dashed sequence...If this pattern doesn't occur,
- X or if any other problems are encountered, it'll return "-1"
- X **/
- X
- X register int loc = 0;
- X
- X if (chloc(string,'-') == -1) /* no dash??? */
- X return(-1); /* that was easy! */
- X
- X /** skip leading white space... **/
- X
- X while (whitespace(string[loc])) loc++; /* MUST have '-' too! */
- X
- X if (string[loc] != '-') return(-1); /* nice try, sleazo! */
- X
- X while (string[loc] == '-') loc++;
- X
- X if (loc >= strlen(string)) return(-1); /* Empty line... */
- X
- X /* otherwise.... */
- X
- X return(loc);
- X}
- X
- X
- Xint
- Xremove_through_ch(string, ch)
- Xchar *string;
- Xchar ch;
- X{
- X /** removes all characters from zero to ch in the string, and
- X any 'white-space' following the 'n'th char... if it hits a
- X NULL string, it returns FALSE, otherwise it'll return TRUE!
- X **/
- X
- X char buffer[SLEN];
- X register int index = 0, i = 0;
- X
- X while (string[index] != ch && string[index] != '\0')
- X index++;
- X
- X if (index >= strlen(string))
- X return(FALSE); /* crash! burn! */
- X
- X index++; /* get past the 'ch' character... */
- X
- X while (whitespace(string[index])) index++;
- X
- X while (index < strlen(string))
- X buffer[i++] = string[index++];
- X
- X buffer[i] = '\0';
- X
- X strcpy(string, buffer);
- X
- X return(TRUE);
- X}
- X
- X#endif
- END_OF_src/calendar.c
- if test 5495 -ne `wc -c <src/calendar.c`; then
- echo shar: \"src/calendar.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/hdrconfg.c\" \(5434 characters\)
- if test -f src/hdrconfg.c ; then
- echo shar: Will not over-write existing file \"src/hdrconfg.c\"
- else
- sed "s/^X//" >src/hdrconfg.c <<'END_OF_src/hdrconfg.c'
- X/** hdrconfg.c **/
- X
- X/** This file contains the routines necessary to be able to modify
- X the mail headers of messages on the way off the machine. The
- X headers currently supported for modification are:
- X
- X Subject:
- X To:
- X Cc:
- X Bcc:
- X Reply-To:
- X
- X Expiration-Date:
- X Priority:
- X In-Reply-To:
- X Action:
- X
- X <user defined>
- X
- X (C) Copyright 1985, Dave Taylor
- X**/
- X
- X#include <stdio.h>
- X#include "headers.h"
- X
- X#include <ctype.h>
- X
- X#ifdef BSD
- X#undef toupper
- X#endif
- X
- X/* these are all defined in the mailmsg file! */
- X
- Xextern char subject[SLEN], action[SLEN], in_reply_to[SLEN], expires[SLEN],
- X priority[SLEN], reply_to[SLEN], to[VERY_LONG_STRING],
- X cc[VERY_LONG_STRING], expanded_to[VERY_LONG_STRING],
- X expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN];
- X
- X#ifdef ALLOW_BCC
- Xextern char bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
- X#endif
- X
- Xchar *strip_commas(), *strcpy();
- X
- Xedit_headers()
- X{
- X /** Edit headers. **/
- X
- X int unexpanded_to = TRUE, unexpanded_cc = TRUE;
- X#ifdef ALLOW_BCC
- X int unexpanded_bcc = TRUE;
- X#endif
- X char c;
- X
- X if (mail_only) goto outta_here; /* how did we get HERE??? */
- X
- X display_headers();
- X
- X while (TRUE) { /* forever */
- X PutLine0(LINES-1,0,"Choice: ");
- X CleartoEOLN();
- X c = toupper(getchar());
- X clear_error();
- X switch (c) {
- X case RETURN:
- X case LINE_FEED:
- X case 'Q' : goto outta_here;
- X case ctrl('L') : display_headers();
- X break;
- X case 'T' : if (optionally_enter(to, 2, 5, TRUE) == -1)
- X goto outta_here;
- X build_address(strip_commas(to), expanded_to);
- X unexpanded_to = FALSE;
- X break;
- X case 'S' : if (optionally_enter(subject, 7, 9, FALSE) == -1)
- X goto outta_here;
- X break;
- X#ifdef ALLOW_BCC
- X case 'B' : if (optionally_enter(bcc, 4, 5, TRUE) == -1)
- X goto outta_here;
- X build_address(strip_commas(bcc), expanded_bcc);
- X unexpanded_bcc = FALSE;
- X break;
- X#endif
- X case 'C' : if (optionally_enter(cc, 3, 5, TRUE) == -1)
- X goto outta_here;
- X build_address(strip_commas(cc), expanded_cc);
- X unexpanded_cc = FALSE;
- X break;
- X case 'R' : if (optionally_enter(reply_to, 5, 10, FALSE) == -1)
- X goto outta_here;
- X break;
- X case 'A' : if (optionally_enter(action, 9, 9, FALSE) == -1)
- X goto outta_here;
- X break;
- X case 'E' : enter_date(10, 17, expires);
- X break;
- X case 'P' : if (optionally_enter(priority, 11,10, FALSE) == -1)
- X goto outta_here;
- X break;
- X case 'U' : if (optionally_enter(user_defined_header,14,0,FALSE)==-1)
- X goto outta_here;
- X else
- X check_user_header(user_defined_header);
- X break;
- X case 'I' : if (strlen(in_reply_to) > 0) {
- X if (optionally_enter(in_reply_to, 12,13, FALSE) == -1)
- X goto outta_here;
- X break;
- X }
- X /** else fall through as an error **/
- X default : error("Unknown header being specified!");
- X }
- X }
- X
- Xoutta_here: /* this section re-expands aliases before we leave... */
- X
- X if (unexpanded_to)
- X build_address(strip_commas(to), expanded_to);
- X if (unexpanded_cc)
- X build_address(strip_commas(cc), expanded_cc);
- X#ifdef ALLOW_BCC
- X if (unexpanded_bcc)
- X build_address(strip_commas(bcc), expanded_bcc);
- X#endif
- X}
- X
- Xdisplay_headers()
- X{
- X ClearScreen();
- X
- X Centerline(0,"Message Header Edit Screen");
- X
- X PutLine1(2,0,"To : %s", to);
- X PutLine1(3,0,"Cc : %s", cc); CleartoEOLN();
- X#ifdef ALLOW_BCC
- X PutLine1(4,0,"Bcc: %s", bcc); CleartoEOLN();
- X#endif
- X PutLine1(5,0,"Reply-To: %s", reply_to); CleartoEOS();
- X
- X PutLine1(7,0,"Subject: %s", subject);
- X PutLine1(9,0,"Action : %s", action);
- X PutLine1(10,0,"Expiration-Date: %s", expires);
- X PutLine1(11,0,"Priority: %s", priority);
- X if (strlen(in_reply_to) > 0)
- X PutLine1(12,0,"In-Reply-To: %s", in_reply_to);
- X
- X if (strlen(user_defined_header) > 0)
- X PutLine1(14,0, "%s", user_defined_header);
- X
- X Centerline(LINES-5,
- X"Choose first letter of existing header, U)ser defined header, or <return>");
- X}
- X
- Xenter_date(x, y, buffer)
- Xint x, y;
- Xchar *buffer;
- X{
- X /** Enter the number of days this message is valid for, then
- X display at (x,y) the actual date of expiration. This
- X routine relies heavily on the routine 'days_ahead()' in
- X the file date.c
- X **/
- X
- X int days;
- X
- X PutLine0(LINES-1,0, "How many days in the future should it expire? ");
- X CleartoEOLN();
- X Raw(OFF);
- X gets(buffer);
- X Raw(ON);
- X sscanf(buffer, "%d", &days);
- X if (days < 1)
- X error("That doesn't make sense!");
- X else if (days > 14)
- X error("Expiration date must be within two weeks of today");
- X else {
- X days_ahead(days, buffer);
- X PutLine0(x, y, buffer);
- X }
- X}
- X
- Xcheck_user_header(header)
- Xchar *header;
- X{
- X /** check the header format...if bad print error and erase! **/
- X
- X register int i = -1;
- X
- X if (strlen(header) == 0)
- X return;
- X
- X if (whitespace(header[0])) {
- X error ("you can't have leading white space in a header!");
- X header[0] = '\0';
- X ClearLine(14);
- X return;
- X }
- X
- X if (header[0] == ':') {
- X error ("you can't have a colon as the first character!");
- X header[0] = '\0';
- X ClearLine(14);
- X return;
- X }
- X
- X while (header[++i] != ':') {
- X if (header[i] == '\0') {
- X error("you need a colon ending the field!");
- X header[0] = '\0';
- X ClearLine(14);
- X return;
- X }
- X else if (whitespace(header[i])) {
- X error("You can't have white space imbedded in the header name!");
- X header[0] = '\0';
- X ClearLine(14);
- X return;
- X }
- X }
- X
- X return;
- X}
- END_OF_src/hdrconfg.c
- if test 5434 -ne `wc -c <src/hdrconfg.c`; then
- echo shar: \"src/hdrconfg.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/help.c\" \(5969 characters\)
- if test -f src/help.c ; then
- echo shar: Will not over-write existing file \"src/help.c\"
- else
- sed "s/^X//" >src/help.c <<'END_OF_src/help.c'
- X/** help.c **/
- X
- X/*** help routine for ELM program
- X
- X (C) Copyright 1985, Dave Taylor
- X
- X***/
- X
- X#include <ctype.h>
- X
- X#ifdef BSD
- X# undef tolower
- X#endif
- X
- X#include "headers.h"
- X
- Xhelp()
- X{
- X /** Process the request for help [section] from the user **/
- X
- X char ch; /* character buffer for input */
- X char *s; /* string pointer... */
- X
- X MoveCursor(LINES-7,0);
- X CleartoEOS();
- X
- X Centerline(LINES-7, "ELM Help System");
- X Centerline(LINES-5,
- X "Press keys you want help for, '?' for a list, or '.' to end");
- X
- X PutLine0(LINES-3, 0, "Help on key: ");
- X
- X do {
- X MoveCursor(LINES-3, strlen("Help on key: "));
- X ch = tolower(ReadCh());
- X
- X if (ch == '.') return(0); /* zero means footer rewrite only */
- X
- X s = "Unknown command. Use '?' for a list of commands...";
- X
- X switch (ch) {
- X
- X case '?': display_helpfile(MAIN_HELP); return(1);
- X
- X case '$': s =
- X "$ = Force a resync of the current mailbox. This will 'purge' deleted mail";
- X break;
- X
- X case '!': s =
- X "! = Escape to the Unix shell of your choice, or just to enter commands";
- X break;
- X case '@': s =
- X "@ = Debug - display a summary of the messages on the header page";
- X break;
- X case '|': s =
- X "| = Pipe the current message or tagged messages to the command specified";
- X break;
- X case '#': s =
- X "# = Debug - display all information known about current message";
- X break;
- X case '%': s =
- X "% = Debug - display the computed return address of the current message";
- X break;
- X case '*': s = "* = Go to the last message in the current mailbox";
- X break;
- X case '-': s =
- X "- = Go to the previous page of messages in the current mailbox";
- X break;
- X case '=': s =
- X "'=' = Go to the first message in the current mailbox";
- X break;
- X case ' ':
- X case '+': s =
- X "+ = Go to the next page of messages in the current mailbox";
- X break;
- X case '/': s = "/ = Search for specified pattern in mailbox";
- X break;
- X case '<': s =
- X "< = Scan current message for calendar entries (if enabled)";
- X break;
- X case '>': s =
- X "> = Save current message or tagged messages to specified file";
- X break;
- X case '^': s =
- X "^ = Toggle the Delete/Undelete status of the current message";
- X break;
- X case 'a': s =
- X "a = Enter the alias sub-menu section. Create and display aliases";
- X break;
- X case 'b': s =
- X "b = Bounce (remail) a message to someone as if you have never seen it";
- X break;
- X case 'c': s =
- X "c = Change mailboxes, leaving the current mailbox as if 'quitting'";
- X break;
- X case 'd': s = "d = Mark the current message for future deletion";
- X break;
- X case ctrl('D') :
- X s = "^D = Mark for deletion all messages with the specified pattern";
- X break;
- X case 'e': s =
- X "e = Invoke the editor on the entire mailbox, resync'ing when done";
- X break;
- X case 'f': s =
- X "f = Forward the current message to someone, return address is yours";
- X break;
- X case 'g': s =
- X "g = Group reply not only to the sender, but to everyone who received msg";
- X break;
- X case 'h': s =
- X "h = Display message with all Headers (ignore weedout list)";
- X break;
- X case 'j': s =
- X "j = Go to the next message. This is the same as the DOWN arrow";
- X break;
- X case 'k': s =
- X "k = Go to the previous message. This is the same as the UP arrow";
- X break;
- X case 'm': s =
- X "m = Create and send mail to the specified person or persons";
- X break;
- X case 'n': s =
- X "n = Read the current message, then move current to next messge";
- X break;
- X case 'o': s = "o = Go to the options submenu";
- X break;
- X case 'p': s =
- X "p = Print the current message or the tagged messages";
- X break;
- X case 'q': s =
- X "q = Quit the mailer, asking about deletion, saving, etc";
- X break;
- X case 'r': s =
- X "r = Reply to the message. This only sends to the originator of the message";
- X break;
- X case 's': s =
- X "s = Save current message or tagged messages to specified file";
- X break;
- X case 't': s =
- X "t = Tag a message for further operations (or untag if tagged)";
- X break;
- X case ctrl('T') :
- X s = "^T = tag all messages with the specified pattern";
- X break;
- X case 'u':
- X s = "u = Undelete - remove the deletion mark on the message";
- X break;
- X case 'x': s = "x = Exit the mail system quickly";
- X break;
- X
- X case '\n':
- X case '\r': s = "<return> = Read the current message";
- X break;
- X
- X case ctrl('L'): s = "^L = Rewrite the screen";
- X break;
- X case ctrl('?'): /* DEL */
- X case ctrl('Q'): s = "Exit the mail system quickly";
- X break;
- X default : if (isdigit(ch))
- X s = "<number> = Make specified number the current message";
- X }
- X
- X ClearLine(LINES-1);
- X Centerline(LINES-1, s);
- X
- X } while (ch != '.');
- X
- X /** we'll never actually get here, but that's okay... **/
- X
- X return(0);
- X}
- X
- Xdisplay_helpfile(section)
- Xint section;
- X{
- X /*** Help me! Read file 'helpfile.<section>' and echo to screen ***/
- X
- X FILE *hfile;
- X char buffer[SLEN];
- X int lines=0;
- X
- X sprintf(buffer, "%s/%s.%d", helphome, helpfile, section);
- X if ((hfile = fopen(buffer,"r")) == NULL) {
- X dprint1(1,"Error: Couldn't open helpfile %s (help)\n", buffer);
- X error1("couldn't open helpfile %s",buffer);
- X return(FALSE);
- X }
- X
- X ClearScreen();
- X
- X while (fgets(buffer, SLEN, hfile) != NULL) {
- X if (lines > LINES-3) {
- X PutLine0(LINES,0,"Press any key to continue: ");
- X (void) ReadCh();
- X lines = 0;
- X ClearScreen();
- X Write_to_screen("%s\r", 1, buffer);
- X }
- X else
- X Write_to_screen("%s\r", 1, buffer);
- X
- X lines++;
- X }
- X
- X PutLine0(LINES,0,"Press any key to return: ");
- X
- X (void) ReadCh();
- X clear_error();
- X
- X return(TRUE);
- X}
- END_OF_src/help.c
- if test 5969 -ne `wc -c <src/help.c`; then
- echo shar: \"src/help.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/pattern.c\" \(5598 characters\)
- if test -f src/pattern.c ; then
- echo shar: Will not over-write existing file \"src/pattern.c\"
- else
- sed "s/^X//" >src/pattern.c <<'END_OF_src/pattern.c'
- X/** pattern.c **/
- X
- X/** General pattern matching for the ELM mailer.
- X
- X (C) Copyright 1986 Dave Taylor
- X**/
- X
- X#include <errno.h>
- X
- X#include "headers.h"
- X
- Xstatic char pattern[SLEN] = { "" };
- Xstatic char alt_pattern[SLEN] = { "" };
- X
- Xextern int errno;
- X
- Xchar *error_name(), *shift_lower(), *strcpy();
- X
- Xmeta_match(function)
- Xint function;
- X{
- X /** Perform specific function based on whether an entered string
- X matches either the From or Subject lines..
- X **/
- X
- X register int i, tagged=0, count=0;
- X static char meta_pattern[SLEN];
- X
- X PutLine1(LINES-3, strlen("Command: "),
- X "%s messages that match pattern...",
- X function==TAGGED?"Tag": function==DELETED?"Delete":"Undelete");
- X
- X if (function == TAGGED) { /* are messages already tagged??? */
- X for (i=0; i < message_count; i++)
- X if (ison(header_table[i].status,TAGGED))
- X tagged++;
- X
- X if (tagged) {
- X if (tagged > 2)
- X PutLine0(LINES-2,0, "Some messages are already tagged");
- X else
- X PutLine0(LINES-2,0, "A message is already tagged");
- X
- X Write_to_screen("- Remove tag%s? y%c", 2, plural(tagged),BACKSPACE);
- X
- X if (tolower(ReadCh()) != 'n') { /* remove tags... */
- X for (i=0; i < message_count; i++) {
- X clearit(header_table[i].status,TAGGED);
- X show_new_status(i);
- X }
- X }
- X }
- X }
- X
- X PutLine0(LINES-2,0, "Enter pattern: "); CleartoEOLN();
- X
- X optionally_enter(meta_pattern, LINES-2,strlen("Enter pattern: "),FALSE);
- X
- X if (strlen(meta_pattern) == 0) {
- X ClearLine(LINES-2);
- X return(0);
- X }
- X
- X strcpy(meta_pattern, shift_lower(meta_pattern)); /* lowercase it */
- X
- X for (i = 0; i < message_count; i++) {
- X if (from_matches(i, meta_pattern)) {
- X if ((selected && header_table[i].status & VISIBLE) || ! selected) {
- X if (function == UNDELETE)
- X clearit(header_table[i].status, DELETED);
- X else
- X setit(header_table[i].status, function);
- X show_new_status(i);
- X count++;
- X }
- X }
- X else if (subject_matches(i, meta_pattern)) {
- X if ((selected && header_table[i].status & VISIBLE) || ! selected) {
- X if (function == UNDELETE)
- X clearit(header_table[i].status, DELETED);
- X else
- X setit(header_table[i].status, function);
- X show_new_status(i);
- X count++;
- X }
- X }
- X }
- X
- X ClearLine(LINES-2); /* remove "pattern: " prompt */
- X
- X if (count > 0)
- X error3("%s %d messsage%s",
- X function==TAGGED? "tagged" :
- X function==DELETED? "marked for deletion" : "undeleted",
- X count, plural(count));
- X else
- X error1("no matches - no messages %s",
- X function==TAGGED? "tagged" :
- X function==DELETED? "marked for deletion": "undeleted");
- X
- X return(0);
- X}
- X
- Xint
- Xpattern_match()
- X{
- X /** Get a pattern from the user and try to match it with the
- X from/subject lines being displayed. If matched (ignoring
- X case), move current message pointer to that message, if
- X not, error and return ZERO **/
- X
- X register int i;
- X
- X PutLine0(LINES-3,40,"/ = match anywhere in messages");
- X
- X PutLine0(LINES-1,0, "Match Pattern:");
- X
- X if (pattern_enter(pattern, alt_pattern, LINES-1, 16,
- X "Match Pattern (in entire mailbox):"))
- X if (strlen(alt_pattern) > 0) {
- X strcpy(alt_pattern, shift_lower(alt_pattern));
- X return(match_in_message(alt_pattern));
- X }
- X else
- X return(1);
- X
- X if (strlen(pattern) == 0)
- X return(0);
- X else
- X strcpy(pattern, shift_lower(pattern));
- X
- X for (i = current; i < message_count; i++) {
- X if (from_matches(i, pattern)) {
- X if (!selected || (selected && header_table[i].status & VISIBLE)) {
- X current = ++i;
- X return(1);
- X }
- X }
- X else if (subject_matches(i, pattern)) {
- X if (!selected || (selected && header_table[i].status & VISIBLE)) {
- X current = ++i;
- X return(1);
- X }
- X }
- X }
- X
- X return(0);
- X}
- X
- Xint
- Xfrom_matches(message_number, pat)
- Xint message_number;
- Xchar *pat;
- X{
- X /** Returns true iff the pattern occurs in it's entirety
- X in the from line of the indicated message **/
- X
- X return( in_string(shift_lower(header_table[message_number].from),
- X pat) );
- X}
- X
- Xint
- Xsubject_matches(message_number, pat)
- Xint message_number;
- Xchar *pat;
- X{
- X /** Returns true iff the pattern occurs in it's entirety
- X in the subject line of the indicated message **/
- X
- X return( in_string(shift_lower(header_table[message_number].subject),
- X pat) );
- X}
- X
- Xmatch_in_message(pat)
- Xchar *pat;
- X{
- X /** Match a string INSIDE a message...starting at the current
- X message read each line and try to find the pattern. As
- X soon as we do, set current and leave!
- X Returns 1 if found, 0 if not
- X **/
- X
- X char buffer[LONG_STRING];
- X int message_number, lines, line;
- X
- X message_number = current-1;
- X
- X error("searching mailbox for pattern...");
- X
- X while (message_number < message_count) {
- X
- X if (fseek(mailfile, header_table[message_number].offset, 0L) != 0) {
- X
- X dprint3(1,"Error: seek %ld bytes into file failed. errno %d (%s)\n",
- X header_table[message_number].offset, errno,
- X "match_in_message");
- X error2("ELM [match] failed looking %ld bytes into file (%s)",
- X header_table[message_number].offset, error_name(errno));
- X return(1); /* fake it out to avoid replacing error message */
- X }
- X
- X line = 0;
- X lines = header_table[message_number].lines;
- X
- X while (fgets(buffer, LONG_STRING, mailfile) != NULL && line < lines) {
- X
- X line++;
- X
- X if (in_string(shift_lower(buffer), pat)) {
- X current = message_number+1;
- X clear_error();
- X return(1);
- X }
- X }
- X
- X /** now we've passed the end of THIS message...increment and
- X continue the search with the next message! **/
- X
- X message_number++;
- X }
- X
- X return(0);
- X}
- END_OF_src/pattern.c
- if test 5598 -ne `wc -c <src/pattern.c`; then
- echo shar: \"src/pattern.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/utils.c\" \(5852 characters\)
- if test -f src/utils.c ; then
- echo shar: Will not over-write existing file \"src/utils.c\"
- else
- sed "s/^X//" >src/utils.c <<'END_OF_src/utils.c'
- X/** utils.c **/
- X
- X/** Utility routines for ELM
- X
- X All routines herein: (C) Copyright 1985 Dave Taylor
- X**/
- X
- X#include "headers.h"
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <ctype.h>
- X#include <errno.h>
- X
- X#ifdef BSD
- X#undef tolower
- X#endif
- X
- X#include <signal.h>
- X
- Xextern int errno;
- X
- Xchar *error_name();
- Xvoid exit();
- X
- Xshow_mailfile_stats()
- X{
- X /** when we're about to die, let's try to dump lots of good stuff
- X to the debug file... **/
- X
- X struct stat buffer;
- X
- X if (debug == 0) return; /* Damn! Can't do it! */
- X
- X if (fstat(fileno(mailfile), &buffer) == 0) {
- X dprint1(1,"\nDump of stats for mailfile %s;\n", infile);
- X
- X dprint3(1, "\tinode: %d, mode: %o, uid: %d, ",
- X buffer.st_ino, buffer.st_mode, buffer.st_uid);
- X dprint2(1,"gid: %d, size: %d\n\n", buffer.st_gid, buffer.st_size);
- X
- X dprint1(1,"\toffset into file = %l\n", ftell(mailfile));
- X }
- X else
- X dprint2(1,"\nfstat on mailfile '%s' failed with error %s!!\n\n",
- X infile, error_name(errno));
- X}
- X
- Xemergency_exit()
- X{
- X /** used in dramatic cases when we must leave without altering
- X ANYTHING about the system... **/
- X
- X dprint0(1,
- X "\nERROR: Something dreadful is happening! Taking emergency exit!!\n\n");
- X dprint0(1," possibly leaving behind the following files;\n");
- X dprint2(1," The mailbox tempfile : %s%s\n", temp_mbox, username);
- X dprint2(1," The mailbox lock file: %s%s.lock\n", mailhome, username);
- X dprint2(1," The composition file : %s%d\n", temp_file, getpid());
- X dprint2(1," The header comp file : %s%d\n", temp_file, getpid()+1);
- X dprint2(1," The readmsg data file: %s/%s\n", home, readmsg_file);
- X
- X Raw(OFF);
- X if (cursor_control) transmit_functions(OFF);
- X if (hp_terminal) softkeys_off();
- X
- X if (cursor_control)
- X MoveCursor(LINES, 0);
- X
- X PutLine0(LINES,0, "\nEmergency Exit taken! All temp files intact!\n\n");
- X
- X exit(1);
- X}
- X
- X/*ARGSUSED*/
- X/*VARARGS0*/
- X
- Xleave(val)
- Xint val; /* not used, placeholder for signal catching! */
- X{
- X char buffer[SLEN];
- X
- X dprint0(2,"\nLeaving mailer normally (leave)\n");
- X
- X Raw(OFF);
- X if (cursor_control) transmit_functions(OFF);
- X if (hp_terminal) softkeys_off();
- X
- X sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s%d",temp_file, getpid()+1); /* editor buffer */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s%s",temp_mbox, username); /* temp mailbox */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s/%s", home, readmsg_file); /* readmsg temp */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s%s.lock",mailhome, username); /* lock file */
- X (void) unlink(buffer);
- X
- X if (! mail_only) {
- X MoveCursor(LINES,0);
- X Writechar('\n');
- X }
- X
- X exit(0);
- X}
- X
- Xsilently_exit()
- X{
- X /** This is the same as 'leave', but it doesn't remove any non-pid
- X files. It's used when we notice that we're trying to create a
- X temp mail file and one already exists!!
- X **/
- X char buffer[SLEN];
- X
- X dprint0(2,"\nLeaving mailer quietly (silently_exit)\n");
- X
- X Raw(OFF);
- X if (cursor_control) transmit_functions(OFF);
- X if (hp_terminal) softkeys_off();
- X
- X sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s%d",temp_file, getpid()+1); /* editor buffer */
- X (void) unlink(buffer);
- X
- X if (! mail_only) {
- X MoveCursor(LINES,0);
- X Writechar('\n');
- X }
- X
- X exit(0);
- X}
- X
- X/*ARGSUSED0*/
- X
- Xleave_locked(val)
- Xint val; /* not used, placeholder for signal catching! */
- X{
- X /** same as leave routine, but don't disturb lock file **/
- X
- X char buffer[SLEN];
- X
- X dprint0(3,
- X "\nLeaving mailer due to presence of lock file (leave_locked)\n");
- X
- X Raw(OFF);
- X if (cursor_control) transmit_functions(OFF);
- X if (hp_terminal) softkeys_off();
- X
- X sprintf(buffer,"%s%d",temp_file, getpid()); /* editor buffer */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s%d",temp_file, getpid()+1); /* editor buffer */
- X (void) unlink(buffer);
- X
- X sprintf(buffer,"%s%s",temp_mbox, username); /* temp mailbox */
- X (void) unlink(buffer);
- X
- X MoveCursor(LINES,0);
- X Writechar('\n');
- X
- X exit(0);
- X}
- X
- Xint
- Xget_page(msg_pointer)
- Xint msg_pointer;
- X{
- X /** Ensure that 'current' is on the displayed page,
- X returning non-zero iff the page changed! **/
- X
- X register int first_on_page, last_on_page;
- X
- X dprint1(6,"* get_page(%d) returns...", msg_pointer);
- X
- X first_on_page = (header_page * headers_per_page) + 1;
- X
- X last_on_page = first_on_page + headers_per_page - 1;
- X
- X dprint2(8,"[first-on-page=%d, last-on-page=%d]",
- X first_on_page, last_on_page);
- X
- X if (selected) /* but what is it on the SCREEN??? */
- X msg_pointer = compute_visible(msg_pointer-1);
- X
- X if (selected && msg_pointer > selected) {
- X dprint0(6,"FALSE - too far!\n");
- X return(FALSE); /* too far - page can't change! */
- X }
- X
- X if (msg_pointer > last_on_page) {
- X header_page = (int) (msg_pointer-(selected? 0:1)) / headers_per_page;
- X dprint3(6,"TRUE (%d > %d New hp=%d)!\n",
- X msg_pointer, last_on_page, header_page);
- X return(1);
- X }
- X else if (msg_pointer < first_on_page) {
- X header_page = (int) (msg_pointer-1) / headers_per_page;
- X dprint3(6,"TRUE (%d < %d New hp=%d)!\n",
- X msg_pointer, first_on_page, header_page);
- X return(1);
- X }
- X else {
- X dprint2(6,"FALSE [first=%d last=%d]\n",
- X first_on_page, last_on_page);
- X return(0);
- X }
- X}
- X
- Xchar *nameof(filename)
- Xchar *filename;
- X{
- X /** checks to see if 'filename' has any common prefixes, if
- X so it returns a string that is the same filename, but
- X with '=' as the folder directory, or '~' as the home
- X directory..
- X **/
- X
- X static char buffer[STRING];
- X register int i = 0, index = 0;
- X
- X if (strncmp(filename, folders, strlen(folders)) == 0) {
- X buffer[i++] = '=';
- X index = strlen(folders);
- X }
- X else if (strncmp(filename, home, strlen(home)) == 0) {
- X buffer[i++] = '~';
- X index = strlen(home);
- X }
- X else index = 0;
- X
- X while (filename[index] != '\0')
- X buffer[i++] = filename[index++];
- X buffer[i] = '\0';
- X
- X return( (char *) buffer);
- X}
- END_OF_src/utils.c
- if test 5852 -ne `wc -c <src/utils.c`; then
- echo shar: \"src/utils.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 5 \(of 19\).
- cp /dev/null ark5isdone
- DONE=true
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- echo shar: You still need to run archive ${I}.
- DONE=false
- fi
- done
- if test "$DONE" = "true" ; then
- echo You have unpacked all 19 archives.
- echo "See the Instructions file"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- fi
- ## End of shell archive.
- exit 0
-